autoconfed isode for kerberos work
authorMark Eichin <eichin@mit.edu>
Fri, 10 Jun 1994 03:36:08 +0000 (03:36 +0000)
committerMark Eichin <eichin@mit.edu>
Fri, 10 Jun 1994 03:36:08 +0000 (03:36 +0000)
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@3697 dc483132-0cff-0310-8789-dd5450dbe970

254 files changed:
src/isode/Makefile.in [new file with mode: 0644]
src/isode/compat/Makefile.in [new file with mode: 0644]
src/isode/compat/asprintf.c [new file with mode: 0644]
src/isode/compat/baduser.c [new file with mode: 0644]
src/isode/compat/bridge.c [new file with mode: 0644]
src/isode/compat/camtec.c [new file with mode: 0644]
src/isode/compat/chkpassword.c [new file with mode: 0644]
src/isode/compat/chrcnv.c [new file with mode: 0644]
src/isode/compat/cmd_srch.c [new file with mode: 0644]
src/isode/compat/configure.in [new file with mode: 0644]
src/isode/compat/dgram.c [new file with mode: 0644]
src/isode/compat/explode.c [new file with mode: 0644]
src/isode/compat/general.c [new file with mode: 0644]
src/isode/compat/getpassword.c [new file with mode: 0644]
src/isode/compat/hpuxx25.c [new file with mode: 0644]
src/isode/compat/implode.c [new file with mode: 0644]
src/isode/compat/inst-man.sh [new file with mode: 0644]
src/isode/compat/internet.c [new file with mode: 0644]
src/isode/compat/isoaddrs.c [new file with mode: 0644]
src/isode/compat/isofiles.c [new file with mode: 0644]
src/isode/compat/isohost.c [new file with mode: 0644]
src/isode/compat/isologs.sh [new file with mode: 0644]
src/isode/compat/isoman.rf [new file with mode: 0644]
src/isode/compat/isoservent.c [new file with mode: 0644]
src/isode/compat/lexequ.c [new file with mode: 0644]
src/isode/compat/lexnequ.c [new file with mode: 0644]
src/isode/compat/libicompat.3 [new file with mode: 0644]
src/isode/compat/log_tai.c [new file with mode: 0644]
src/isode/compat/logger.c [new file with mode: 0644]
src/isode/compat/na2norm.c [new file with mode: 0644]
src/isode/compat/na2str.c [new file with mode: 0644]
src/isode/compat/nochrcnv.c [new file with mode: 0644]
src/isode/compat/norm2na.c [new file with mode: 0644]
src/isode/compat/pa2str.c [new file with mode: 0644]
src/isode/compat/putenv.c [new file with mode: 0644]
src/isode/compat/rcmd_srch.c [new file with mode: 0644]
src/isode/compat/saddr2str.c [new file with mode: 0644]
src/isode/compat/sel2str.c [new file with mode: 0644]
src/isode/compat/select.c [new file with mode: 0644]
src/isode/compat/serror.c [new file with mode: 0644]
src/isode/compat/servbyname.c [new file with mode: 0644]
src/isode/compat/servbyport.c [new file with mode: 0644]
src/isode/compat/servbysel.c [new file with mode: 0644]
src/isode/compat/signals.c [new file with mode: 0644]
src/isode/compat/smalloc.c [new file with mode: 0644]
src/isode/compat/sprintb.c [new file with mode: 0644]
src/isode/compat/sstr2arg.c [new file with mode: 0644]
src/isode/compat/str2elem.c [new file with mode: 0644]
src/isode/compat/str2saddr.c [new file with mode: 0644]
src/isode/compat/str2sel.c [new file with mode: 0644]
src/isode/compat/str2taddr.c [new file with mode: 0644]
src/isode/compat/str2vec.c [new file with mode: 0644]
src/isode/compat/strdup.c [new file with mode: 0644]
src/isode/compat/sunlink.c [new file with mode: 0644]
src/isode/compat/taddr2str.c [new file with mode: 0644]
src/isode/compat/tailor.c [new file with mode: 0644]
src/isode/compat/ubcx25.c [new file with mode: 0644]
src/isode/compat/ultrix25.c [new file with mode: 0644]
src/isode/compat/version.major [new file with mode: 0644]
src/isode/compat/version.minor [new file with mode: 0644]
src/isode/compat/x25addr.c [new file with mode: 0644]
src/isode/configure.in [new file with mode: 0644]
src/isode/h/Makefile.in [new file with mode: 0644]
src/isode/h/acpkt.h [new file with mode: 0644]
src/isode/h/acsap.h [new file with mode: 0644]
src/isode/h/cmd_srch.h [new file with mode: 0644]
src/isode/h/config.h [new file with mode: 0644]
src/isode/h/configure.in [new file with mode: 0644]
src/isode/h/dgram.h [new file with mode: 0644]
src/isode/h/fpkt.h [new file with mode: 0644]
src/isode/h/ftam.h [new file with mode: 0644]
src/isode/h/general.h [new file with mode: 0644]
src/isode/h/internet.h [new file with mode: 0644]
src/isode/h/isoaddrs.h [new file with mode: 0644]
src/isode/h/isoservent.h [new file with mode: 0644]
src/isode/h/logger.h [new file with mode: 0644]
src/isode/h/manifest.h [new file with mode: 0644]
src/isode/h/mpkt.h [new file with mode: 0644]
src/isode/h/pepdefs.h [new file with mode: 0644]
src/isode/h/pepsy.h [new file with mode: 0644]
src/isode/h/ppkt.h [new file with mode: 0644]
src/isode/h/psap.h [new file with mode: 0644]
src/isode/h/psap2.h [new file with mode: 0644]
src/isode/h/ronot.h [new file with mode: 0644]
src/isode/h/ropkt.h [new file with mode: 0644]
src/isode/h/rosap.h [new file with mode: 0644]
src/isode/h/rosy.h [new file with mode: 0644]
src/isode/h/rtpkt.h [new file with mode: 0644]
src/isode/h/rtsap.h [new file with mode: 0644]
src/isode/h/spkt.h [new file with mode: 0644]
src/isode/h/ssap.h [new file with mode: 0644]
src/isode/h/sys.dirent.h [new file with mode: 0644]
src/isode/h/sys.file.h [new file with mode: 0644]
src/isode/h/tailor.h [new file with mode: 0644]
src/isode/h/tp4.h [new file with mode: 0644]
src/isode/h/tpkt.h [new file with mode: 0644]
src/isode/h/tsap.h [new file with mode: 0644]
src/isode/h/usr.dirent.h [new file with mode: 0644]
src/isode/h/x25.h [new file with mode: 0644]
src/isode/pepsy/Makefile.in [new file with mode: 0644]
src/isode/pepsy/UNIV.py [new file with mode: 0644]
src/isode/pepsy/configure.in [new file with mode: 0644]
src/isode/pepsy/dec.c [new file with mode: 0644]
src/isode/pepsy/dfns.c [new file with mode: 0644]
src/isode/pepsy/doc/DESCRIPTION [new file with mode: 0644]
src/isode/pepsy/doc/Makefile [new file with mode: 0644]
src/isode/pepsy/doc/overview.ms [new file with mode: 0644]
src/isode/pepsy/doc/tables.ms [new file with mode: 0644]
src/isode/pepsy/doc/wt-pep.ms [new file with mode: 0644]
src/isode/pepsy/dtabs.c [new file with mode: 0644]
src/isode/pepsy/enc.c [new file with mode: 0644]
src/isode/pepsy/etabs.c [new file with mode: 0644]
src/isode/pepsy/fre.c [new file with mode: 0644]
src/isode/pepsy/lex.l.gnrc [new file with mode: 0644]
src/isode/pepsy/libpepsy.3 [new file with mode: 0644]
src/isode/pepsy/macdefs.h [new file with mode: 0644]
src/isode/pepsy/main.c [new file with mode: 0644]
src/isode/pepsy/mine.h [new file with mode: 0644]
src/isode/pepsy/mod.c [new file with mode: 0644]
src/isode/pepsy/pass2.c [new file with mode: 0644]
src/isode/pepsy/pass2.h [new file with mode: 0644]
src/isode/pepsy/pep.output [new file with mode: 0644]
src/isode/pepsy/pepsy-driver.h [new file with mode: 0644]
src/isode/pepsy/pepsy.1 [new file with mode: 0644]
src/isode/pepsy/pepsy.c [new file with mode: 0644]
src/isode/pepsy/pepsy.h.gnrc [new file with mode: 0644]
src/isode/pepsy/pepsy_misc.c [new file with mode: 0644]
src/isode/pepsy/pepsy_str.c [new file with mode: 0644]
src/isode/pepsy/pepsydefs.h.gnrc [new file with mode: 0644]
src/isode/pepsy/pepy-refs.h [new file with mode: 0644]
src/isode/pepsy/prnt.c [new file with mode: 0644]
src/isode/pepsy/ptabs.c [new file with mode: 0644]
src/isode/pepsy/py_advise.c [new file with mode: 0644]
src/isode/pepsy/sym.h [new file with mode: 0644]
src/isode/pepsy/t1.py [new file with mode: 0644]
src/isode/pepsy/t2.py [new file with mode: 0644]
src/isode/pepsy/t3.py [new file with mode: 0644]
src/isode/pepsy/test_table.h [new file with mode: 0644]
src/isode/pepsy/tt.py [new file with mode: 0644]
src/isode/pepsy/util.c [new file with mode: 0644]
src/isode/pepsy/version.major [new file with mode: 0644]
src/isode/pepsy/version.minor [new file with mode: 0644]
src/isode/pepsy/vprint.c [new file with mode: 0644]
src/isode/pepsy/yacc.y.gnrc [new file with mode: 0644]
src/isode/psap/Makefile.in [new file with mode: 0644]
src/isode/psap/addr2ref.c [new file with mode: 0644]
src/isode/psap/bit2prim.c [new file with mode: 0644]
src/isode/psap/bit_ops.c [new file with mode: 0644]
src/isode/psap/bitstr2strb.c [new file with mode: 0644]
src/isode/psap/configure.in [new file with mode: 0644]
src/isode/psap/dec2pe.c [new file with mode: 0644]
src/isode/psap/dg2ps.c [new file with mode: 0644]
src/isode/psap/fdx2ps.c [new file with mode: 0644]
src/isode/psap/flag2prim.c [new file with mode: 0644]
src/isode/psap/gtime.c [new file with mode: 0644]
src/isode/psap/hex2pe.c [new file with mode: 0644]
src/isode/psap/int2strb.c [new file with mode: 0644]
src/isode/psap/isobject.c [new file with mode: 0644]
src/isode/psap/libpsap.3 [new file with mode: 0644]
src/isode/psap/num2prim.c [new file with mode: 0644]
src/isode/psap/obj2prim.c [new file with mode: 0644]
src/isode/psap/objectbyname.c [new file with mode: 0644]
src/isode/psap/objectbyoid.c [new file with mode: 0644]
src/isode/psap/ode2oid.c [new file with mode: 0644]
src/isode/psap/oid2ode.c [new file with mode: 0644]
src/isode/psap/oid_cmp.c [new file with mode: 0644]
src/isode/psap/oid_cpy.c [new file with mode: 0644]
src/isode/psap/oid_free.c [new file with mode: 0644]
src/isode/psap/pe2pl.c [new file with mode: 0644]
src/isode/psap/pe2ps.c [new file with mode: 0644]
src/isode/psap/pe2qb_f.c [new file with mode: 0644]
src/isode/psap/pe2ssdu.c [new file with mode: 0644]
src/isode/psap/pe2text.c [new file with mode: 0644]
src/isode/psap/pe2uvec.c [new file with mode: 0644]
src/isode/psap/pe_alloc.c [new file with mode: 0644]
src/isode/psap/pe_cmp.c [new file with mode: 0644]
src/isode/psap/pe_cpy.c [new file with mode: 0644]
src/isode/psap/pe_error.c [new file with mode: 0644]
src/isode/psap/pe_expunge.c [new file with mode: 0644]
src/isode/psap/pe_extract.c [new file with mode: 0644]
src/isode/psap/pe_free.c [new file with mode: 0644]
src/isode/psap/pe_pullup.c [new file with mode: 0644]
src/isode/psap/pl2pe.c [new file with mode: 0644]
src/isode/psap/pl_tables.c [new file with mode: 0644]
src/isode/psap/prim2bit.c [new file with mode: 0644]
src/isode/psap/prim2flag.c [new file with mode: 0644]
src/isode/psap/prim2num.c [new file with mode: 0644]
src/isode/psap/prim2oid.c [new file with mode: 0644]
src/isode/psap/prim2qb.c [new file with mode: 0644]
src/isode/psap/prim2real.c [new file with mode: 0644]
src/isode/psap/prim2set.c [new file with mode: 0644]
src/isode/psap/prim2str.c [new file with mode: 0644]
src/isode/psap/prim2time.c [new file with mode: 0644]
src/isode/psap/ps2pe.c [new file with mode: 0644]
src/isode/psap/ps_alloc.c [new file with mode: 0644]
src/isode/psap/ps_error.c [new file with mode: 0644]
src/isode/psap/ps_flush.c [new file with mode: 0644]
src/isode/psap/ps_free.c [new file with mode: 0644]
src/isode/psap/ps_get_abs.c [new file with mode: 0644]
src/isode/psap/ps_io.c [new file with mode: 0644]
src/isode/psap/ps_prime.c [new file with mode: 0644]
src/isode/psap/psaptest.c [new file with mode: 0644]
src/isode/psap/qb2pe.c [new file with mode: 0644]
src/isode/psap/qb2prim.c [new file with mode: 0644]
src/isode/psap/qb2str.c [new file with mode: 0644]
src/isode/psap/qb_free.c [new file with mode: 0644]
src/isode/psap/qb_pullup.c [new file with mode: 0644]
src/isode/psap/qbuf2pe.c [new file with mode: 0644]
src/isode/psap/qbuf2pe_f.c [new file with mode: 0644]
src/isode/psap/qbuf2ps.c [new file with mode: 0644]
src/isode/psap/real2prim.c [new file with mode: 0644]
src/isode/psap/seq_add.c [new file with mode: 0644]
src/isode/psap/seq_addon.c [new file with mode: 0644]
src/isode/psap/seq_del.c [new file with mode: 0644]
src/isode/psap/seq_find.c [new file with mode: 0644]
src/isode/psap/set_add.c [new file with mode: 0644]
src/isode/psap/set_addon.c [new file with mode: 0644]
src/isode/psap/set_del.c [new file with mode: 0644]
src/isode/psap/set_find.c [new file with mode: 0644]
src/isode/psap/sprintoid.c [new file with mode: 0644]
src/isode/psap/sprintref.c [new file with mode: 0644]
src/isode/psap/ssdu2pe.c [new file with mode: 0644]
src/isode/psap/std2ps.c [new file with mode: 0644]
src/isode/psap/str2oid.c [new file with mode: 0644]
src/isode/psap/str2pe.c [new file with mode: 0644]
src/isode/psap/str2prim.c [new file with mode: 0644]
src/isode/psap/str2ps.c [new file with mode: 0644]
src/isode/psap/str2qb.c [new file with mode: 0644]
src/isode/psap/strb2bitstr.c [new file with mode: 0644]
src/isode/psap/strb2int.c [new file with mode: 0644]
src/isode/psap/test/test1.pl [new file with mode: 0644]
src/isode/psap/test/test2.pl [new file with mode: 0644]
src/isode/psap/time2prim.c [new file with mode: 0644]
src/isode/psap/time2str.c [new file with mode: 0644]
src/isode/psap/tm2ut.c [new file with mode: 0644]
src/isode/psap/ts2ps.c [new file with mode: 0644]
src/isode/psap/ut2tm.c [new file with mode: 0644]
src/isode/psap/uvec2ps.c [new file with mode: 0644]
src/isode/psap/version.major [new file with mode: 0644]
src/isode/psap/version.minor [new file with mode: 0644]
src/isode/support/Makefile.in [new file with mode: 0644]
src/isode/support/aliases.local [new file with mode: 0644]
src/isode/support/configure.in [new file with mode: 0644]
src/isode/support/entities.local [new file with mode: 0644]
src/isode/support/macros.local [new file with mode: 0644]
src/isode/support/objects.local [new file with mode: 0644]
src/isode/support/services.local [new file with mode: 0644]
src/isode/support/version.major [new file with mode: 0644]
src/isode/support/version.minor [new file with mode: 0644]
src/isode/util/config_for [new file with mode: 0644]
src/isode/util/extract.sh [new file with mode: 0644]
src/isode/util/inst-lint.sh [new file with mode: 0644]
src/isode/util/make-lib.sh [new file with mode: 0644]
src/isode/util/version.sh [new file with mode: 0644]

diff --git a/src/isode/Makefile.in b/src/isode/Makefile.in
new file mode 100644 (file)
index 0000000..47706e8
--- /dev/null
@@ -0,0 +1,6 @@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+all::
+
+SUBDIRS = @SUBDIRS@
diff --git a/src/isode/compat/Makefile.in b/src/isode/compat/Makefile.in
new file mode 100644 (file)
index 0000000..65a90c7
--- /dev/null
@@ -0,0 +1,217 @@
+###############################################################################
+#   Instructions to Make, for compilation of UNIX compatibility library
+###############################################################################
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+BUILDTOP = ../../
+TOPDIR = $(BUILDTOP)
+
+OPTIONS        =       -I. -I$(HDIR) $(PEPYPATH) $(KRBOPT)
+CFLAGS  =       $(OPTIONS) $(LOPTIONS) 
+
+HDIR   =       $(TOPDIR)isode/h/
+UTILDIR        =       $(TOPDIR)isode/util/
+INCDIRM        =       $(HDIR)
+INCDIR =       $(INCDIRM)/
+PEPSYDIRM=     $(INCDIR)pepsy
+PEPSYDIR=      $(PEPSYDIRM)/
+LIBISODE=      $(TOPDIR)libisode.a
+LIBDSAP        =       $(TOPDIR)libdsap.a
+
+LIBES  =       libcompat.a
+LLIBS   =
+HFILES =       $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+LN     =       ln
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           libcompat 
+inst-all:      inst-isologs # inst-libcompat manuals
+install:       inst-all clean
+lint:          l-libcompat
+
+
+################################################################
+# libcompat
+################################################################
+
+CFILES =       general.c logger.c select.c signals.c \
+               asprintf.c explode.c implode.c isofiles.c isohost.c sel2str.c \
+                       serror.c sprintb.c str2elem.c str2sel.c str2vec.c \
+                       tailor.c \
+               baduser.c chkpassword.c getpassword.c putenv.c \
+               chrcnv.c cmd_srch.c lexequ.c lexnequ.c log_tai.c nochrcnv.c \
+                       rcmd_srch.c smalloc.c sstr2arg.c strdup.c \
+               isoservent.c servbyname.c servbyport.c servbysel.c \
+               isoaddrs.c str2saddr.c str2taddr.c saddr2str.c taddr2str.c\
+                        na2norm.c norm2na.c na2str.c pa2str.c \
+               internet.c \
+               dgram.c \
+               bridge.c camtec.c sunlink.c ubcx25.c \
+               hpuxx25.c ultrix25.c x25addr.c
+OFILES =       general.o logger.o select.o signals.o \
+               asprintf.o explode.o implode.o isofiles.o isohost.o sel2str.o \
+                       serror.o sprintb.o str2elem.o str2sel.o str2vec.o \
+                       tailor.o \
+               baduser.o chkpassword.o getpassword.o putenv.o \
+               chrcnv.o cmd_srch.o lexequ.o lexnequ.o log_tai.o nochrcnv.o \
+                       rcmd_srch.o smalloc.o sstr2arg.o strdup.o \
+               isoservent.o servbyname.o servbyport.o servbysel.o \
+               isoaddrs.o str2saddr.o str2taddr.o saddr2str.o taddr2str.o \
+                       na2norm.o norm2na.o na2str.o pa2str.o \
+               internet.o \
+               dgram.o \
+               bridge.o camtec.o sunlink.o ubcx25.o \
+               hpuxx25.o ultrix25.o x25addr.o \
+               $(OSTRINGS)
+
+inst-libcompat:        $(LIBDIR)libicompat.a $(LINTDIR)llib-licompat
+
+$(LIBDIR)libicompat.a: libcompat.a
+               -rm -f $@
+               cp libcompat.a $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+               -@ls -gls $@
+               -@echo ""
+
+$(LINTDIR)llib-licompat:       llib-lcompat
+               -cp $@ zllib-lcompat
+               -rm -f $@
+               sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+                       < llib-lcompat | \
+                       sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+               @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+               -@ls -gls $@ $@.ln
+               -@echo ""
+
+libcompat:     libcompat.a
+
+libcompat.a:   compatvrsn.o
+               -rm -f $@
+               $(UTILDIR)make-lib.sh $(SYSTEM) $@ $(OFILES) \
+                       compatvrsn.o
+               -@rm -f $(TOPDIR)libcompat.a $(TOPDIR)llib-lcompat
+               -@$(LN) libcompat.a $(TOPDIR)libcompat.a || cp libcompat.a $(TOPDIR)libcompat.a
+               -@$(LN) llib-lcompat $(TOPDIR)llib-lcompat
+               -@ls -l $@
+               -@echo "COMPAT library built normally"
+
+compatvrsn.c:  $(OFILES)
+               @$(UTILDIR)version.sh compat > $@
+
+l-libcompat:;  $(LINT) $(LFLAGS) -DBINPATH=\"$(BINDIR)\" \
+                       -DETCPATH=\"$(ETCDIR)\" -DSBINPATH=\"$(SBINDIR)\" \
+                       -DLOGPATH=\"$(LOGDIR)\" $(CFILES) compatvrsn.c \
+                       | grep -v "warning: possible pointer alignment problem"
+
+general.o:     $(HFILES)
+logger.o:      $(HFILES) $(HDIR)logger.h $(HDIR)tailor.h
+select.o:      $(HFILES) $(HDIR)logger.h $(HDIR)tailor.h
+signals.o:     $(HFILES)
+asprintf.o:    $(HFILES)
+explode.o:     $(HFILES)
+implode.o:     $(HFILES)
+isofiles.o:    $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+isohost.o:     $(HFILES) $(HDIR)internet.h $(HDIR)tailor.h $(HDIR)logger.h
+sel2str.o:     $(HFILES) $(HDIR)isoaddrs.h
+serror.o:      $(HFILES)
+sprintb.o:     $(HFILES)
+str2elem.o:    $(HFILES)
+str2sel.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+str2vec.o:     $(HFILES)
+tailor.o:      $(HFILES) $(HDIR)isoaddrs.h $(HDIR)tailor.h $(HDIR)logger.h 
+               $(CC) $(CFLAGS) -DBINPATH=\"$(BINDIR)\" \
+                       -DETCPATH=\"$(ETCDIR)\" -DSBINPATH=\"$(SBINDIR)\" \
+                       -DLOGPATH=\"$(LOGDIR)\" -c tailor.c
+baduser.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+chkpassword.o: $(HFILES)
+getpassword.o: $(HFILES)
+putenv.o:      $(HFILES)
+chrcnv.o:      $(HFILES)
+cmd_srch.o:    $(HFILES) $(HDIR)cmd_srch.h
+lexequ.o:      $(HFILES)
+lexnequ.o:     $(HFILES)
+log_tai.o:     $(HFILES) $(HDIR)logger.h
+nochrcnv.o:    $(HFILES)
+rcmd_srch.o:   $(HFILES) $(HDIR)cmd_srch.h
+smalloc.o:     $(HFILES) $(HDIR)tailor.h
+sstr2arg.o:    $(HFILES)
+strdup.o:      $(HFILES)
+isoservent.o:  $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h $(HDIR)logger.h
+servbyname.o:  $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h $(HDIR)logger.h
+servbyport.o:  $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h $(HDIR)logger.h
+servbysel.o:   $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h $(HDIR)logger.h
+isoaddrs.o:    $(HFILES) $(HDIR)isoaddrs.h $(HDIR)internet.h $(HDIR)tailor.h \
+                       $(HDIR)logger.h
+str2saddr.o:   $(HFILES) $(HDIR)isoaddrs.h
+str2taddr.o:   $(HFILES) $(HDIR)isoaddrs.h
+saddr2str.o:   $(HFILES) $(HDIR)isoaddrs.h
+taddr2str.o:   $(HFILES) $(HDIR)isoaddrs.h
+na2norm.o:     $(HFILES) $(HDIR)isoaddrs.h $(HDIR)internet.h $(HDIR)tailor.h \
+                       $(HDIR)logger.h
+norm2na.o:     $(HDIR)psap.h $(HFILES) $(HDIR)isoaddrs.h $(HDIR)tailor.h \
+                       $(HDIR)logger.h
+na2str.o:      $(HFILES) $(HDIR)isoaddrs.h
+pa2str.o:      $(HFILES) $(HDIR)isoaddrs.h
+internet.o:    $(HFILES) $(HDIR)internet.h
+dgram.o:       $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \
+                       $(HDIR)dgram.h $(HDIR)internet.h $(HDIR)tp4.h
+bridge.o:      $(HFILES) $(HDIR)internet.h $(HDIR)internet.h $(HDIR)tailor.h \
+                        $(HDIR)logger.h $(HDIR)tpkt.h $(HDIR)tsap.h
+camtec.o:      $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h $(HDIR)logger.h \
+                       $(HDIR)tpkt.h $(HDIR)tsap.h
+sunlink.o:     $(HFILES) $(HDIR)isoaddrs.h $(HDIR)x25.h $(HDIR)tailor.h \
+                        $(HDIR)logger.h
+ubcx25.o:      $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h $(HDIR)logger.h \
+                       $(HDIR)tpkt.h $(HDIR)tsap.h
+ultrix.o:      $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h $(HDIR)logger.h \
+                       $(HDIR)tpkt.h $(HDIR)tsap.h
+hpuxx25.o:     $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h $(HDIR)logger.h \
+                       $(HDIR)tpkt.h $(HDIR)tsap.h
+x25addr.o:     $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h $(HDIR)logger.h \
+                       $(HDIR)tpkt.h $(HDIR)tsap.h
+
+
+################################################################
+# isologs
+################################################################
+
+inst-isologs:  $(SBINDIR)isologs
+
+$(SBINDIR)isologs: isologs.sh Makefile
+               -cp $@ zxisologs
+               -rm -f $@
+               sed -e 's%@(ETCDIR)%$(ETCDIR)%' < isologs.sh | \
+                       sed -e 's%@(LOGDIR)%$(LOGDIR)%' > $@
+               chmod a+rx $@
+               -@ls -gls $@
+               -@echo ""
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       libicompat.3
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a z* _* core compatvrsn.c 
+
+grind:;                iprint Makefile
+               tgrind -lc $(CFILES) compatvrsn.c llib-lcompat
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
diff --git a/src/isode/compat/asprintf.c b/src/isode/compat/asprintf.c
new file mode 100644 (file)
index 0000000..d271523
--- /dev/null
@@ -0,0 +1,112 @@
+/* asprintf.c - sprintf with errno */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:26:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:21  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:28  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:48  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f   DATA */
+
+extern int errno;
+
+/* \f */
+
+void   asprintf (bp, ap)               /* what, fmt, args, ... */
+char *bp;
+va_list        ap;
+{
+    char   *what;
+
+    what = va_arg (ap, char *);
+
+    _asprintf (bp, what, ap);
+}
+
+
+void   _asprintf (bp, what, ap)        /* fmt, args, ... */
+register char *bp;
+char   *what;
+va_list        ap;
+{
+    register int    eindex;
+    char   *fmt;
+
+    eindex = errno;
+
+    *bp = NULL;
+    fmt = va_arg (ap, char *);
+
+    if (fmt) {
+#ifndef        VSPRINTF
+       struct _iobuf iob;
+#endif
+
+#ifndef        VSPRINTF
+#ifdef pyr
+       bzero ((char *) &iob, sizeof iob);
+       iob._file = _NFILE;
+#endif
+       iob._flag = _IOWRT | _IOSTRG;
+#if    !defined(vax) && !defined(pyr)
+       iob._ptr = (unsigned char *) bp;
+#else
+       iob._ptr = bp;
+#endif
+       iob._cnt = BUFSIZ;
+       _doprnt (fmt, ap, &iob);
+       putc (NULL, &iob);
+#else
+       (void) vsprintf (bp, fmt, ap);
+#endif
+       bp += strlen (bp);
+
+    }
+
+    if (what) {
+       if (*what) {
+           (void) sprintf (bp, " %s: ", what);
+           bp += strlen (bp);
+       }
+       (void) strcpy (bp, sys_errname (eindex));
+       bp += strlen (bp);
+    }
+
+    errno = eindex;
+}
diff --git a/src/isode/compat/baduser.c b/src/isode/compat/baduser.c
new file mode 100644 (file)
index 0000000..9ec4ded
--- /dev/null
@@ -0,0 +1,88 @@
+/* baduser.c - check file of bad users */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:26:56  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:23  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:29  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:49  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f */
+
+int    baduser (file, user)
+char   *file,
+       *user;
+{
+    int     hit,
+           tries;
+    register char  *bp;
+    char    buffer[BUFSIZ];
+    FILE   *fp;
+
+    hit = 0;
+    for (tries = 0; tries < 2 && !hit; tries++) {
+       switch (tries) {
+           case 0:
+               if (file) {
+                   bp = isodefile (file, 0);
+                   break;
+               }
+               tries++;
+               /* and fall */
+           default:
+               bp = "/etc/ftpusers";
+               break;
+       }
+       if ((fp = fopen (bp, "r")) == NULL)
+           continue;
+
+       while (fgets (buffer, sizeof buffer, fp)) {
+           if (bp = index (buffer, '\n'))
+               *bp = NULL;
+           if (strcmp (buffer, user) == 0) {
+               hit++;
+               break;
+           }
+       }
+
+       (void) fclose (fp);
+    }
+
+
+    return hit;
+}
diff --git a/src/isode/compat/bridge.c b/src/isode/compat/bridge.c
new file mode 100644 (file)
index 0000000..45fd181
--- /dev/null
@@ -0,0 +1,434 @@
+/* bridge.c - X.25 abstractions for TCP bridge to X25 */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ * Contributed by Julian Onions, Nottingham University in the UK
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:26:59  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:25  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:32  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:49  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+#include "internet.h"
+#include "tpkt.h"
+
+/* \f    TCP/X.25 BRIDGE */
+
+#ifdef BRIDGE_X25
+
+
+static int     assfd[FD_SETSIZE];
+static char    bridge_inited = 0;
+
+/* \f */
+
+/* ARGSUSED */
+
+int    start_bridge_client (local)
+struct NSAPaddr        *local;
+{
+    int     sd;
+    u_short port;
+    register struct servent *sp;
+
+    if ((sp = getservbyname ("x25bridge", "tcp")) == NULL)
+       port = x25_bridge_port;
+    else
+       port = sp -> s_port;
+
+    if ((sd = in_connect (x25_bridge_host, port)) == NOTOK)
+       return NOTOK;
+
+    if (write_tcp_socket (sd, "\01", 1) != 1) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("initial write"));
+
+       (void) close_tcp_socket (sd);
+       return NOTOK;
+    }
+
+    return sd;
+}
+
+/* \f */
+
+static int  in_connect (addr, port)
+char   *addr;
+u_short port;
+{
+    int     sd;
+    struct sockaddr_in in_socket;
+    register struct sockaddr_in *isock = &in_socket;
+    register struct hostent *hp;
+
+    if ((hp = gethostbystring (addr)) == NULL) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", addr));
+
+       return NOTOK;
+    }
+
+    bzero ((char *) isock, sizeof *isock);
+    isock -> sin_family = hp -> h_addrtype;
+    isock -> sin_port = port;
+    inaddr_copy (hp, isock);
+
+    if ((sd = start_tcp_client ((struct sockaddr_in *) NULL, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("start_tcp_client"));
+
+       return NOTOK;
+    }
+
+    if (join_tcp_server (sd, isock) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("join_tcp_server"));
+
+       (void) close_tcp_socket (sd);
+       return NOTOK;
+    }
+
+    return sd;
+}
+
+/* \f */
+
+int    join_bridge_server (fd, remote)
+int    fd;
+register struct NSAPaddr *remote;
+{
+    if (remote != NULLNA)
+        remote -> na_stack = NA_BRG, remote -> na_community = ts_comm_x25_default;
+    if (bridge_write_nsap_addr (fd, remote, write_tcp_socket) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("write of NSAP failed"));
+
+       return NOTOK;
+    }
+
+    return fd;
+}
+
+/* \f */
+
+int    start_bridge_server (local, backlog, opt1, opt2)
+struct NSAPaddr *local;
+int    backlog,
+       opt1,
+       opt2;
+{
+    int     len,
+            new,
+            sd;
+    u_short port;
+    struct servent *sp;
+    struct sockaddr_in in_socket;
+    register struct sockaddr_in *isock = &in_socket;
+
+    if (bridge_inited == 0) {
+       for (sd = 0; sd < FD_SETSIZE; sd++)
+           assfd[sd] = NOTOK;
+       bridge_inited = 1;
+    }
+    if ((sp = getservbyname ("x25bridge", "tcp")) == NULL)
+       port = x25_bridge_port;
+    else
+       port = sp -> s_port;
+
+    if ((sd = in_connect (x25_bridge_host, port)) == NOTOK)
+       return NOTOK;
+
+    if (write_tcp_socket (sd, "\02", 1) != 1) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("initial write"));
+
+       (void) close_tcp_socket (sd);
+       return NOTOK;
+    }
+
+    if (local != NULLNA)
+       local -> na_stack = NA_BRG, local -> na_community = ts_comm_x25_default;
+    if (local != NULLNA && local -> na_dtelen == 0)
+    {
+       (void) strcpy (local -> na_dte, x25_bridge_addr);
+       local -> na_dtelen = strlen(x25_bridge_addr);
+    }
+    if (local != NULLNA) {
+       DLOG (compat_log, LLOG_DEBUG,
+             ("addr", "type=%d '%s' len=%d",
+              local -> na_stack, local -> na_dte,local -> na_dtelen));
+       DLOG (compat_log, LLOG_DEBUG,
+             ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
+              local -> na_pid, local -> na_pidlen,
+              local -> na_fac, local -> na_faclen,
+              local -> na_pid, local -> na_pidlen,
+              local -> na_cudf, local -> na_cudflen));
+    }
+
+    if (bridge_write_nsap_addr (sd, local, write_tcp_socket) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("write of NSAP failed"));
+
+       (void) close_tcp_socket (sd);
+       return NOTOK;
+    }
+
+    if ((new = in_listen (backlog, opt1, opt2)) == NOTOK) {
+       (void) close_tcp_socket (sd);
+       return NOTOK;
+    }
+
+    len = sizeof *isock;
+    if (getsockname (new, (struct sockaddr *) isock, &len) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("getsockname"));
+
+out: ;
+       (void) close_tcp_socket (sd);
+       (void) close_tcp_socket (new);
+       return NOTOK;
+    }
+
+    isock -> sin_family = htons (isock -> sin_family);
+    if (write_tcp_socket (sd, (char *)isock, sizeof *isock) != sizeof *isock) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("write of sockaddr_in"));
+
+       goto out;
+    }
+    assfd[new] = sd;
+
+    return new;
+}
+
+int    get_bridge_assfd(fd)
+int    fd;
+{
+    if (!bridge_inited)
+       return NOTOK;
+    return assfd[fd];
+}
+
+/* \f */
+
+static int  in_listen (backlog, opt1, opt2)
+int    backlog,
+       opt1,
+       opt2;
+{
+    int     sd;
+    char   *cp;
+    struct sockaddr_in  lo_socket;
+    register struct sockaddr_in *lsock = &lo_socket;
+    register struct hostent *hp;
+
+    if ((hp = gethostbystring (cp = getlocalhost ())) == NULL) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, ("%s: unknown host", cp));
+
+       return NOTOK;
+    }
+
+    bzero ((char *) lsock, sizeof *lsock);
+    lsock -> sin_family = hp -> h_addrtype;
+    inaddr_copy (hp, lsock);
+
+    if ((sd = start_tcp_server (lsock, backlog, opt1, opt2)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("start_tcp_server"));
+
+       return NOTOK;
+    }
+
+    return sd;
+}
+
+/* \f */
+
+int    join_bridge_client (fd, remote)
+int    fd;
+struct NSAPaddr        *remote;
+{
+    int     new;
+    struct sockaddr_in  in_socket;
+    struct NSAPaddr    sock;
+
+    if ((new = join_tcp_client (fd, &in_socket)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("join_tcp_client"));
+
+       return NOTOK;
+    }
+
+    if (bridge_read_nsap_addr (new, &sock, read_tcp_socket) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("read of NSAP"));
+
+       (void) close_tcp_socket (new);
+       return NOTOK;
+    }
+    DLOG (compat_log, LLOG_DEBUG,
+         ("addr", "type=%d '%s' len=%d", sock.na_stack, sock.na_dte,
+          sock.na_dtelen));
+    DLOG (compat_log, LLOG_DEBUG,
+         ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
+          sock.na_pid, sock.na_pidlen,
+          sock.na_fac, sock.na_faclen,
+          sock.na_pid, sock.na_pidlen,
+          sock.na_cudf, sock.na_cudflen));
+    sock.na_stack = ntohl (sock.na_stack);
+    *remote = sock;
+    DLOG (compat_log, LLOG_DEBUG,
+         ("addr", "type=%d '%s' len=%d",
+          remote -> na_stack, remote -> na_dte,remote -> na_dtelen));
+    DLOG (compat_log, LLOG_DEBUG,
+         ("addr", "pid='%s'(%d) fac='%s'(%d) cudf='%s'(%d)",
+          remote -> na_pid, remote -> na_pidlen,
+          remote -> na_fac, remote -> na_faclen,
+          remote -> na_pid, remote -> na_pidlen,
+          remote -> na_cudf, remote -> na_cudflen));
+    return new;
+}
+
+int    close_bridge_socket (sd)
+int    sd;
+{
+       if (bridge_inited && assfd[sd] != NOTOK)
+               (void) close_tcp_socket (assfd[sd]);
+       assfd[sd] = NOTOK;
+       return close_tcp_socket (sd);
+}
+
+/* ARGSUSED */
+
+int    bridgediscrim (na)
+struct NSAPaddr *na;
+{
+#ifndef        X25
+    return 1;  /* must be bridge */
+#else
+    int len = strlen (x25_bridge_discrim);
+
+    if (len == 1 && *x25_bridge_discrim == '-')
+       return 0;
+
+    return (len == 0 ? 1
+                    : strncmp (na -> na_dte, x25_bridge_discrim, len) == 0);
+#endif
+}
+#endif
+
+/*
+ * Structure is as follows :-
+ * 0-1         type
+ * 2-17        dte
+ * 18          dte len
+ * 19-22       pid
+ * 23          pid len
+ * 24-39       user data
+ * 40          user data len
+ * 41-46       facilities
+ * 47          facility length
+ */
+int bridge_write_nsap_addr (fd, nsap, writefnx)
+int    fd;
+struct NSAPaddr *nsap;
+IFP    writefnx;
+{
+    u_short    na_stack;
+    char       buffer[50];
+
+    if (nsap == NULLNA || (na_stack = nsap -> na_stack) != NA_BRG)
+       return NOTOK;
+    na_stack = htons(na_stack);
+    bcopy ((char *)&na_stack, buffer, sizeof(na_stack));
+    bcopy (nsap -> na_dte, &buffer[2], 16);
+    buffer[18] = nsap -> na_dtelen;
+    bcopy (nsap -> na_pid, &buffer[19], 4);
+    buffer[23] = nsap -> na_pidlen;
+    bcopy (nsap -> na_cudf, &buffer[24], 16);
+    buffer[40] = nsap -> na_cudflen;
+    bcopy (nsap -> na_fac, &buffer[41], 6);
+    buffer[47] = nsap -> na_faclen;
+    if ((*writefnx) (fd, buffer, 48) != 48)
+       return NOTOK;
+    return OK;
+}
+
+static int  readx ();
+
+int    bridge_read_nsap_addr (fd, nsap, readfnx)
+int    fd;
+struct NSAPaddr *nsap;
+IFP    readfnx;
+{
+    u_short    na_stack;
+    char       buffer[50];
+
+    if (readx (fd, buffer, 48, readfnx) != 48)
+       return NOTOK;
+    bcopy (buffer, (char *)&na_stack, sizeof(na_stack));
+    na_stack = ntohs(na_stack);
+    if (na_stack != NA_BRG)
+       return NOTOK;
+    nsap -> na_stack = na_stack;
+    bcopy (&buffer[2], nsap -> na_dte, 16);
+    nsap -> na_dtelen = buffer[18];
+    bcopy (&buffer[19], nsap -> na_pid, 4);
+    nsap -> na_pidlen = buffer[23];
+    bcopy (&buffer[24], nsap -> na_cudf, 16);
+    nsap -> na_cudflen = buffer[40];
+    bcopy (&buffer[41], nsap -> na_fac, 6);
+    nsap -> na_faclen = buffer[47];
+    return OK;
+}
+
+static int  readx (fd, buffer, n, readfnx)
+int     fd;
+char    *buffer;
+int     n;
+IFP     readfnx;
+{
+    register int    i,
+    cc;
+    register char   *bp;
+
+    for (bp = buffer, i = n; i > 0; bp += cc, i -= cc) {
+       switch (cc = (*readfnx) (fd, bp, i)) {
+           case NOTOK:
+               return (i = bp - buffer) ? i : NOTOK;
+
+           case OK:
+               break;
+
+           default:
+               continue;
+       }
+       break;
+    }
+
+    return (bp - buffer);
+}
diff --git a/src/isode/compat/camtec.c b/src/isode/compat/camtec.c
new file mode 100644 (file)
index 0000000..20e251b
--- /dev/null
@@ -0,0 +1,268 @@
+/* camtec.c - X.25, CONS abstractions for CAMTEC CCL  */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by Keith Ruttle, CAMTEC Electronics Ltd
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:01  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:27  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:34  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:50  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+
+#ifdef  X25
+
+#include "x25.h"
+#include "isoaddrs.h"
+
+
+#ifdef  CAMTEC_CCL
+
+#include "tailor.h"
+#include "tpkt.h"
+
+/* \f   4.[23] UNIX: CCL X25 */
+
+
+static char calling_dte[NSAP_DTELEN + 1];
+
+/* \f */
+
+int     start_x25_client (local)
+struct NSAPaddr *local;
+{
+    int     sd, pgrp;
+    CONN_DB l_iov;
+
+    if (local != NULLNA)
+       local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+    if ((sd = socket (AF_CCL, SOCK_STREAM, CCLPROTO_X25)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    l_iov.ccl_iovec[0].iov_base = calling_dte;
+    gen2if(local, &l_iov, ADDR_LOCAL);
+
+    return sd;
+}
+
+/* \f */
+
+int     start_x25_server (local, backlog, opt1, opt2)
+struct NSAPaddr *local;
+int     backlog,
+       opt1,
+       opt2;
+{
+    int     sd, pgrp;
+    CONN_DB b_iov;
+    char param1[128];
+
+    b_iov.ccl_iovec[0].iov_base = param1;
+
+    if ((sd = socket (AF_CCL, SOCK_STREAM, CCLPROTO_X25)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK; /* Can't get an X.25 socket */
+    }
+
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    if (local != NULLNA) {
+       local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+       if (local -> na_dtelen == 0) {
+           (void) strcpy (local -> na_dte, x25_local_dte);
+           local -> na_dtelen = strlen(x25_local_dte);
+           if (local -> na_pidlen == 0 && *x25_local_pid)
+               local -> na_pidlen =
+                   str2sel (x25_local_pid, -1, local -> na_pid, NPSIZE);
+       }
+    }
+
+    (void) gen2if (local, &b_iov, ADDR_LISTEN);
+    if (bind (sd, &b_iov, sizeof(b_iov)) != NOTOK) {
+       if (ioctl(sd, CCL_AUTO_ACCEPT, 1) < 0) {
+               SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+                     ("CCL_AUTO_ACCEPT"));
+               close (sd);
+               return NOTOK;
+       }
+       (void) listen (sd, backlog);
+       return sd;
+    }
+
+    (void) close (sd);
+    return NOTOK;
+}
+
+/* \f */
+
+int     join_x25_client (fd, remote)
+int     fd;
+struct NSAPaddr *remote;
+{
+    CONN_DB     sck;
+    struct iovec *iov;
+    int         i, len = 0;
+    int         nfd;
+    char        param1[128];
+    char        param2[128];
+    char        param3[128];
+    char        param4[256];
+
+    iov = &(sck.ccl_iovec[0]);
+    if((nfd = accept (fd, (char *) 0, &len)) == NOTOK)
+       return NOTOK;
+    iov[0].iov_base = param1;
+    iov[1].iov_base = param2;
+    iov[2].iov_base = param3;
+    iov[3].iov_base = param4;
+    iov[0].iov_len = iov[1].iov_len = iov[2].iov_len = 128;
+    iov[3].iov_len = 256;
+    iov[4].iov_len = iov[5].iov_len = iov[6].iov_len = 0;
+    if (ioctl(nfd, CCL_FETCH_CONNECT, &iov[0]) < 0)
+       return NOTOK;
+    (void) if2gen (remote, &sck, ADDR_REMOTE);
+    ioctl (nfd, CCL_SEND_TYPE, 0);
+    return nfd;
+}
+
+int     join_x25_server (fd, remote)
+int     fd;
+struct NSAPaddr *remote;
+{
+    CONN_DB zsck;
+    CONN_DB *sck = &zsck;
+    int r;
+    struct iovec *iov = &( zsck.ccl_iovec[0] );
+    char        param1[128];
+    char        param3[128];
+    char        param4[256];
+
+    if (remote == NULLNA || remote -> na_stack != NA_X25)
+    {
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+             ("Invalid type na%d", remote->na_stack));
+       return NOTOK;
+    }
+
+    iov[0].iov_base = param1;
+    iov[1].iov_base = calling_dte;
+    iov[1].iov_len = strlen(calling_dte);
+    iov[2].iov_base = param3;
+    iov[3].iov_base = param4;
+    iov[4].iov_len = iov[5].iov_len = iov[6].iov_len = 0;
+
+    (void) gen2if (remote, sck, ADDR_REMOTE);
+    if ((r = connect (fd, sck, sizeof (CONN_DB))) >= 0)
+           ioctl (fd, CCL_SEND_TYPE, 0);
+    bzero(calling_dte, sizeof calling_dte );
+    return (r);
+}
+
+int     read_x25_socket (fd, buffer, len)
+int     fd, len;
+char    *buffer;
+{
+    static u_char mode;
+    int cc, count = 0, total = len;
+    char *p = buffer;
+
+    do {
+           cc = recv (fd, p, total, 0);
+           switch (cc) {
+               case NOTOK:
+                       if (errno == ECONNRESET) {
+                               struct iovec iov[7];
+                               char parm[34];
+                               int i;
+                               iov[0].iov_base = parm;
+                               iov[0].iov_len = 1;
+                               iov[1].iov_base = parm + 1;
+                               iov[1].iov_len = 32;
+                               for (i = 2; i < 7; i++) {
+                                       iov[i].iov_base = (char *)0;
+                                       iov[i].iov_len = 0;
+                               }
+                               ioctl(fd, CCL_FETCH_RESET, iov);
+                       elucidate_x25_err( 1 << RECV_DIAG, iov[0].iov_base);
+                       }
+               case 0:
+                       return cc;
+
+               default:
+                       ioctl (fd, CCL_RECV_TYPE, &mode);
+                       count += cc;
+                       p += cc;
+                       total -= cc;
+                       break;
+           }
+    } while (total > 0 && (mode & MORE_DATA));
+
+    DLOG (compat_log, LLOG_DEBUG,
+         ("X25 read, total %d", count ));
+    return count;
+}
+
+int     write_x25_socket (fd, buffer, len)
+int     fd, len;
+char    *buffer;
+{
+    int         count;
+    int         cc;
+
+    count = send(fd, buffer, len, 0);
+    DLOG (compat_log, LLOG_DEBUG,
+         ("X25 write, total %d/%d", count, len));
+    return count;
+}
+#else  /* CAMTEC_CCL */
+int    _camtec_sunlink_stub2 () {}
+#endif  /* CAMTEC_CCL */
+#else  /* X25 */
+int    _camtec_sunlink_stub () {}
+#endif  /* X25 */
diff --git a/src/isode/compat/chkpassword.c b/src/isode/compat/chkpassword.c
new file mode 100644 (file)
index 0000000..bbb5412
--- /dev/null
@@ -0,0 +1,101 @@
+/* chkpassword.c - check the password */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:03  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:30  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:35  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:50  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+
+char   *crypt ();
+
+
+#ifdef KRB_PASSWD
+#include <krb.h>
+#endif
+
+/* L.McLoughlin added kerberos passwd checking - based on original
+ * code from xnlock by S. Lacey.
+ * Takes the username, the password from the password file, and the passwd
+ * the user is trying to use.
+ * Returns 1 if the passwd matches otherwise 0.
+ */
+
+#ifndef        KRB_PASSWD
+/* ARGSUSED */
+#endif
+
+int    chkpassword ( usrname, pwpass, usrpass )
+char   *usrname;
+char   *pwpass;
+char   *usrpass;
+{
+#ifdef KRB_PASSWD
+       char realm[REALM_SZ];
+       int krbval;
+
+       /* 
+        * check to see if the passwd is `*krb*'
+        * if it is, use kerberos
+        */
+
+       if (strcmp(pwpass, "*krb*") == 0) {
+               /*
+                * use kerberos, first of all find the realm
+                */
+               if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+                       (void) strncpy(realm, KRB_REALM, sizeof(realm));
+               }
+
+               /*
+                * now check the passwd
+                */
+               krbval = krb_get_pw_in_tkt(usrname, "",
+                                          realm, "krbtgt",
+                                          realm,
+                                          DEFAULT_TKT_LIFE, usrpass);
+
+               return (krbval == INTK_OK);;
+       }
+#endif
+
+       /*
+        * use passwd file password
+        */
+       return (strcmp(crypt(usrpass, pwpass), pwpass) == 0);
+}
diff --git a/src/isode/compat/chrcnv.c b/src/isode/compat/chrcnv.c
new file mode 100644 (file)
index 0000000..ec53a1a
--- /dev/null
@@ -0,0 +1,82 @@
+/* chrcnv.c - character conversion table */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:05  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:32  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:37  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:51  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+
+/* \f */
+
+char                                   /* character conversion table   */
+       chrcnv[] =                     /*   lower to upper case letters */
+{
+    '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7',
+    '\10', '\t', '\n', '\13', '\14', '\r', '\16', '\17',
+    '\20', '\21', '\22', '\23', '\24', '\25', '\26', '\27',
+    '\30', '\31', '\32', '\33', '\34', '\35', '\36', '\37',
+    ' ', '!', '"', '#', '$', '%', '&', '\47',
+    '(', ')', '*', '+', ',', '-', '.', '/',
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', ':', ';', '<', '=', '>', '?',
+    '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+    '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'X', 'Y', 'Z', '{', '|', '}', '~', '\177',
+    '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7',
+    '\10', '\t', '\n', '\13', '\14', '\r', '\16', '\17',
+    '\20', '\21', '\22', '\23', '\24', '\25', '\26', '\27',
+    '\30', '\31', '\32', '\33', '\34', '\35', '\36', '\37',
+    ' ', '!', '"', '#', '$', '%', '&', '\47',
+    '(', ')', '*', '+', ',', '-', '.', '/',
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', ':', ';', '<', '=', '>', '?',
+    '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+    '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'X', 'Y', 'Z', '{', '|', '}', '~', '\177'
+};
+
diff --git a/src/isode/compat/cmd_srch.c b/src/isode/compat/cmd_srch.c
new file mode 100644 (file)
index 0000000..7266d81
--- /dev/null
@@ -0,0 +1,58 @@
+/* cmd_srch.c - search a lookup table: return numeric value */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:07  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:34  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:38  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:51  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "manifest.h"
+#include "cmd_srch.h"
+
+/* \f */
+
+/* map a string onto a value */
+
+cmd_srch(str, cmd)
+register char   *str;
+register CMD_TABLE *cmd;
+{
+       extern char chrcnv[];
+
+       for(;cmd->cmd_key != NULLCP; cmd++)
+               if(chrcnv[*str] == chrcnv[*cmd->cmd_key] &&
+                  lexequ(str, cmd->cmd_key) == 0)
+                       return(cmd->cmd_value);
+       return(cmd->cmd_value);
+}
diff --git a/src/isode/compat/configure.in b/src/isode/compat/configure.in
new file mode 100644 (file)
index 0000000..cdff2db
--- /dev/null
@@ -0,0 +1,2 @@
+AC_INIT(configure.in)
+AC_OUTPUT(Makefile)
diff --git a/src/isode/compat/dgram.c b/src/isode/compat/dgram.c
new file mode 100644 (file)
index 0000000..7c15fb2
--- /dev/null
@@ -0,0 +1,805 @@
+/* dgram.c - datagram (CL-mode TS) abstractions */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:11  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:37  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:42  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:52  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+#include "dgram.h"
+#ifdef TCP
+#include "internet.h"
+#endif
+#ifdef TP4
+#include "tp4.h"
+#endif
+
+
+#if    defined(SOCKETS) && (defined(TCP) || defined(CLTS))
+#ifndef        DEBUG
+#define        action(s,f,i)
+#else
+static action ();
+#endif
+
+extern int  errno;
+extern IFP set_check_fd ();
+
+/* \f */
+
+union sockaddr_un {            /* 'cause sizeof (struct sockaddr_iso) == 32 */
+    struct sockaddr    sa;
+
+#ifdef TCP
+    struct sockaddr_in sin;
+#endif
+
+#ifdef BSD_TP4
+    union sockaddr_osi sosi;
+#endif
+};
+
+
+struct dgramblk {
+    int            dgram_parent;
+    union sockaddr_un dgram_peer;
+#ifdef BSD44
+    u_char  dgram_addrlen;
+#endif
+
+    struct qbuf dgram_queue;
+};
+
+
+static int     maxpeers = 0;
+static struct dgramblk *peers = NULL;
+
+/* \f */
+
+#ifdef TCP
+
+/* ARGSUSED */
+
+int    start_udp_server (sock, backlog, opt1, opt2)
+struct sockaddr_in *sock;
+int    backlog,
+       opt1,
+       opt2;
+{
+    register int    port;
+    int     sd;
+#ifdef BSD43
+    int            onoff;
+#endif
+    register struct dgramblk *up,
+                           *vp;
+
+    if (peers == NULL) {
+       maxpeers = getdtablesize ();
+       peers = (struct dgramblk *) calloc ((unsigned)maxpeers, sizeof *peers);
+       if (peers == NULL)
+           return NOTOK;
+
+       for (vp = (up = peers) + maxpeers; up < vp; up++) {
+           up -> dgram_parent = NOTOK;
+           up -> dgram_queue.qb_forw = up -> dgram_queue.qb_back =
+               &up -> dgram_queue;
+       }
+    }
+
+    if ((sd = socket (AF_INET, SOCK_DGRAM, 0)) == NOTOK)
+       return NOTOK;
+
+    if (sock -> sin_port != 0) {
+       action ("BIND", sd, (struct sockaddr *) sock);
+
+       if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
+           goto got_socket;
+
+       (void) close (sd);
+       return NOTOK;
+    }
+    else
+       sock -> sin_family = AF_INET;
+
+    for (port = IPPORT_RESERVED;; port++) {
+       sock -> sin_port = htons ((u_short) port);
+
+       action ("BIND", sd, (struct sockaddr *) sock);
+
+       if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
+           break;
+
+       switch (errno) {
+           case EADDRINUSE: 
+               continue;
+
+           case EADDRNOTAVAIL: 
+           default: 
+               (void) close (sd);
+               return NOTOK;
+       }
+    }
+
+got_socket: ;
+#ifdef DEBUG
+    {
+       int     len = sizeof *sock;
+
+       action ("FOO1", sd, (struct sockaddr *) sock);
+       if (getsockname (sd, (struct sockaddr *) sock, &len) != NOTOK)
+           action ("FOO2", sd, (struct sockaddr *) sock);
+    }
+#endif
+
+#ifndef        BSD43
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
+#else
+    onoff = 1;
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
+#endif
+
+    (void) set_check_fd (sd, check_dgram_socket, NULLCP);
+    return (peers[sd].dgram_parent = sd);
+}
+#endif
+
+/* \f */
+
+#ifdef BSD_TP4
+
+/* ARGSUSED */
+
+int    start_clts_server (sock, backlog, opt1, opt2)
+union sockaddr_osi *sock;
+int    backlog,
+       opt1,
+       opt2;
+{
+    int     sd;
+#ifdef BSD43
+    int            onoff;
+#endif
+    u_char *cp;
+    register struct dgramblk *up,
+                           *vp;
+    struct sockaddr_iso *ifaddr = &sock -> osi_sockaddr;
+
+    if (peers == NULL) {
+       maxpeers = getdtablesize ();
+       peers = (struct dgramblk *) calloc ((unsigned)maxpeers, sizeof *peers);
+       if (peers == NULL)
+           return NOTOK;
+
+       for (vp = (up = peers) + maxpeers; up < vp; up++) {
+           up -> dgram_parent = NOTOK;
+           up -> dgram_queue.qb_forw = up -> dgram_queue.qb_back =
+               &up -> dgram_queue;
+       }
+    }
+
+    if ((sd = socket (AF_ISO, SOCK_DGRAM, 0)) == NOTOK)
+       return NOTOK;
+
+    if (ifaddr -> siso_tlen != 0) {
+       action ("BIND", sd, (struct sockaddr *) ifaddr);
+
+       if (bind (sd, (struct sockaddr *) ifaddr, (int) ifaddr -> siso_len)
+               != NOTOK)
+           goto got_socket;
+
+       (void) close (sd);
+       return NOTOK;
+    }
+    else
+       ifaddr -> siso_family = AF_ISO;
+
+    {
+       int     pid;
+       u_char *dp,
+              *ep,
+              *fp;
+
+       pid = getpid ();
+       cp = fp = (u_char *) ifaddr -> siso_data + ifaddr -> siso_nlen;
+       for (ep = (dp = (u_char *) &pid) + sizeof pid; dp < ep; dp++)
+           *cp++ = *dp;
+       ifaddr -> siso_tlen = (cp - fp) + 1;
+       ifaddr -> siso_slen = ifaddr -> siso_plen = 0;
+       ifaddr -> siso_len = sizeof *ifaddr;
+    }
+
+    for (*cp = 0x00; *cp < 0xff; *cp += 1) {
+       action ("BIND", sd, (struct sockaddr *) ifaddr);
+
+       if (bind (sd, (struct sockaddr *) ifaddr, (int) ifaddr -> siso_len)
+               != NOTOK)
+           goto got_socket;
+
+       switch (errno) {
+           case EADDRINUSE:
+               continue;
+
+           case EADDRNOTAVAIL:
+           default:
+               (void) close (sd);
+               return NOTOK;
+       }
+    }
+    (void) close (sd);
+    errno = EADDRNOTAVAIL;
+    return NOTOK;
+
+got_socket: ;
+#ifdef DEBUG
+    {
+       int     len = sizeof *sock;
+
+       action ("FOO1", sd, ifaddr);
+       if (getsockname (sd, (struct sockaddr *) ifaddr, &len) != NOTOK)
+           action ("FOO2", sd, ifaddr);
+    }
+#endif
+
+#ifndef        BSD43
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
+#else
+    onoff = 1;
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
+#endif
+
+    (void) set_check_fd (sd, check_dgram_socket, NULLCP);
+    return (peers[sd].dgram_parent = sd);
+}
+#endif
+
+/* \f */
+
+int    join_dgram_aux (fd, sock, newfd)
+int    fd,
+       newfd;
+struct sockaddr *sock;
+{
+    int            nfds,
+           sd;
+    fd_set  ifds;
+    register struct qbuf *qb;
+    register struct dgramblk *up;
+
+    if (fd < 0 || fd >= maxpeers || peers[fd].dgram_parent != fd) {
+       errno = EINVAL;
+       return NOTOK;
+    }
+
+    if (newfd) {
+       FD_ZERO (&ifds);
+
+       nfds = fd + 1;
+       FD_SET (fd, &ifds);
+       if (select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, OK) == NOTOK)
+           return NOTOK;
+
+       up = &peers[fd];
+       if ((qb = up -> dgram_queue.qb_forw) == &up -> dgram_queue) {
+           errno = EWOULDBLOCK;
+           return NOTOK;
+       }
+
+       if ((sd = dup (fd)) == NOTOK)
+           return NOTOK;
+       (void) set_check_fd (fd, check_dgram_socket, NULLCP);
+
+       up = &peers[sd];
+#ifdef BSD44
+       bcopy (qb -> qb_base, (caddr_t) sock,
+              ((struct sockaddr *) qb -> qb_base) -> sa_len);
+#else
+       *sock = *((struct sockaddr *) qb -> qb_base);   /* struct copy */
+#endif
+
+       remque (qb);
+       insque (qb, up -> dgram_queue.qb_back);
+    }
+    else
+       up = &peers[fd];
+
+    up -> dgram_parent = fd;
+#ifdef BSD44
+    if (sock -> sa_len == 0)
+       sock -> sa_len = sizeof *sock;
+    bcopy ((caddr_t) sock, (caddr_t) &up -> dgram_peer, sock -> sa_len);
+    {
+       struct sockaddr_in *sin;
+
+       up -> dgram_addrlen = sock -> sa_family != AF_INET ? sock -> sa_len
+                               : sizeof *sin - sizeof sin -> sin_zero;
+    }
+#else
+    up -> dgram_peer.sa = *sock;       /* struct copy */
+#endif
+
+    action ("JOIN", newfd ? sd : fd, sock);
+
+    return (newfd ? sd : OK);
+}
+
+/* \f */
+
+int    read_dgram_socket (fd, q)
+int    fd;
+struct qbuf **q;
+{
+    int            nfds;
+    fd_set  ifds,
+           mask;
+    register struct qbuf *qb;
+    register struct dgramblk *up;
+
+    if (fd < 0
+           || fd >= maxpeers
+           || (up = &peers[fd]) -> dgram_parent == NOTOK) {
+       errno = EINVAL;
+       return NOTOK;
+    }
+
+    if ((qb = up -> dgram_queue.qb_forw) == &up -> dgram_queue) {
+       FD_ZERO (&mask);
+
+       nfds = fd + 1;
+       FD_SET (fd, &mask);
+       for (ifds = mask;; ifds = mask) {
+           if (select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, NOTOK)
+                   == NOTOK)
+               return NOTOK;
+
+           if ((qb = up -> dgram_queue.qb_forw) != &up -> dgram_queue)
+               break;
+       }
+    }
+
+    remque (qb);
+    qb -> qb_forw = qb -> qb_back = qb;
+
+    *q = qb;
+
+    return qb -> qb_len;
+}
+
+/* \f */
+
+int    hack_dgram_socket (fd, sock)
+int    fd;
+struct  sockaddr *sock;
+{
+    register struct dgramblk *up;
+
+    if (fd < 0
+           || fd >= maxpeers
+           || (up = &peers[fd]) -> dgram_parent != fd) {
+       errno = EINVAL;
+       return NOTOK;
+    }
+
+    if (sock == NULL) {
+       bzero ((caddr_t) &up -> dgram_peer, sizeof up -> dgram_peer);
+       return OK;
+    }
+
+#ifdef BSD44
+    if (sock -> sa_len == 0)
+       sock -> sa_len = sizeof *sock;
+    bcopy ((caddr_t) sock, (caddr_t) &up -> dgram_peer, sock -> sa_len);
+    up -> dgram_addrlen = 0;
+#else
+    up -> dgram_peer.sa = *sock;       /* struct copy */
+#endif
+
+    action ("HACK", fd, sock);
+
+    return OK;
+}
+
+
+int    write_dgram_socket (fd, qb)
+int    fd;
+register struct qbuf *qb;
+{
+    register struct dgramblk *up;
+
+    if (fd < 0
+           || fd >= maxpeers
+           || (up = &peers[fd]) -> dgram_parent == NOTOK
+           || up -> dgram_peer.sa.sa_family == 0) {
+       errno = EINVAL;
+       return NOTOK;
+    }
+
+    action ("SENDTO", fd, &up -> dgram_peer.sa);
+
+#ifdef BSD44
+    return sendto (fd, qb -> qb_data, qb -> qb_len, NULL,
+                  &up -> dgram_peer.sa, (int) up -> dgram_peer.sa.sa_len);
+#else
+    return sendto (fd, qb -> qb_data, qb -> qb_len, NULL,
+                  &up -> dgram_peer.sa, sizeof up -> dgram_peer.sa);
+#endif
+}
+
+
+/* \f */
+
+int    close_dgram_socket (fd)
+int    fd;
+{
+    register struct dgramblk *up,
+                           *vp;
+
+    if (fd < 0
+           || fd >= maxpeers
+           || (up = &peers[fd]) -> dgram_parent == NOTOK) {
+       errno = EINVAL;
+       return NOTOK;
+    }
+
+    action ("CLOSE", fd, &up -> dgram_peer.sa);
+
+    up -> dgram_parent = NOTOK;
+    bzero ((char *) &up -> dgram_peer, sizeof up -> dgram_peer);
+    QBFREE (&up -> dgram_queue);
+    
+    for (vp = (up = peers) + maxpeers; up < vp; up++)
+       if (up -> dgram_parent == fd)
+           up -> dgram_parent = up - peers;
+
+    (void) set_check_fd (fd, NULLIFP, NULLCP);
+    return close (fd);
+}
+
+/* \f */
+
+int    select_dgram_socket (nfds, rfds, wfds, efds, secs)
+int    nfds;
+fd_set *rfds,
+       *wfds,
+       *efds;
+int    secs;
+{
+    register int    fd;
+    int            cc,
+           mfds,
+           result;
+    fd_set  ifds,
+           jfds;
+    register struct qbuf *qb;
+    register struct dgramblk *up,
+                           *vp;
+    struct dgramblk *wp;
+    union sockaddr_un *sock;
+
+    if (rfds) {
+       jfds = *rfds;
+
+       if (secs != OK)
+           for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++)
+               if (up -> dgram_parent != NOTOK
+                       && FD_ISSET (fd, &jfds)
+                       && up -> dgram_queue.qb_forw != &up -> dgram_queue) {
+                   secs = OK;
+                   break;
+               }
+    }
+
+    if ((result = selsocket (nfds, rfds, wfds, efds, secs)) == NOTOK
+           || rfds == NULLFD)
+       return result;
+
+    ifds = *rfds;
+    if ((mfds = nfds) > maxpeers)
+       mfds = maxpeers;
+    for (fd = 0, up = peers; fd < mfds; fd++, up++)
+       if (FD_ISSET (fd, &ifds)) {
+           int     slen;
+           u_char  len;
+           char   *data;
+
+           FD_CLR (fd, &ifds);
+
+           if (up -> dgram_parent == NOTOK)
+               continue;
+
+           if ((qb = (struct qbuf *) malloc ((unsigned) (sizeof *qb
+                                                         + (slen
+                                                               = sizeof *sock)
+                                                         + MAXDGRAM)))
+                   == NULL)
+               return NOTOK;
+
+           sock = (union sockaddr_un *) qb -> qb_base;
+           qb -> qb_data = qb -> qb_base + slen;
+           if ((cc = recvfrom (fd, qb -> qb_data, MAXDGRAM, NULL,
+                               &sock -> sa, &slen)) == NOTOK) {
+               free ((char *) qb);
+               return NOTOK;
+           }
+#ifdef BSD44
+           sock -> sa.sa_len = slen;
+#endif
+           qb -> qb_len = cc;
+
+           action ("RECVFROM", fd, &sock -> sa);
+
+           vp = up;
+           data = sock -> sa.sa_data;
+           switch (sock -> sa.sa_family) {
+               case AF_INET:   /* XXX: doesn't take into account padding */
+                   len = sizeof sock -> sa.sa_data
+                       - sizeof sock -> sin.sin_zero;
+                   break;
+
+               default:
+#ifdef BSD44
+                   len = sock -> sa.sa_len;
+#else
+                   len = sizeof sock -> sa;
+#endif
+                   break;
+           }
+           if (
+#ifdef BSD44
+               len != up -> dgram_addrlen ||
+#endif
+               bcmp (data, up -> dgram_peer.sa.sa_data, (int) len)
+                           != 0) {
+               for (wp = (vp = peers) + maxpeers; vp < wp; vp++)
+                   if (vp != up
+                           && vp -> dgram_parent == up -> dgram_parent
+#ifdef BSD44
+                           && len == vp -> dgram_addrlen
+#endif
+                           && bcmp (data, vp -> dgram_peer.sa.sa_data,
+                                    (int) len) == 0)
+                       break;
+               if (vp >= wp
+                       && (vp = &peers[up -> dgram_parent])
+                                           -> dgram_peer.sa.sa_family != 0) {
+                   free ((char *) qb);
+                   continue;
+               }
+           }
+
+           insque (qb, vp -> dgram_queue.qb_back);
+
+           if (--result <= 0
+                   || (result = selsocket (nfds, &ifds, NULLFD, NULLFD, OK))
+                           <= 0)
+               break;
+           
+       }
+
+    for (vp = (up = peers) + maxpeers, fd = 0; up < vp; up++, fd++)
+       if (up -> dgram_parent != NOTOK && FD_ISSET (fd, &jfds))
+           if (up -> dgram_queue.qb_forw != &up -> dgram_queue)
+               FD_SET (fd, rfds);
+           else
+               FD_CLR (fd, rfds);
+
+    result = 0;
+    ifds = *rfds;
+    if (wfds)
+       for (fd = 0; fd < nfds; fd++)
+           if (FD_ISSET (fd, wfds))
+               FD_SET (fd, &ifds);
+    if (efds)
+       for (fd = 0; fd < nfds; fd++)
+           if (FD_ISSET (fd, efds))
+               FD_SET (fd, &ifds);
+    for (fd = 0; fd < nfds; fd++)
+       if (FD_ISSET (fd, &ifds))
+           result++;
+
+    return result;
+}
+
+/* \f */
+
+int    check_dgram_socket (fd)
+int    fd;
+{
+    int            nfds;
+    fd_set  ifds;
+
+    FD_ZERO (&ifds);
+
+    nfds = fd + 1;
+    FD_SET (fd, &ifds);
+
+    return select_dgram_socket (nfds, &ifds, NULLFD, NULLFD, OK);
+}
+
+/* \f */
+
+#ifdef DEBUG
+
+#ifdef TCP
+#include "isoaddrs.h"
+
+
+static inetprint (sin, bp)
+struct sockaddr_in *sin;
+char   *bp;
+{
+    (void) sprintf (bp, "Internet=%s+%d+%d", inet_ntoa (sin -> sin_addr),
+                   (int) ntohs (sin -> sin_port), NA_TSET_UDP);
+}
+#endif
+
+/* \f */
+
+#ifdef CLTS
+/* prints OSI address using the format described in:
+
+       "A string encoding of Presentation Address"
+
+       S.E. Kille, Research Note RN/89/14, February 1989
+       Department of Computer Science
+       University College London
+
+ */
+
+#ifndef SSEL
+#define SSEL(s) ((s)->siso_tlen + TSEL(s))
+#define PSEL(s) ((s)->siso_slen + SSEL(s))
+#endif
+
+
+static isoprint (siso, bp)
+register struct sockaddr_iso *siso;
+char   *bp;
+{
+    int            didone = 0;
+
+    if (siso -> siso_plen) {
+       hexprint (bp, siso -> siso_plen, PSEL (siso), "'", "'H");
+       bp += strlen (bp);
+       *bp++ = '/';
+       didone++;
+    }
+    if (siso -> siso_slen || didone) {
+       hexprint (bp, siso -> siso_slen, SSEL (siso), "'", "'H");
+       bp += strlen (bp);
+       *bp++ = '/';
+       didone++;
+    }
+    if (siso -> siso_tlen || didone) {
+       hexprint (bp, siso -> siso_tlen, TSEL (siso), "'", "'H");
+       bp += strlen (bp);
+       *bp++ = '/';
+       didone++;
+    }
+    hexprint (bp, siso -> siso_nlen, siso -> siso_data, "NS+", "");
+}
+
+
+static hexprint (bp, n, buf, start, stop)
+char   *bp;
+int    n;
+u_char *buf;
+char   *start,
+       *stop;
+{
+        register u_char *in = buf, *top = in + n;
+        if (n == 0)
+           return;
+
+       (void) strcpy (bp, start);
+       bp += strlen (bp);
+
+        while (in < top) {
+           (void) sprintf (bp, "%02x", *in++ & 0xff);
+           bp += 2;
+       }
+
+        (void) strcpy (bp, stop);
+}
+#endif
+
+/* \f */
+
+static struct printent {
+    int            p_family;
+    IFP            p_function;
+} ents[] = {
+#ifdef TCP
+    AF_INET,   inetprint,
+#endif
+
+#ifdef CLTS
+    AF_ISO,    isoprint,
+#endif
+
+    NULL
+};
+
+static action (s, fd, sock)
+char   *s;
+int    fd;
+struct sockaddr *sock;
+{
+    char    buffer[BUFSIZ];
+    register struct printent *p;
+
+    if (!(compat_log -> ll_events & LLOG_TRACE))
+       return;
+
+    for (p = ents; p -> p_family; p++)
+       if (p -> p_family == sock -> sa_family)
+           break;
+    if (!p -> p_family) {
+       DLOG (compat_log, LLOG_EXCEPTIONS,
+             ("unknown dgram address family 0x%x", sock -> sa_family));
+       return;
+    }
+
+    (void) (*p -> p_function) (sock, buffer);
+
+    DLOG (compat_log, LLOG_TRACE, ("%-10.10s %d %s", s, fd, buffer));
+}
+#endif
+
+#else
+
+/* \f */
+
+int    dgram_dummy () {}
+
+#endif
diff --git a/src/isode/compat/explode.c b/src/isode/compat/explode.c
new file mode 100644 (file)
index 0000000..a26cdcd
--- /dev/null
@@ -0,0 +1,69 @@
+/* explode.c - explode octets into ascii */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:12  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:39  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:43  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f   DATA */
+
+static char nib2hex[0x10] = {
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
+/* \f */
+
+int    explode (a, b, n)
+register char  *a;
+register u_char *b;
+register int    n;
+{
+    register int    i;
+    register u_char c;
+
+    for (i = 0; i < n; i++) {
+       c = *b++;
+       *a++ = nib2hex[(u_char)(c & 0xf0) >> 4];
+       *a++ = nib2hex[(c & 0x0f)];
+    }
+    *a = NULL;
+
+    return (n * 2);
+}
diff --git a/src/isode/compat/general.c b/src/isode/compat/general.c
new file mode 100644 (file)
index 0000000..3d5bb27
--- /dev/null
@@ -0,0 +1,162 @@
+/* general.c - general utilities for emulation of 4.2BSD */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:14  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:41  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:45  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f   Berkeley UNIX: 4.2 */
+
+#ifdef BSD42
+
+/* Simply including "general.h" is sufficient. */
+
+int    _general_stub () {};
+
+#endif
+
+/* \f   non-Berkeley UNIX */
+
+#if    !defined(BSDLIBC) || defined(BSD44)
+
+#ifndef        lint
+
+struct qelem {
+    struct qelem   *q_forw;
+    struct qelem   *q_back;
+    char           q_data[1];  /* extensible */
+};
+
+
+insque (elem, pred)
+struct qelem   *elem,
+              *pred;
+{
+    pred -> q_forw -> q_back = elem;
+    elem -> q_forw = pred -> q_forw;
+    elem -> q_back = pred;
+    pred -> q_forw = elem;
+}
+
+
+remque (elem)
+struct qelem   *elem;
+{
+    elem -> q_forw -> q_back = elem -> q_back;
+    elem -> q_back -> q_forw = elem -> q_forw;
+}
+
+#endif
+#endif
+
+/* \f   DUP2 */
+
+#ifndef        BSD42
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+
+
+extern int errno;
+
+
+int     dup2 (d1, d2)
+register int    d1,
+                d2;
+{
+    int     d;
+
+    if (d1 == d2)
+       return OK;
+
+    (void) close (d2);
+#ifdef F_DUPFD
+    if ((d = fcntl (d1, F_DUPFD, d2)) == NOTOK)
+       return NOTOK;
+#else
+    if ((d = dup2_aux (d1, d2)) == NOTOK)
+       return NOTOK;
+#endif
+    if (d == d2)
+       return OK;
+
+    errno = 0;
+    return NOTOK;
+}
+
+
+#ifndef        F_DUPFD
+dup2_aux (d1, d2)
+int    d1,
+       d2;
+{
+    int     fd,
+           result;
+
+    if ((fd = dup (d1)) == NOTOK || fd == d2)
+       return fd;
+
+    result = dup2_aux (d1, d2);
+
+    (void) close (fd);
+
+    return result;
+}
+#endif
+#endif
+
+/* \f    BYTEORDER */
+
+#ifndef        SWABLIB
+
+/* ROS and HP-UX don't seem to have these in libc.a */
+
+#undef ntohs
+u_short        ntohs (netshort) u_short netshort; { return netshort; }
+
+#undef htons
+u_short        htons (hostshort) u_short hostshort; { return hostshort; }
+
+#undef ntohl
+u_long ntohl (netlong) u_long netlong; { return netlong; }
+
+#undef htonl
+u_long htonl (hostlong) u_long hostlong; { return hostlong; }
+
+#endif
diff --git a/src/isode/compat/getpassword.c b/src/isode/compat/getpassword.c
new file mode 100644 (file)
index 0000000..984b3f0
--- /dev/null
@@ -0,0 +1,144 @@
+/* getpassword.c - generic read-the-password-from-the-tty */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:16  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:43  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:46  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <signal.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "sys.file.h"
+
+#ifdef BSD44
+char   *getpass ();
+#endif
+
+/* \f */
+
+/* roll our own since want to get past UNIX's limit of 8 octets... */
+
+char *getpassword (prompt)
+char *prompt;
+{
+#ifndef        BSD44
+    register int    c;
+    int            flags,
+           isopen;
+    register char  *bp,
+                  *ep;
+#if    !defined(SYS5) && !defined(XOS_2)
+    struct sgttyb   sg;
+#else
+    struct termio   sg;
+#endif
+    SFP            istat;
+    FILE    *fp;
+    static char buffer[BUFSIZ];
+
+#ifdef SUNLINK_7_0
+    fp = stdin, isopen = 0;    /* will help greatly to work off a script */
+#else
+    if ((c = open ("/dev/tty", O_RDWR)) != NOTOK && (fp = fdopen (c, "r")))
+       setbuf (fp, NULLCP), isopen = 1;
+    else {
+       if (c != NOTOK)
+           (void) close (c);
+
+       fp = stdin, isopen = 0;
+    }
+#endif
+
+    istat = signal (SIGINT, SIG_IGN);
+
+#if    !defined(SYS5) && !defined(XOS_2)
+    (void) gtty (fileno (fp), &sg);
+    flags = sg.sg_flags;
+    sg.sg_flags &= ~ECHO;
+    (void) stty (fileno (fp), &sg);
+#else
+    (void) ioctl (fileno (fp), TCGETA, (char *) &sg);
+    flags = sg.c_lflag;
+    sg.c_lflag &= ~ECHO;
+    (void) ioctl (fileno (fp), TCSETAW, (char *) &sg);
+#endif
+
+#ifdef SUNLINK_7_0
+    (void) fprintf (stdout, "%s", prompt);
+    (void) fflush (stdout);
+#else
+    (void) fprintf (stderr, "%s", prompt);
+    (void) fflush (stderr);
+#endif
+
+    for (ep = (bp = buffer) + sizeof buffer - 1; (c = getc (fp)) != EOF;)
+#ifndef        apollo
+       if (c == '\n')
+#else
+       if (c == '\n' || c == '\r')
+#endif
+           break;
+       else
+           if (bp < ep)
+               *bp++ = c;
+    *bp = NULL;
+
+#ifdef SUNLINK_7_0
+    (void) fprintf (stdout, "\n");
+    (void) fflush (stdout);
+#else
+    (void) fprintf (stderr, "\n");
+    (void) fflush (stderr);
+#endif
+
+#if    !defined(SYS5) && !defined(XOS_2)
+    sg.sg_flags = flags;
+    (void) stty (fileno (fp), &sg);
+#else
+    sg.c_lflag = flags;
+    (void) ioctl (fileno (fp), TCSETAW, (char *) &sg);
+#endif
+
+    (void) signal (SIGINT, istat);
+
+    if (isopen)
+       (void) fclose (fp);
+
+    return buffer;
+#else
+    return getpass (prompt);
+#endif
+}
diff --git a/src/isode/compat/hpuxx25.c b/src/isode/compat/hpuxx25.c
new file mode 100644 (file)
index 0000000..22ee713
--- /dev/null
@@ -0,0 +1,922 @@
+/* hpuxx25.c - X.25 abstractions for HPUX X25/9000 */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by John Pavel, Department of Trade and Industry/National
+ * Physical Laboratory in the UK
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:18  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:46  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:48  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f   HP UNIX: X25/9000 */
+
+#ifdef  X25
+
+#include "x25.h"
+#include "isoaddrs.h"
+
+#ifdef  HPUX_X25
+
+#define        CALLING 0
+#define        CALLED  1
+#define        PROBE   (-1)
+
+struct  fdl_st {
+          int  fd; 
+          struct fdl_st *next;
+       };
+static struct fdl_st *fdl = NULL;
+static void setup_sigurg ();
+static void clear_sigurg ();
+
+/* \f */
+
+#ifdef  DEBUG
+void    print_x25_facilities ();
+#endif
+
+/* \f */
+
+/* ARGSUSED */
+
+int     start_x25_client (local, priv)
+struct  NSAPaddr *local;
+int     priv;
+{
+    int     sd, pgrp;
+
+    if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK;
+    }
+
+    pgrp = -getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    return sd;
+}
+
+/* \f */
+
+int     start_x25_server (local, backlog, opt1, opt2)
+struct  NSAPaddr *local;
+int     backlog,
+       opt1,
+       opt2;
+{
+    CONN_DB    sbuf;
+    CONN_DB    *sock;
+    int                sd, onoff, pgrp;
+    char       cudfbuf [NPSIZE + CUDFSIZE];
+
+    bzero(&sbuf, sizeof(CONN_DB));
+    sbuf.addr.x25_family = AF_CCITT;
+    if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK;
+    }
+
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    /* if neither dte or pid are given use dte from interface */
+    if (!(local->na_dtelen || local->na_pidlen)) {
+       strcpy (sbuf.addr.x25ifname, "x25_0");
+       if (ioctl (sd, X25_RD_HOSTADR, (char *) &sbuf.addr) == NOTOK) {
+           SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_HOSTADR"));
+           (void) close_x25_socket (sd);
+           return NOTOK;
+       }
+       sbuf.addr.x25ifname [0] = '\0';
+       sbuf.addr.x25hostlen = strlen(sbuf.addr.x25_host);
+       if (x25_dnic_prefix && *x25_dnic_prefix)
+           strcpy (local->na_dte, x25_dnic_prefix);
+       strcat (local->na_dte, sbuf.addr.x25_host);
+       local->na_dtelen = strlen (local->na_dte);
+    }
+    /* Avoid a null local dte address, set it to '0',       */
+    /* gen2if will set it back to zero in interface address */
+    if (!local->na_dtelen) {
+       local->na_dtelen = 1;
+       local->na_dte [0] = '0';
+    }
+    sock = gen2if(local, &sbuf, ADDR_LISTEN);
+
+    if (sock->cudf.x25_cud_len)
+       if (ioctl (sd, X25_WR_USER_DATA, &sock->cudf) == -1) {
+           SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_WR_USER_DATA"));
+           (void) close_x25_socket (sd);
+           return NOTOK;
+       }
+    if (bind (sd, (X25_ADDR *) &sock->addr, sizeof(X25_ADDR)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+
+#ifndef        BSD43
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
+#else
+    onoff = 1;
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
+#endif
+
+    if (set_x25_facilities(sd, CALLED, "Acceptable") == NOTOK) {
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+
+    (void) listen (sd, backlog);
+
+    onoff = 0;
+    if (ioctl (sd, X25_CALL_ACPT_APPROVAL, (char *) &onoff) == NOTOK) {
+       SLOG (x25_log, LLOG_EXCEPTIONS, "failed",
+             ("X25_CALL_ACPT_APPROVAL"));
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+
+    return sd;
+}
+
+/* \f */
+
+int     join_x25_server (fd, remote)
+register int fd;
+register struct NSAPaddr *remote;
+{
+    CONN_DB sbuf;
+    CONN_DB *sock = &sbuf;
+    register int nfd;
+
+    bzero(&sbuf, sizeof(CONN_DB));
+    sbuf.addr.x25_family = AF_CCITT;
+    sock = gen2if (remote, sock, ADDR_REMOTE);
+
+    if (set_x25_facilities(fd, CALLING, "Proposed") == NOTOK)
+       return NOTOK;
+
+    if (sock->cudf.x25_cud_len)
+       if (ioctl (fd, X25_WR_USER_DATA, &sock->cudf) == -1) {
+           SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_WR_USER_DATA"));
+           return NOTOK;
+       }
+    setup_sigurg (fd);
+    if ((nfd = connect (fd, (X25_ADDR *) &sock->addr, sizeof (X25_ADDR)))
+           == NOTOK) {
+       return nfd;
+    }
+#ifdef  DEBUG
+    else
+       if (x25_log -> ll_events & LLOG_DEBUG)
+           (void) log_x25_facilities(fd, CALLING, "Effective Calling");
+#endif
+
+    remote = if2gen (remote, sock, ADDR_REMOTE);
+
+    return nfd;
+}
+
+/* \f */
+
+int     join_x25_client (fd, remote)
+int     fd;
+struct  NSAPaddr *remote;
+{
+    CONN_DB     sbuf;
+    CONN_DB     *sock = &sbuf;
+    int     len = sizeof *sock;
+    int     nfd;
+
+    bzero(&sbuf, sizeof(CONN_DB));
+    sbuf.addr.x25_family = AF_CCITT;
+    if ((nfd = accept (fd, (X25_ADDR *) &sock->addr, &len)) == NOTOK) {
+       return nfd;
+    }
+
+    setup_sigurg (nfd);
+    if (ioctl(nfd,X25_SEND_CALL_ACEPT, NULLCP) < 0)
+       SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_SEND_CALL_ACEPT"));
+
+#ifdef  DEBUG
+     if (x25_log -> ll_events & LLOG_DEBUG)
+        (void) log_x25_facilities(fd, CALLED, "Effective Called");
+#endif
+    remote = if2gen (remote, sock, ADDR_REMOTE);
+
+    return nfd;
+}
+
+/* \f */
+
+int fac_ccitt2hp (ccitt, hp)
+CCITT_FACILITY_DB      *ccitt;
+FACILITY_DB            *hp;
+{
+    register int       i, j;
+    int                        returncode = OK;
+
+    memset (hp, 0, sizeof (FACILITY_DB));
+    for (i = 0; i < ccitt->x25_fac_len; i++)
+    switch (ccitt->x25_fac [i]) {
+       case 0x01:
+           hp->t_01 = ccitt->x25_fac [++i];
+           break;
+       case 0x02:
+           hp->t_02 = ccitt->x25_fac [++i];
+           break;
+       case 0x03:
+           hp->t_03_sel = 1;
+           hp->t_03 = ccitt->x25_fac [++i];
+           break;
+       case 0x07:
+           hp->t_07 = ccitt->x25_fac [++i];
+           break;
+       case 0x41:
+           hp->t_41_sel = 1;
+           hp->t_41 = ccitt->x25_fac [++i] << 8;
+           hp->t_41 += ccitt->x25_fac [++i];
+           break;
+       case 0x42:
+           hp->t_42 [0] = ccitt->x25_fac [++i];
+           hp->t_42 [1] = ccitt->x25_fac [++i];
+           break;
+       case 0x43:
+           hp->t_43 [0] = ccitt->x25_fac [++i];
+           hp->t_43 [1] = ccitt->x25_fac [++i];
+           break;
+       case 0x44:
+           hp->t_44_sel = 1;
+           hp->t_44 = ccitt->x25_fac [++i] << 8;
+           hp->t_44 += ccitt->x25_fac [++i];
+           break;
+       default:
+           /* ignore parameter */
+           returncode = NOTOK;
+           switch (ccitt->x25_fac [i] & 0xc0) {
+               case 0x00:
+                   i += 1; break;
+               case 0x40:
+                   i += 2; break;
+               case 0x80:
+                   i += 3; break;
+               case 0xc0:
+                   i += ccitt->x25_fac [++i]; break;
+           }
+    }
+    return (returncode);
+}
+
+
+void fac_hp2ccitt (hp, ccitt)
+FACILITY_DB            *hp;
+CCITT_FACILITY_DB      *ccitt;
+{
+    register int       i;
+
+    memset (ccitt, 0, sizeof (CCITT_FACILITY_DB));
+    i = 0;
+    if (hp->t_01) {
+       ccitt->x25_fac_len += 2;
+       ccitt->x25_fac [i++] = 0x01;
+       ccitt->x25_fac [i++] = hp->t_01;
+    }
+    if (hp->t_02) {
+       ccitt->x25_fac_len += 2;
+       ccitt->x25_fac [i++] = 0x02;
+       ccitt->x25_fac [i++] = hp->t_02;
+    }
+    if (hp->t_03_sel) {
+       ccitt->x25_fac_len += 2;
+       ccitt->x25_fac [i++] = 0x03;
+       ccitt->x25_fac [i++] = hp->t_03;
+    }
+    if (hp->t_07) {
+       ccitt->x25_fac_len += 2;
+       ccitt->x25_fac [i++] = 0x07;
+       ccitt->x25_fac [i++] = hp->t_07;
+    }
+    if (hp->t_41_sel) {
+       ccitt->x25_fac_len += 3;
+       ccitt->x25_fac [i++] = 0x41;
+       ccitt->x25_fac [i++] = hp->t_41 >> 8;
+       ccitt->x25_fac [i++] = hp->t_41 && 0xff;
+    }
+    if (hp->t_42 [0] || hp->t_42 [1]) {
+       ccitt->x25_fac_len += 3;
+       ccitt->x25_fac [i++] = 0x42;
+       ccitt->x25_fac [i++] = hp->t_42 [0];
+       ccitt->x25_fac [i++] = hp->t_42 [1];
+    }
+    if (hp->t_43 [0] || hp->t_43 [1]) {
+       ccitt->x25_fac_len += 3;
+       ccitt->x25_fac [i++] = 0x43;
+       ccitt->x25_fac [i++] = hp->t_43 [0];
+       ccitt->x25_fac [i++] = hp->t_43 [1];
+    }
+    if (hp->t_44_sel) {
+       ccitt->x25_fac_len += 3;
+       ccitt->x25_fac [i++] = 0x44;
+       ccitt->x25_fac [i++] = hp->t_44 >> 8;
+       ccitt->x25_fac [i++] = hp->t_44 && 0xff;
+    }
+}
+
+
+int     set_x25_facilities(sd, coc, caption)
+int     sd, coc;
+char *caption;
+{
+    FACILITY_DB                facilities;
+    CCITT_FACILITY_DB  ccitt_facilities;
+
+    bzero ((char *) &facilities, sizeof (FACILITY_DB));
+    bzero ((char *) &ccitt_facilities, sizeof (CCITT_FACILITY_DB));
+
+    if (ioctl (sd, X25_RD_FACILITIES, (char *) &ccitt_facilities) == NOTOK) {
+       SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_FACILITIES"));
+       return NOTOK;
+    }
+    if (fac_ccitt2hp (&ccitt_facilities, &facilities) == NOTOK)
+       SLOG (x25_log, LLOG_EXCEPTIONS, "unkonwn parameter(s)", ("fac_ccitt2hp"));
+
+    if (coc == PROBE
+           || !(coc == CALLED
+                   || reverse_charge   || recvpktsize || sendpktsize
+                   || recvwndsize      || sendwndsize || recvthruput
+                   || sendthruput      || cug_req  /* || cug_index */
+                   || fast_select_type || rpoa_req /* || rpoa */)) {
+       if (facilities.t_42 [0])
+           recvpktsize = 1 << facilities.t_42 [0];
+       if (facilities.t_42 [1])
+           sendpktsize = 1 << facilities.t_42 [1];
+       return OK;
+    }
+
+    if (reverse_charge)
+       facilities.t_01 |= 0x01;
+    else
+       facilities.t_01 &= ~0x01;
+    
+    switch (recvpktsize) {
+       case 16:
+           facilities.t_42 [0] = 4;
+           break;
+       case 32:
+           facilities.t_42 [0] = 5;
+           break;
+       case 64:
+           facilities.t_42 [0] = 6;
+           break;
+       case 128:
+           facilities.t_42 [0] = 7;
+           break;
+       case 256:
+           facilities.t_42 [0] = 8;
+           break;
+       case 512:
+           facilities.t_42 [0] = 9;
+           break;
+       case 1024:
+           facilities.t_42 [0] = 10;
+    }
+    switch (sendpktsize) {
+       case 16:
+           facilities.t_42 [1] = 4;
+           break;
+       case 32:
+           facilities.t_42 [1] = 5;
+           break;
+       case 64:
+           facilities.t_42 [1] = 6;
+           break;
+       case 128:
+           facilities.t_42 [1] = 7;
+           break;
+       case 256:
+           facilities.t_42 [1] = 8;
+           break;
+       case 512:
+           facilities.t_42 [1] = 9;
+           break;
+       case 1024:
+           facilities.t_42 [1] = 10;
+    }
+
+    if (recvwndsize)
+       facilities.t_43 [0] = recvwndsize;
+    if (sendwndsize)
+       facilities.t_43 [1] = sendwndsize;
+
+    if (sendthruput)
+       facilities.t_02 = (facilities.t_02 & 0xf0) | (sendthruput & 0x0f);
+    if (recvthruput)
+       facilities.t_02 = (facilities.t_02 & 0x0f) | (recvthruput << 4);
+
+    if (cug_req) {
+       facilities.t_03_sel = 1;
+       facilities.t_03 = cug_index;
+    }
+
+    switch (fast_select_type) {
+       case 0:
+           facilities.t_01 &= ~CCITT_FAST_SELECT;
+           if (coc == CALLED)
+               facilities.t_01 |= CCITT_FAST_ACPT_CLR;
+           break;
+       case 1:
+           facilities.t_01 &= ~CCITT_FAST_SELECT;
+           facilities.t_01 |= CCITT_FAST_CLR_ONLY;
+           break;
+       case 2:
+           facilities.t_01 &= ~CCITT_FAST_SELECT;
+           facilities.t_01 |= CCITT_FAST_ACPT_CLR;
+           break;
+       default:
+           SLOG (x25_log, LLOG_EXCEPTIONS, "illegal value",
+               ("fast_select_type"));
+    }
+
+    /* rpoa not supported - is this parameter t_41 in ccitt-description ??? */
+
+    fac_hp2ccitt (&facilities, &ccitt_facilities);
+    if (ioctl (sd, X25_WR_FACILITIES, (char *) &ccitt_facilities) == NOTOK) {
+       SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_WR_FACILITIES"));
+       return NOTOK;
+    }
+
+#ifdef  DEBUG
+    if (x25_log -> ll_events & LLOG_DEBUG)
+       print_x25_facilities (facilities, coc, caption);
+#endif
+
+    if (facilities.t_42 [0])
+       recvpktsize = 1 << facilities.t_42 [0];
+    if (facilities.t_42 [1])
+       sendpktsize = 1 << facilities.t_42 [1];
+
+    return OK;
+}
+
+/* \f */
+
+int     log_cause_and_diag(fd)
+int fd;
+{
+    char buf [MAX_EVENT_SIZE];
+    int        buflen;
+    char flags = 0;
+
+    for (;;) {
+       if ((buflen = recv (fd, buf, MAX_EVENT_SIZE, MSG_OOB)) == NOTOK) {
+           if (x25_log -> ll_events & LLOG_NOTICE)
+               SLOG (x25_log, LLOG_NOTICE,
+                   "failed", ("recv %d (MSG_OOB)", fd));
+           clear_sigurg (fd);
+           return OK;
+       }
+       else if (!buflen)
+           return OK;
+       switch (buf [1]) {
+           case OOB_INTERRUPT:
+               SLOG (x25_log, LLOG_NOTICE, NULLCP, ("OOB_INTERRUPT"));
+               break;
+           case OOB_VC_RESET:
+               SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP, ("OOB_VC_RESET"));
+               flags = (1 << RECV_DIAG);
+               close_x25_socket (fd);
+               break;
+           case OOB_VC_CLEAR:
+               SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP, ("OOB_VC_CLEAR"));
+               flags = (1 << RECV_DIAG) | (1 << DIAG_TYPE);
+               close_x25_socket (fd);
+               break;
+           case OOB_VC_RESET_CONF:
+               SLOG (x25_log, LLOG_NOTICE, NULLCP, ("OOB_VC_RESET_CONF"));
+               break;
+           case OOB_VC_INTERRUPT_CONF:
+               SLOG (x25_log, LLOG_NOTICE, NULLCP, ("OOB_VC_INTERRUPT_CONF"));
+               break;
+           case OOB_VC_DBIT_CONF:
+               SLOG (x25_log, LLOG_NOTICE, NULLCP, ("OOB_VC_DBIT_CONF"));
+               break;
+           case OOB_VC_MSG_TOO_BIG:
+               SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP, ("OOB_VC_MSG_TOO_BIG"));
+               close_x25_socket (fd);
+               break;
+           case OOB_VC_L2DOWN:
+               SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP, ("OOB_VC_L2DOWN"));
+               close_x25_socket (fd);
+               break;
+       }
+       (void) elucidate_x25_err (flags, &buf [2]);
+    }
+}
+
+
+void sigurg (sig, code, scp)
+int  sig, code;
+struct sigcontext *scp;
+{
+    struct fdl_st *fdlp = fdl, *nfdlp;
+
+    (void) signal (SIGURG, sigurg);
+    while (fdlp != NULL) {
+       log_cause_and_diag (fdlp->fd);
+       fdlp = fdlp->next;
+    }
+    if (scp == NULL) {
+       SLOG (x25_log, LLOG_NOTICE, NULLCP, ("No signal context"));
+       return;
+    };
+    if (scp->sc_syscall != SYS_NOTSYSCALL)
+       scp->sc_syscall_action = SIG_RESTART;
+}
+
+void setup_sigurg (fd)
+int fd;
+{
+    struct fdl_st *fdlp = fdl;
+
+    (void) signal (SIGURG, sigurg);
+    while (fdlp != NULL)
+       if (fdlp->fd == fd)
+           return;
+       else
+           fdlp = fdlp->next;
+    if ((fdlp = malloc (sizeof (struct fdl_st))) == NULL) {
+       SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("malloc (sigurg-struct)"));
+       return;
+    }
+    fdlp->fd = fd;
+    fdlp->next = fdl;
+    fdl = fdlp;
+}
+
+void clear_sigurg (fd)
+int fd;
+{
+    struct fdl_st *fdlp = fdl, *nfdlp;
+
+    if ((fdl != NULL) && (fdl->fd == fd)) {
+       fdl = fdl->next;
+       if (free (fdlp) == NOTOK)
+           SLOG (x25_log, LLOG_EXCEPTIONS, "failed",
+               ("free (sigurg-struct)"));
+       return;
+    }
+    else while (fdlp != NULL)
+       if ((fdlp->next != NULL) && (fdlp->next->fd == fd)) {
+           nfdlp = fdlp->next;
+           fdlp->next = fdlp->next->next;
+           if (free (nfdlp) == NOTOK)
+               SLOG (x25_log, LLOG_EXCEPTIONS, "failed",
+                   ("free (sigurg-struct)"));
+       }
+       else
+           fdlp = fdlp->next;
+}
+
+int close_x25_socket (fd)
+int fd;
+{
+    clear_sigurg (fd);
+    return (close (fd));
+};
+
+
+/* \f */
+
+#ifdef  DEBUG
+
+static int  log_x25_facilities (fd, coc, caption)
+int     fd;
+int     coc;
+char   *caption;
+{
+    FACILITY_DB        hp;
+    CCITT_FACILITY_DB  ccitt;
+
+    if (ioctl (fd, X25_RD_FACILITIES, (char *) &ccitt) == NOTOK) {
+       SLOG (x25_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_FACILITIES"));
+       return NOTOK;
+    }
+
+    fac_ccitt2hp (&ccitt, &hp);
+    print_x25_facilities (&hp, coc, caption);
+
+    return OK;
+}
+
+/* \f */
+
+static void  print_x25_facilities (hp, coc, caption)
+FACILITY_DB *hp;
+int     coc;
+char   *caption;
+{
+    int     i, baud;
+
+    DLOG (x25_log, LLOG_DEBUG, ("%s X.25 Facilities:", caption));
+
+    /* reverse charge */
+    switch (hp->t_01 & REVCHARGE) {
+       case 0:
+           DLOG (x25_log, LLOG_DEBUG, ((coc == CALLED)
+                     ? "reverse charging not allowed"
+                     : "reverse charging not requested"));
+           break;
+
+       case 1:
+           DLOG (x25_log, LLOG_DEBUG, ((coc == CALLING)
+                     ? "reverse charging requested"
+                     : "reverse charging allowed"));
+           break;
+    }
+
+    /* ACK expected */
+    if (hp->t_07 & ACK_EXPECTED)
+       DLOG (x25_log, LLOG_DEBUG, ("ACK-packets expected"));
+    else
+       DLOG (x25_log, LLOG_DEBUG, ("no ACK-packets expected"));
+
+    /* NACK expected */
+    if (hp->t_07 & NACK_EXPECTED)
+       DLOG (x25_log, LLOG_DEBUG, ("NACK-packets expected"));
+    else
+       DLOG (x25_log, LLOG_DEBUG, ("no NACK-packets expected"));
+
+    /* recvpktsize */
+    switch (i = hp->t_42 [0] ? (1 << hp->t_42 [0]) : 0) {
+       case 0:
+           DLOG (x25_log, LLOG_DEBUG, ("default recv packet size"));
+           break;
+
+       case 16:
+       case 32:
+       case 64:
+       case 128:
+       case 256:
+       case 512:
+       case 1024:
+           DLOG (x25_log, LLOG_DEBUG, ("recv packet size %d", i));
+           break;
+
+       default:
+           DLOG (x25_log, LLOG_DEBUG, ("invalid recv packet size %d", i));
+           break;
+    }
+
+    /* sendpktsize */
+    switch (i = hp->t_42 [1] ? (1 << hp->t_42 [1]) : 0) {
+       case 0:
+           DLOG (x25_log, LLOG_DEBUG, ("default send packet size"));
+           break;
+
+       case 16:
+       case 32:
+       case 64:
+       case 128:
+       case 256:
+       case 512:
+       case 1024:
+           DLOG (x25_log, LLOG_DEBUG, ("send packet size %d", i));
+           break;
+
+       default:
+           DLOG (x25_log, LLOG_DEBUG, ("invalid send packet size %d", i));
+           break;
+    }
+
+    DLOG (x25_log, LLOG_DEBUG,
+         (hp->t_43 [0] == 0 ? "default recv window size"
+                 : 1 <= hp->t_43 [0] && hp->t_43 [0] <= 127
+                     ? "recv window size %d"
+                     : "invalid recv window size %d",
+             hp->t_43 [0]));
+
+    DLOG (x25_log, LLOG_DEBUG,
+         (hp->t_43 [1] == 0 ? "default send window size"
+                 : 1 <= hp->t_43 [1] && hp->t_43 [1] <= 127
+                     ? "send window size %d"
+                     : "invalid send window size %d",
+             hp->t_43 [1]));
+
+    /* recvthruput */
+    switch (hp->t_02 >> 4) {
+       case 0:
+           DLOG (x25_log, LLOG_DEBUG, ("default recv throughput"));
+           break;
+
+       case 3:
+           baud = 75;
+print_recv: ;
+           DLOG (x25_log, LLOG_DEBUG, ("recv throughput %dbps", baud));
+           break;
+
+       case 4:
+           baud = 150;
+           goto print_recv;
+
+       case 5:
+           baud = 300;
+           goto print_recv;
+
+       case 6:
+           baud = 600;
+           goto print_recv;
+
+       case 7:
+           baud = 1200;
+           goto print_recv;
+
+       case 8:
+           baud = 2400;
+           goto print_recv;
+
+       case 9:
+           baud = 4800;
+           goto print_recv;
+
+       case 10:
+           baud = 9600;
+           goto print_recv;
+
+       case 11:
+           baud = 19200;
+           goto print_recv;
+
+       case 12:
+           baud = 48000;
+           goto print_recv;
+
+       default:
+           DLOG (x25_log, LLOG_DEBUG, ("invalid recv throughput %d",
+                     hp->t_02 >> 4));
+           break;
+    }
+
+    /* sendthruput */
+    switch (hp->t_02 & 0x0f) {
+       case 0:
+           DLOG (x25_log, LLOG_DEBUG, ("default send throughput"));
+           break;
+
+       case 3:
+           baud = 75;
+print_send: ;
+           DLOG (x25_log, LLOG_DEBUG, ("send throughput %dbps", baud));
+           break;
+
+       case 4:
+           baud = 150;
+           goto print_send;
+
+       case 5:
+           baud = 300;
+           goto print_send;
+
+       case 6:
+           baud = 600;
+           goto print_send;
+
+       case 7:
+           baud = 1200;
+           goto print_send;
+
+       case 8:
+           baud = 2400;
+           goto print_send;
+
+       case 9:
+           baud = 4800;
+           goto print_send;
+
+       case 10:
+           baud = 9600;
+           goto print_send;
+
+       case 11:
+           baud = 19200;
+           goto print_send;
+
+       case 12:
+           baud = 48000;
+           goto print_send;
+
+       default:
+           DLOG (x25_log, LLOG_DEBUG, ("invalid send throughput %d",
+                     hp->t_02 & 0x0f));
+           break;
+    }
+
+    if (hp->t_03_sel)
+       DLOG (x25_log, LLOG_DEBUG, ("closed user group 0x%x (BCD)",
+               hp->t_03));
+    else
+       DLOG (x25_log, LLOG_DEBUG, ("no closed user group"));
+
+    if (hp->t_41_sel)
+       DLOG (x25_log, LLOG_DEBUG, ("bilateral closed user group 0x%x (BCD)",
+               hp->t_41 [0] << 8 + hp->t_41 [1]));
+    else
+       DLOG (x25_log, LLOG_DEBUG, ("no bilateral closed user group"));
+
+    switch (hp->t_01 & CCITT_FAST_SELECT) {
+       case CCITT_FAST_OFF:
+           DLOG (x25_log, LLOG_DEBUG, ("don't use fast select"));
+           break;
+
+       case CCITT_FAST_CLR_ONLY:
+           DLOG (x25_log, LLOG_DEBUG, ("clear is fast select response"));
+           break;
+
+       case CCITT_FAST_ACPT_CLR:
+           DLOG (x25_log, LLOG_DEBUG,
+                 ("clear or call accepted is fast select response"));
+           break;
+
+       default:
+           DLOG (x25_log, LLOG_DEBUG, ("invalid fast select type %d",
+               hp->t_01 & CCITT_FAST_SELECT));
+           break;
+    }
+
+/*
+ * Don't know the meaning of this parameter (is t_44 ?)
+ *
+    switch (f.rpoa_req) {
+       case 0:
+           DLOG (x25_log, LLOG_DEBUG, ("no RPOA transit request"));
+           break;
+
+       case 1:
+           DLOG (x25_log, LLOG_DEBUG, ("RPOA transit request 0x%x",
+                     f.rpoa_req));
+           break;
+
+       default:
+           DLOG (x25_log, LLOG_DEBUG, ("invalid RPOA transit request %d",
+                     f.rpoa_req));
+    }
+ *
+ *
+ */
+}
+#endif
+#else
+int _hpuxx25_stub2 (){;}
+#endif
+#else
+int _hpuxx25_stub (){;}
+#endif
diff --git a/src/isode/compat/implode.c b/src/isode/compat/implode.c
new file mode 100644 (file)
index 0000000..e396914
--- /dev/null
@@ -0,0 +1,80 @@
+/* implode.c - explode ascii into octets */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:20  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:48  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:50  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:55  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f   DATA */
+
+char   hex2nib[0x80] = {
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, NULL, 
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, NULL, 
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/* \f */
+
+int    implode (a, b, n)
+register u_char *a;
+register char  *b;
+register int    n;
+{
+    register int    i;
+
+    for (i = 0; i < n; i += 2) {
+       *a++ = (hex2nib[b[0] & 0x7f] << 4) | (hex2nib[b[1] & 0x7f]);
+       b += 2;
+    }
+
+    return (n / 2);
+}
diff --git a/src/isode/compat/inst-man.sh b/src/isode/compat/inst-man.sh
new file mode 100644 (file)
index 0000000..50f4e33
--- /dev/null
@@ -0,0 +1,167 @@
+: run this script through /bin/sh
+
+# for a non standard base directory, set MANDIR
+
+# set MANOPTS in config/CONFIG.make -- may be one of:
+# -bsd42  man<n>/<file>
+# -bsd44  cat<n>/thing.0
+# -ros    man<n>/<file>                         -- using /etc/install
+# -sys5   <a|p|u>_man/man<n>/<file>
+# -aix    <a|p|u>_man/man<n>/<file>
+# -local  manl/<base>.l
+# -l      man<n>/<base>.<n>l
+# -hpux   hpux
+
+BINDIR="@(BINDIR)"
+ETCDIR="@(ETCDIR)"
+INCDIR="@(INCDIR)"
+LOGDIR="@(LOGDIR)"
+SBINDIR="@(SBINDIR)"
+MANDIR="@(MANDIR)"
+
+M=BSD42
+
+if test ! -d ${MANDIR}
+then
+    echo "inst-man: ${MANDIR} non-existant directory" 1>&2
+    exit 0
+fi
+
+for A in $*
+do
+    case $A in
+       -bsd42) M=BSD42
+               ;;
+
+       -bsd44) M=BSD44
+               ;;
+
+       -ros)   M=ROS
+               ;;
+
+       -local) M=LOCAL
+               ;;
+
+       -l)     M=L
+               ;;
+
+       -sys5)  M=SYS5
+               ;;
+
+       -aix)   M=AIX
+               ;;
+
+       -hpux)  M=HPUX
+               ;;
+
+       -*)     echo "inst-man: $A unknown" 1>&2
+               exit 1
+               ;;
+
+       *)      if test ! -f  $A
+               then
+                   exit 0
+               fi
+               F=`basename $A`
+               E=`echo $F | sed -e "s%^.*\.\([1-8]\).*%\1%"`
+
+               X=/tmp/$F
+               rm -f $X
+               echo '.ds BD @(BINDIR)'   > $X
+               echo '.ds ED @(ETCDIR)'  >> $X
+               echo '.ds ID @(INCDIR)'  >> $X
+               echo '.ds LD @(LOGDIR)'  >> $X
+               echo '.ds SD @(SBINDIR)' >> $X
+               cat $A >> $X
+
+               case $M in
+                   BSD42)
+                       echo install -m 0644 -c $X ${MANDIR}man$E/$F
+                       install -m 0644 -c $X ${MANDIR}man$E/$F
+                       ;;
+
+                   BSD44)
+                       echo "nroff -man $X > ${MANDIR}cat$E/$F" | \
+                       sed -e 's%\.\([1-8]\)[1-8cn]*$%.0%' | \
+                       sh -ve
+                       ;;
+
+                   LOCAL)
+                       (cd /tmp ; \
+                           echo $F | \
+                           sed -e "s%.*%install -m 0644 -c & ${MANDIR}manl/&%" | \
+                           sed -e 's%\.[1-8cn]*$%.l%' | \
+                           sh -ve)
+                       ;;
+
+                   L)
+                       (cd /tmp ; \
+                           echo "install -m 0644 -c $F ${MANDIR}man$E/$F" | \
+                           sed -e 's%\.\([1-8]\)[1-8cn]*$%.\1l%' | \
+                           sh -ve)
+                       ;;
+
+                   SYS5|AIX)
+                       case $E in
+                           3)      D=p_man     ;;
+                           5)      D=p_man E=4 ;;
+                           8)      D=a_man E=1 ;;
+                           *)      D=u_man     ;;
+                       esac
+                       echo /etc/install -m 0644 -f ${MANDIR}$D/man$E $X
+                       /etc/install -m 0644 -f ${MANDIR}$D/man$E $X
+                       case $D in
+                           a_man)
+                               F=`basename $A .8c`.1m
+                               echo mv ${MANDIR}$D/man$E/$A \
+                                    ${MANDIR}$D/man$E/$F
+                               mv ${MANDIR}$D/man$E/$A ${MANDIR}$D/man$E/$F
+                               ;;
+
+                           p_man)
+                               if [ "$E" = "4" ]; then
+                                   F=`basename $A .5`.4
+                                   echo mv ${MANDIR}$D/man$E/$A \
+                                        ${MANDIR}$D/man$E/$F
+                                   mv ${MANDIR}$D/man$E/$A \
+                                        ${MANDIR}$D/man$E/$F
+                               fi
+                               ;;
+                       esac
+                       ;;
+
+                   HPUX)
+                       case $E in
+                           5)  E=4 ;;
+                           8)  E=1m ;;
+                       esac
+                       echo /etc/install -m 0644 -f ${MANDIR}man$E $X
+                       /etc/install -m 0644 -f ${MANDIR}man$E $X
+                       case $E in
+                           4)  F=`basename $A .5`.4
+                               echo mv ${MANDIR}man$E/$A ${MANDIR}man$E/$F
+                               mv ${MANDIR}man$E/$A ${MANDIR}man$E/$F
+                               ;;
+
+                           1m) F=`basename $A .8c`.1m
+                               echo mv ${MANDIR}man$E/$A ${MANDIR}man$E/$F
+                               mv ${MANDIR}man$E/$A ${MANDIR}man$E/$F
+                               ;;
+                       esac
+                       ;;
+  
+                   ROS)
+                       echo /etc/install -m 0644 -c $X ${MANDIR}man$E/$F
+                       /etc/install -m 0644 -c $X ${MANDIR}man$E/$F
+                       ;;
+
+                   *)  echo "inst-man: mode botch" 1>&2
+                       exit 1
+                       ;;
+               esac
+               rm -f $X
+               ;;
+    esac
+done
+
+exit 0
diff --git a/src/isode/compat/internet.c b/src/isode/compat/internet.c
new file mode 100644 (file)
index 0000000..b6e0ea5
--- /dev/null
@@ -0,0 +1,700 @@
+/* internet.c - TCP/IP abstractions */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:24  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:52  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:53  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:56  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f */
+
+#ifdef TCP
+#include "internet.h"
+
+
+extern int  errno;
+
+/* \f   Berkeley UNIX: 4.2 */
+
+#ifdef SOCKETS
+
+/* For real networking, nothing is better than 4BSD! */
+
+
+int    start_tcp_client (sock, priv)
+struct sockaddr_in *sock;
+int    priv;
+{
+    register int    port;
+    int     eindex,
+           sd;
+#ifdef BSD43
+    int            onoff;
+#endif
+
+    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK;
+    }
+
+    if (sock == NULL)
+       goto got_socket;
+
+    for (port = IPPORT_RESERVED - priv;; priv ? port-- : port++) {
+       sock -> sin_port = htons ((u_short) port);
+
+       if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
+           break;
+
+       switch (errno) {
+           case EADDRINUSE: 
+               if (!priv || (port >= IPPORT_RESERVED / 2))
+                   continue;   /* else fall */
+
+           case EADDRNOTAVAIL: 
+           default:
+               eindex = errno;
+               SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+               (void) close_tcp_socket (sd);
+               errno = eindex;
+               return NOTOK;
+       }
+    }
+
+got_socket: ;
+#ifndef        BSD43
+    if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULLCP, 0) == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
+#else
+    onoff = 1;
+    if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &onoff,
+                      sizeof onoff) == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
+#endif
+
+    return sd;
+}
+
+/* \f */
+
+int    start_tcp_server (sock, backlog, opt1, opt2)
+struct sockaddr_in *sock;
+int    backlog,
+       opt1,
+       opt2;
+{
+    register int    port;
+    int     eindex,
+           sd;
+#ifdef BSD43
+    int            onoff;
+#endif
+
+    if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK;
+    }
+
+    if (sock -> sin_port != 0) {
+       if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
+           goto got_socket;
+
+       eindex = errno;
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+       (void) close_tcp_socket (sd);
+       errno = eindex;
+       return NOTOK;
+    }
+
+    for (port = IPPORT_RESERVED;; port++) {
+       sock -> sin_port = htons ((u_short) port);
+
+       if (bind (sd, (struct sockaddr *) sock, sizeof *sock) != NOTOK)
+           break;
+
+       switch (errno) {
+           case EADDRINUSE: 
+               continue;
+
+           case EADDRNOTAVAIL: 
+           default:
+               eindex = errno;
+               SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+               (void) close_tcp_socket (sd);
+               errno = eindex;
+               return NOTOK;
+       }
+    }
+
+got_socket: ;
+#ifndef        BSD43
+    if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, NULLCP, 0) == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
+    if (opt1 && setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0) == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+             ("set socket option 0x%x", opt1));
+    if (opt2 && setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0) == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+             ("set socket option 0x%x", opt2));
+#else
+    onoff = 1;
+    if (setsockopt (sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &onoff,
+                      sizeof onoff) == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("set SO_KEEPALIVE"));
+    if (opt1
+           && setsockopt (sd, SOL_SOCKET, opt1, (char *) &onoff, sizeof onoff)
+                   == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+             ("set socket option 0x%x", opt1));
+    if (opt2
+           && setsockopt (sd, SOL_SOCKET, opt2, (char *) &onoff, sizeof onoff)
+                   == NOTOK)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+             ("set socket option 0x%x", opt2));
+#endif
+
+    (void) listen (sd, backlog);
+
+    return sd;
+}
+
+/* \f */
+
+int    join_tcp_client (fd, sock)
+int    fd;
+struct sockaddr_in *sock;
+{
+    int     eindex,
+           len = sizeof *sock,
+           result;
+
+    if ((result = accept (fd, (struct sockaddr *) sock, &len)) == NOTOK) {
+       eindex = errno;
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("accept"));
+       errno = eindex;
+    }
+
+    return result;
+}
+
+/* \f */
+
+int    join_tcp_server (fd, sock)
+int    fd;
+struct sockaddr_in *sock;
+{
+    int     eindex,
+           result;
+
+    if ((result = connect (fd, (struct sockaddr *) sock, sizeof *sock))
+           == NOTOK) {
+       eindex = errno;
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("connect"));
+       errno = eindex;
+    }
+
+    return result;
+}
+
+/* \f */
+
+close_tcp_socket (fd)
+int    fd;
+{
+#ifdef never_do_this_if_from_join_tcp_client
+    (void) shutdown (fd, 2);
+#endif
+
+    return (close (fd));
+}
+
+#endif
+
+/* \f   AT&T UNIX: 5r3 using TLI */
+
+
+/* \f   AT&T UNIX: 5 with EXOS 8044 TCP/IP card */
+
+#ifdef EXOS
+
+/* If we had a getsockname() for the EXOS card, then we could postpone some
+   of the binding until connect time.  But since we don't, our hand is forced
+   and we must prematurely bind the sockets to IP addresses. */
+
+
+start_tcp_client (sock, priv)
+struct sockaddr_in *sock;
+int    priv;
+{
+    register int    port;
+    int     sd;
+    register struct hostent *hp;
+
+    if (sock == NULL)
+       return socket (SOCK_STREAM, 0, (struct sockaddr *) 0, SO_KEEPALIVE);
+
+    if (sock -> sin_addr.s_addr == 0) {
+       if ((hp = gethostbyname ("localhost")) == NULL) {
+           errno = EADDRNOTAVAIL;
+           return NOTOK;
+       }
+       sock -> sin_family = hp -> h_addrtype;
+       inaddr_copy (hp, sock);
+    }
+
+    for (port = IPPORT_RESERVED - priv;; priv ? port-- : port++) {
+       sock -> sin_port = htons ((u_short) port);
+
+       if ((sd = socket (SOCK_STREAM, 0, (struct sockaddr *) sock,
+                         SO_KEEPALIVE)) != NOTOK)
+           return sd;
+
+       switch (errno) {
+           case EADDRINUSE: 
+               if (!priv || (port >= IPPORT_RESERVED / 2))
+                   continue;   /* else fall */
+
+           case EADDRNOTAVAIL: 
+           default: 
+               return NOTOK;
+       }
+    }
+}
+
+/* \f */
+
+int    start_tcp_server (sock, backlog, opt1, opt2)
+struct sockaddr_in *sock;
+int    backlog,
+       opt1,
+       opt2;
+{
+    register int    port;
+    int     sd;
+    register struct hostent *hp;
+
+    if (backlog != 1)
+       return socket (SOCK_STREAM, 0, (struct sockaddr *) sock,
+                   SO_ACCEPTCONN | SO_KEEPALIVE | opt1 | opt2);
+
+    if (sock -> sin_addr.s_addr == 0) {
+       if ((hp = gethostbyname ("localhost")) == NULL) {
+           errno = EADDRNOTAVAIL;
+           return NOTOK;
+       }
+       sock -> sin_family = hp -> h_addrtype;
+       inaddr_copy (hp, sock);
+    }
+
+    for (port = IPPORT_RESERVED;; port++) {
+       sock -> sin_port = htons ((u_short) port);
+
+       if ((sd = socket (SOCK_STREAM, 0, (struct sockaddr *) sock,
+                   SO_ACCEPTCONN | SO_KEEPALIVE | opt1 | opt2)) != NOTOK)
+           return sd;
+
+       switch (errno) {
+           case EADDRINUSE: 
+               continue;
+
+           case EADDRNOTAVAIL: 
+           default: 
+               return NOTOK;
+       }
+    }
+}
+
+#endif
+
+/* \f   GETHOSTENT PLUS */
+
+static char *empty = NULL;
+#ifdef h_addr
+static char *addrs[2] = { NULL };
+#endif
+
+struct hostent *gethostbystring (s)
+char   *s;
+{
+    register struct hostent *h;
+#ifndef        DG
+    static u_long iaddr;
+#else
+    static struct in_addr iaddr;
+#endif
+    static struct hostent   hs;
+
+    iaddr = inet_addr (s);
+#ifndef        DG
+    if (iaddr == NOTOK)
+#else
+    if (iaddr.s_addr == NOTOK)
+#endif
+       return gethostbyname (s);
+
+    h = &hs;
+    h -> h_name = s;
+    h -> h_aliases = &empty;
+    h -> h_addrtype = AF_INET;
+    h -> h_length = sizeof (iaddr);
+#ifdef h_addr
+    h -> h_addr_list = addrs;
+    bzero ((char *) addrs, sizeof addrs);
+#endif
+    h -> h_addr = (char *) &iaddr;
+
+    return h;
+}
+
+/* \f   AT&T UNIX: 5 with EXOS 8044 TCP/IP card */
+
+#ifdef EXOS
+
+long   rhost ();
+char   *raddr ();
+
+
+struct hostent *gethostbyaddr (addr, len, type)
+char   *addr;
+int    len,
+       type;
+{
+    long    iaddr;
+    char   *name;
+    static char buffer[BUFSIZ];
+    static struct hostent   hs;
+    register struct hostent *h = &hs;
+
+    if (len != sizeof (long) || type != AF_INET)
+       return NULL;
+    bcopy (addr, (char *) &iaddr, len);
+    if ((name = raddr (iaddr)) == NULL)
+       return NULL;
+
+    (void) strcpy (buffer, name);
+    free (name);
+
+    h -> h_name = buffer;
+    h -> h_aliases = &empty;
+    h -> h_addrtype = type;
+    h -> h_length = len;
+    h -> h_addr = addr;
+
+    return h;
+}
+
+
+struct hostent *gethostbyname (name)
+char   *name;
+{
+    static long iaddr;
+    static char buffer[BUFSIZ];
+    static struct hostent   hs;
+    register struct hostent *h = &hs;
+
+    if ((iaddr = rhost (&name)) == NOTOK)
+       return NULL;
+
+    (void) strcpy (buffer, name);
+    free (name);
+
+    h -> h_name = buffer;
+    h -> h_aliases = &empty;
+    h -> h_addrtype = AF_INET;
+    h -> h_length = sizeof (iaddr);
+    h -> h_addr = (char *) &iaddr;
+
+    return h;
+
+}
+
+/* \f */
+
+/* really only need the "tsap" entry in this table... but why not? */
+
+static struct servent   services[] = {
+    "tsap", NULL, 102, "tcp",
+    "miscellany", NULL, 17000, "lpp",
+
+    "echo", NULL, 7, "tcp",            /* Network standard functions */
+    "echo", NULL, 7, "udp",
+    "sink", NULL, 9, "tcp",
+    "sink", NULL, 9, "udp",
+    "users", NULL, 11, "tcp",
+    "users", NULL, 11, "udp",
+    "daytime", NULL, 13, "tcp",
+    "daytime", NULL, 13, "udp",
+    "netstat", NULL, 15, "tcp",
+    "netstat", NULL, 15, "udp",
+    "qotd", NULL, 17, "tcp",
+    "qotd", NULL, 17, "udp",
+    "chargen", NULL, 19, "tcp",
+    "chargen", NULL, 19, "udp",
+    "ftp", NULL, 21, "tcp",
+    "telnet", NULL, 23, "tcp",
+    "smtp", NULL, 25, "tcp",
+    "imagen", NULL, 35, "udp",
+    "time", NULL, 37, "tcp",
+    "time", NULL, 37, "udp",
+    "name", NULL, 42, "tcp",
+    "name", NULL, 42, "udp",
+    "whois", NULL, 43, "tcp",
+    "whois", NULL, 43, "udp",
+    "nameserver", NULL, 53, "tcp",
+    "nameserver", NULL, 53, "udp",
+    "mtp", NULL, 57, "tcp",
+    "hostnames", NULL, 101, "tcp",
+    "pop", NULL, 109, "tcp",
+    "pwdgen", NULL, 129, "tcp",
+    "pwdgen", NULL, 129, "udp",
+    "x25bridge", NULL, 146, "tcp",
+    "iso-ip", NULL, 147, "udp",
+
+    "tftp", NULL, 69, "udp",           /* Host specific functions */
+    "rje", NULL, 77, "tcp",
+    "nmui", NULL, 77, "udp",
+    "finger", NULL, 79, "tcp",
+    "finger", NULL, 79, "udp",
+    "link", NULL, 87, "tcp",
+    "supdup", NULL, 95, "tcp",
+    "path", NULL, 117, "tcp",
+
+    "exec", NULL, 512, "tcp",          /* UNIX TCP sockets */
+    "login", NULL, 513, "tcp",
+    "shell", NULL, 514, "tcp",
+    "printer", NULL, 515, "tcp",
+    "rfile", NULL, 522, "tcp",
+    "ingreslock", NULL, 1524, "tcp",
+
+    "biff", NULL, 512, "udp",          /* UNIX UDP sockets */
+    "who", NULL, 513, "udp",
+    "syslog", NULL, 514, "udp",
+    "talk", NULL, 517, "udp",
+    "routed", NULL, 520, "udp",
+    "router_1", NULL, 521, "udp",
+
+    NULL, &empty, 0, NULL
+};
+
+
+
+struct servent *getservbyname (name, proto)
+register char   *name,
+               *proto;
+{
+    register struct servent *s;
+
+    for (s = services; s -> s_name; s++)
+       if (strcmp (name, s -> s_name) == 0
+               && strcmp (proto, s -> s_proto) == 0) {
+           if (s -> s_aliases == NULL) {
+               s -> s_aliases = &empty;
+               s -> s_port = htons ((u_short) s -> s_port);
+           }
+
+           return s;
+       }
+
+    return NULL;
+}
+
+/* \f */
+
+#define        s2a(b)  (((int) (b)) & 0xff)
+
+char   *inet_ntoa (in)
+struct in_addr in;
+{
+    register char  *s = (char *) &in;
+    static char addr[4 * 3 + 3 + 1];
+
+    (void) sprintf (addr, "%d.%d.%d.%d",
+           s2a (s[0]), s2a (s[1]), s2a (s[2]), s2a (s[3]));
+
+    return addr;
+}
+
+
+u_long inet_addr (cp)
+char   *cp;
+{
+    register int    base;
+    register char   c;
+    register u_long val;
+    u_long     parts[4];
+    register u_long *pp = parts;
+
+    for (;;) {
+       val = 0, base = 10;
+       if (*cp == '0')
+           base = 8, cp++;
+       if (*cp == 'x' || *cp == 'X')
+           base = 16, cp++;
+
+       for (; isxdigit ((u_char) (c = *cp)); cp++)
+           if (base == 16)
+               val = (val << 4) + (c + 10 - (islower ((u_char) c) ? 'a' : 'A'));
+           else
+               if (isdigit ((u_char) c))
+                   val = (val * base) + (c - '0');
+               else
+                   break;
+
+       switch (*cp) {
+           case '.': 
+               if (pp >= parts + 4)
+                   return NOTOK;
+               *pp++ = val, cp++;
+               continue;
+
+           default: 
+               if (*cp && !isspace ((u_char) *cp))
+                   return NOTOK;
+               *pp++ = val;
+               break;
+       }
+
+       break;
+    }
+
+    switch (pp - parts) {
+       case 1:
+           val = parts[0];
+           break;
+
+       case 2:
+           val = ((parts[0] & 0xff) << 24)
+                       | (parts[1] & 0xffffff);
+           break;
+
+       case 3:
+           val = ((parts[0] & 0xff) << 24)
+                       | ((parts[1] & 0xff) << 16)
+                       | (parts[2] & 0xffff);
+           break;
+
+       case 4:
+           val = ((parts[0] & 0xff) << 24)
+                       | ((parts[1] & 0xff) << 16)
+                       | ((parts[2] & 0xff) << 8)
+                       | (parts[3] & 0xff);
+           break;
+
+       default:
+           return NOTOK;
+    }
+
+    return htonl (val);
+}
+
+u_long inet_network (cp)
+char   *cp;
+{
+    register int    base;
+    register char   c;
+    register u_long val;
+    u_long     parts[4];
+    register u_long *pp = parts;
+
+    for (;;) {
+       val = 0, base = 10;
+       if (*cp == '0')
+           base = 8, cp++;
+       if (*cp == 'x' || *cp == 'X')
+           base = 16, cp++;
+
+       for (; isxdigit ((u_char) (c = *cp)); cp++)
+           if (base == 16)
+               val = (val << 4) + (c + 10 - (islower ((u_char) c) ? 'a' : 'A'));
+           else
+               if (isdigit ((u_char) c))
+                   val = (val * base) + (c - '0');
+               else
+                   break;
+
+       switch (*cp) {
+           case '.': 
+               if (pp >= parts + 4)
+                   return NOTOK;
+               *pp++ = val, cp++;
+               continue;
+
+           default: 
+               if (*cp && !isspace ((u_char) *cp))
+                   return NOTOK;
+               *pp++ = val;
+               break;
+       }
+
+       break;
+    }
+
+    switch (pp - parts) {
+       case 1:
+           val = (parts[0] & 0xff) << 24;
+           break;
+
+       case 2:
+           val = ((parts[0] & 0xff) << 24)
+                       | ((parts[1] & 0xff) << 16);
+           break;
+
+       case 3:
+           val = ((parts[0] & 0xff) << 24)
+                       | ((parts[1] & 0xff) << 16)
+                       | ((parts[2] & 0xff) << 8)
+           break;
+
+       case 4:
+           val = ((parts[0] & 0xff) << 24)
+                       | ((parts[1] & 0xff) << 16)
+                       | ((parts[2] & 0xff) << 8)
+                       | (parts[3] & 0xff);
+           break;
+
+       default:
+           return NOTOK;
+    }
+
+    return htonl (val);
+}
+#endif
+#endif
diff --git a/src/isode/compat/isoaddrs.c b/src/isode/compat/isoaddrs.c
new file mode 100644 (file)
index 0000000..c1a0d5a
--- /dev/null
@@ -0,0 +1,1234 @@
+/* isoaddrs.c - simple parsing of ISODE addresses */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:54  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.2  1994/06/06 19:51:28  eichin
+ * NULL is not a char
+ *
+ * Revision 1.1  1994/05/31 20:33:55  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:57  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+#include "internet.h"
+#include "tailor.h"
+
+/* \f   DATA */
+
+static int  read_macros ();
+static int  read_file ();
+static int  add_macro ();
+static char *isomacros = "isomacros";
+
+#define        MBUCKETS        128
+#define        MHASH(nm) \
+    (((nm)[1]) ? (((chrcnv[((nm)[0])] - chrcnv[((nm)[1])]) & 0x1f) \
+                       + ((chrcnv[(nm)[2]]) & 0x5f)) \
+              : (chrcnv[(nm)[0]]) & 0x7f)
+
+struct macro {
+    char   *m_name;
+    char   *m_value;
+
+    struct macro *m_chain;
+};
+
+static int inited = 0;
+static struct macro *Mbuckets[MBUCKETS];
+
+/* \f   MACROS */
+
+static struct macro *name2macro (name)
+char   *name;
+{
+    register struct macro *m;
+
+    read_macros ();
+
+    for (m = Mbuckets[MHASH (name)];
+            m && lexequ (m -> m_name, name);
+            m = m -> m_chain)
+       continue;
+
+    if (m)
+       LLOG (addr_log, LLOG_DEBUG,
+             ("MACRO \"%s\" VALUE \"%s\"", m -> m_name, m -> m_value));
+    else
+       LLOG (addr_log, LLOG_DEBUG,
+             ("lookup of MACRO \"%s\" failed", name));
+
+    return m;
+}
+
+/* \f */
+
+static struct macro *value2macro (value)
+char   *value;
+{
+    register int   i,
+                  j,
+                  k;
+    register struct macro *m,
+                         *p,
+                        **np,
+                        **pp;
+
+    read_macros ();
+
+    p = NULL, i = 0;
+    k = strlen (value);
+    for (pp = (np = Mbuckets) + MBUCKETS; np < pp; np++)
+       for (m = *np; m; m = m -> m_chain)
+           if ((j = strlen (m -> m_value)) <= k
+                   &&  j > i
+                   && strncmp (value, m -> m_value, j) == 0)
+               p = m, i = j;
+
+    if (p)
+       LLOG (addr_log, LLOG_DEBUG,
+             ("MACRO \"%s\" VALUE \"%s\" differential %d",
+              p -> m_name, p -> m_value, k - strlen (p -> m_value)));
+    else
+       LLOG (addr_log, LLOG_DEBUG,
+             ("lookup of VALUE \"%s\" failed", value));
+
+    return p;
+}
+
+/* \f */
+
+static int  read_macros ()
+{
+    register char *hp;
+    char    buffer[BUFSIZ];
+
+    if (inited)
+       return;
+    inited = 1;
+
+    bzero ((char *) Mbuckets, sizeof Mbuckets);
+
+    read_file (isodefile (isomacros, 0));
+
+    if ((hp = getenv ("HOME")) == NULL)
+       hp = ".";
+    (void) sprintf (buffer, "%s/.isode_macros", hp);
+    read_file (buffer);
+}
+
+/* \f */
+
+static int  read_file (file)
+char   *file;
+{
+    register char *cp;
+    char    buffer[BUFSIZ + 1],
+          *vec[NVEC + NSLACK + 1];
+    register FILE *fp;
+
+    if ((fp = fopen (file, "r")) == NULL)
+       return;
+
+    while (fgets (buffer, sizeof buffer, fp)) {
+       if (*buffer == '#')
+           continue;
+       if (cp = index (buffer, '\n'))
+           *cp  = NULL;
+       if (str2vec (buffer, vec) < 2)
+           continue;
+
+       if (add_macro (vec[0], vec[1]) == NOTOK)
+           break;
+    }
+
+    (void) fclose (fp);
+}
+
+/* \f */
+
+static int  add_macro (name, value)
+char   *name,
+       *value;
+{
+    int            i;
+    register char  *cp;
+    char    buffer[BUFSIZ];
+    register struct macro *m,
+                         *p;
+
+    if (cp = index (value, '=')) {
+       *cp++ = NULL;
+       if ((p = name2macro (value)) == NULL) {
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("macro \"%s\" references non-existant macro \"%s\"",
+                  name, value));
+           return OK;
+       }
+
+       (void) sprintf (value = buffer, "%s%s", p -> m_value, cp);
+    }
+
+    if ((m = (struct macro *) calloc (1, sizeof *m)) == NULL) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("calloc of macro structure failed"));
+       return NOTOK;
+    }
+    if ((m -> m_name = malloc ((unsigned) (strlen (name) + 1))) == NULL
+               || (m -> m_value = malloc ((unsigned) (strlen (value) + 1)))
+           == NULL) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("malloc of alias structure failed"));
+       if (m -> m_name)
+           free (m -> m_name);
+       free ((char *) m);
+       return NOTOK;
+    }
+    (void) strcpy (m -> m_name, name);
+    (void) strcpy (m -> m_value, value);
+
+    m -> m_chain = Mbuckets[i = MHASH (m -> m_name)];
+    Mbuckets[i] = m;
+
+    return OK;
+}
+
+/* \f */
+
+char   *macro2str (name)
+char   *name;
+{
+    register struct macro *m = name2macro (name);
+
+    return (m ? m -> m_value : NULLCP);
+}
+
+/* \f   STR2PADDR */
+
+#define        PS_INIT 0       /* <selector> or <network-address> */
+#define        PS_SEL1 1       /*   .. got one selector already */
+#define        PS_SEL2 2       /*   .. got two selectors already */
+#define        PS_SEL3 3       /* <network-address> */
+
+
+static struct afi_info {
+    char   *p_name;
+    char   *p_dec0, *p_hex0, *p_dec1, *p_hex1, *p_ia5;
+    int           p_idi_len, p_dec_dsp_len, p_hex_dsp_len;     
+}      afi_entries[] = {
+    "X121",  "36", "37", "52", "53", NULL, 14, 24,  9,
+    "DCC",   "38", "39", NULL, NULL, NULL,  3, 35, 14,
+    "TELEX", "40", "41", "54", "55", NULL,  8, 30, 12,
+    "PSTN",  "42", "43", "56", "57", NULL, 12, 26, 10,
+    "ISDN",  "44", "45", "58", "59", NULL, 15, 23,  9,
+    "ICD",   "46", "47", NULL, NULL, NULL,  4, 34, 13,
+    "LOCAL", "48", "49", NULL, NULL, "50",  0, 38, 19,
+
+    NULL
+};
+#define p_ia5_dsp_len(pp) \
+       (pp -> p_ia5 == NULL ? NOTOK : (pp -> p_dec_dsp_len >> 1))
+
+
+static char sel1[TSSIZE];
+static char sel2[TSSIZE];
+static char sel3[TSSIZE];
+static char *sels[3] = {
+    sel1, sel2, sel3
+};
+
+
+#define        IMPLODE(intres,octres,octval,intval,losing,loslab) \
+{ \
+    register int   z = (intval); \
+    register char *y = (octval); \
+    register char *zp = y + z; \
+ \
+    while (zp-- > y) \
+       if (!isxdigit ((u_char) *zp)) { \
+loslab: ; \
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP, \
+                 ("invalid hexstring: \"%*.*s\"", \
+                  z, z, y)); \
+           return (losing); \
+       } \
+    if (z % 2) \
+       goto loslab; \
+    (intres) = implode ((u_char *) (octres), y, z); \
+}
+
+/* \f */
+
+struct PSAPaddr *str2paddr (str)
+char   *str;
+{
+    register int    state,
+                  *lp;
+    int            j,
+           lens[3];
+    register char  *cp,
+                  *dp,
+                  *ep,
+                  *fp,
+                  *np,
+                 **sp;
+    char    buf1[BUFSIZ],
+           buf2[BUFSIZ],
+           nsap[NASIZE * 2 + 1];
+    register struct macro *m;
+    register struct afi_info *pp;
+    static int i = 0;
+    static struct PSAPaddr pas[2];
+    register struct PSAPaddr *pa = &pas[i++];
+    register struct SSAPaddr *sa = &pa -> pa_addr;
+    register struct TSAPaddr *ta = &sa -> sa_addr;
+    register struct NSAPaddr *na = ta -> ta_addrs;
+
+    LLOG (addr_log, LLOG_DEBUG, ("str2paddr: %s", str));
+    i = i % 2;
+
+    bzero ((char *) pa, sizeof *pa);
+    (void) strcpy (buf1, str);
+
+    state = PS_INIT;
+    sp = sels, lp = lens;
+
+    for (cp = buf1; *cp; )
+       switch (state) {
+           case PS_INIT:       
+           case PS_SEL1:
+           case PS_SEL2:
+               switch (*cp) {
+                   case '"':           /* '"' <otherstring> '"' */
+                       if ((cp = index (dp = cp + 1, '"')) == NULL) {
+                           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("missing double-quote in selector: %s",
+                                  str));
+                           return NULLPA;
+                       }
+                       *cp++ = NULL;
+                       (void) strcpy (*sp, dp);
+                       *lp = strlen (dp);
+                       break;
+
+                   case '#':           /* '#' <digitstring> */
+                       j = 0;
+                       for (cp++; isdigit ((u_char) *cp); cp++)
+                           j = j * 10 + *cp - '0';
+                       if (j > 0xffff) {
+                           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("invalid #-style selector: %s", str));
+                           return NULLPA;
+                       }
+                       (*sp)[0] = (j >> 8) & 0xff;
+                       (*sp)[1] = j & 0xff;
+                       *lp = 2;
+                       break;
+
+                   case '\'':          /* "'" <hexstring> "'H" */
+                       if ((cp = index (dp = cp + 1, '\'')) == NULL) {
+missing_quoteH: ;
+                           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("missing 'H in selector: %s",str));
+                           return NULLPA;
+                       }
+                       *cp++ = NULL;
+                       if (*cp++ != 'H')
+                           goto missing_quoteH;
+                       IMPLODE (*lp, *sp, dp, strlen (dp), NULLPA, L1);
+                       break;
+
+                   case '/':           /* empty selector */
+                       *lp = 0;
+                       break;
+
+                   default:
+                       goto stuff_selectors;
+               }
+               sp++, lp++;
+               if (*cp++ != '/') {
+                   SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("missing selector seperator at position %d: %s",
+                          cp - buf1, str));
+                   return NULLPA;
+               }
+               state++;
+               break;
+
+stuff_selectors: ;
+               state = PS_SEL3;
+               /* and fall */
+
+           case PS_SEL3:
+               if ((cp = index (ep = cp, '|')) == NULL)
+                   cp = ep + strlen (ep);
+               else
+                   *cp++ = NULL;
+
+               if (dp = index (ep, '=')) {
+                   *dp++ = NULL;
+                   if ((m = name2macro (ep)) == NULL) {
+                       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                             ("non-existant macro \"%s\"", ep));
+                       return NULLPA;
+                   }
+                   (void) sprintf (ep = buf2, "%s%s", m -> m_value, dp);
+               }
+
+               {
+                   register int    k,
+                                   l,
+                                   n;
+                   register struct ts_interim *ts,
+                                              *tp;
+
+                   tp = NULL, n = 0;
+                   k = strlen (ep);
+                   for (ts = ts_interim; ts -> ts_name; ts++)
+                       if (ts -> ts_value
+                               && (l = strlen (ts -> ts_value)) <= k
+                               && l > n
+                               && strncmp (ep, ts -> ts_value, l) == 0)
+                           tp = ts, n = l;
+                   if (tp)
+                       na -> na_community = tp -> ts_subnet;
+                   else {
+                       /* Assume all the AFI+IDI[+DSP] formats are 
+                        * SUBNET_REALNS until later. Note that the X121 format
+                        * without a DSP is converted to SUBNET_INT_X25 later.
+                        */
+                       for (pp = afi_entries; pp -> p_name; pp++)
+                           if (strncmp (pp -> p_name, ep, 
+                                        strlen (pp -> p_name) - 1) == 0 &&
+                               ep[strlen (pp -> p_name)] == '+')
+                               break;
+                       if (!pp -> p_name) {
+                           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("unable to determine community for %s",ep));
+                           return NULLPA;
+                       }
+                       na -> na_community = SUBNET_REALNS;
+                   }
+               }
+
+               if ((ep = index (dp = ep, '+')) == NULL) {
+missing_seperator: ;
+                   SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("missing network-address seperator: %s", str));
+                   return NULLPA;
+               }
+               *ep++ = NULL;
+               if (ta -> ta_naddr >= NTADDR) {
+#ifdef h_addr
+too_many: ;
+#endif
+                   SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("too many network addresses starting at position %d: %s",
+                          dp - buf1 + 1, str));
+                   return pa;
+               }
+
+               na -> na_stack = NA_NSAP;
+               LLOG (addr_log, LLOG_DEBUG,
+                   ("str2paddr: dp='%s', ep='%s'", dp, ep));
+
+               if (lexequ (dp, "NS") == 0) {
+                   IMPLODE (na -> na_addrlen, na -> na_address, ep,
+                            strlen (ep), NULLPA, L2);
+               }
+               else {
+                   int     len;
+                   char    padchar;
+
+                   for (pp = afi_entries; pp -> p_name; pp++)
+                       if (lexequ (pp -> p_name, dp) == 0)
+                           break;
+                   if (!pp -> p_name) {
+                       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                             ("unknown AFI \"%s\": %s", dp, str));
+                       return NULLPA;
+                   }
+                   if ((ep = index (dp = ep, '+')) == NULL)
+                       ep = dp + strlen (dp);
+                   else
+                       *ep++ = NULL;
+                   for (fp = dp; *fp; fp++)
+                           if (!isdigit ((u_char) *fp))
+                                   break;
+                   if (*fp) {
+                           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("invalid IDI \"%s\": %s", dp, cp));
+                           return NULLPA;
+                   }
+                   if (lexequ (pp -> p_name, "X121") == 0 &&
+                       *ep == NULL) {
+                       /* X121 form -- should be more general
+                        * Only applies if the DSP is NULL
+                        */
+                       (void) strcpy (nsap, dp);
+                       if ((na -> na_dtelen = strlen (nsap)) > NSAP_DTELEN) {
+                           dp = nsap;
+                           goto invalid_dte;
+                       }
+                       (void) strcpy (na -> na_dte, nsap);
+#ifdef BRIDGE_X25
+                       na -> na_stack = bridgediscrim (na) ? NA_BRG : NA_X25;
+#else
+                       na -> na_stack = NA_X25;
+#endif
+                       na -> na_community = SUBNET_INT_X25;
+                       goto next;
+                   }
+                   switch (*ep) {
+                       case 'd':
+                       case 0:
+                           if (*dp == '0' && pp -> p_dec1 != NULL)
+                               fp = pp -> p_dec1, padchar = '1';
+                           else
+                               fp = pp -> p_dec0, padchar = '0';
+                           (void) strcpy (nsap, fp);
+                           fp = nsap + strlen (nsap);
+                           for (len = pp -> p_idi_len - strlen (dp);
+                                    len > 0;
+                                    len--)
+                               *fp++ = padchar;
+                           (void) strcpy (fp, dp);
+                           fp += strlen (fp);
+                           if (*ep != NULL)
+                               (void) strcpy (fp, ep + 1);
+                           goto handle_dsp;    
+
+                       case 'x':
+                           if (*dp == '0' && pp -> p_hex1 != NULL)
+                               fp = pp -> p_hex1, padchar = '1';
+                           else
+                               fp = pp -> p_hex0, padchar = '0';
+                           (void) strcpy (nsap, fp);
+                           fp = nsap + strlen (nsap);
+                           for (len = pp -> p_idi_len - strlen (dp);
+                                    len > 0;
+                                    len--)
+                               *fp++ = padchar;
+                           (void) strcpy (fp, dp);
+                           /* Odd length IDI padded below */
+                           goto handle_dsp;
+
+                       case 'l':
+                           if (pp -> p_ia5 == NULL) {
+                               SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                     ("No IA5 syntax for AFI \"%s\"",
+                                      pp -> p_name));
+                                   return NULLPA;
+                           }
+                           (void) strcpy (nsap, pp -> p_ia5);
+                           goto handle_dsp;
+
+handle_dsp: ;
+                           np = nsap, dp = na -> na_address;
+                           while (*np) {
+                               *dp = (*np++ - '0') << 4;
+                               if (*np)
+                                   *dp++ |= (*np++ - '0') & 0x0f;
+                               else
+                                   *dp++ |= 0x0f;
+                           }
+                           na -> na_addrlen = dp - na -> na_address;
+                           if (*ep == 'x') {
+                               IMPLODE (j, dp, ep + 1, strlen (ep + 1),
+                                        NULLPA, L3);
+                               na -> na_addrlen += j;
+                           }
+                           else
+                               if (*ep == 'l') {
+                                   (void) strcpy (dp, ep + 1);
+                                   na -> na_addrlen += strlen (ep + 1);
+                               }
+                           break;
+
+                       default:
+                           if (*dp == '0' && pp -> p_dec1 != NULL)
+                               fp = pp -> p_dec1, padchar = '1';
+                           else
+                               fp = pp -> p_dec0, padchar = '0';
+                           (void) strcpy (nsap, fp);
+                           fp = nsap + strlen (nsap);
+                           for (len = pp -> p_idi_len - strlen (dp);
+                                    len > 0;
+                                    len--)
+                               *fp++ = padchar;
+                           (void) strcpy (fp, dp);
+                           if (strncmp ("RFC-1006+", ep,
+                                        sizeof "RFC-1006+" - 1) == 0) {
+#ifdef h_addr
+                               register char **ap;
+#endif
+                               register struct hostent *hp;
+
+                               na -> na_stack = NA_TCP;
+                               ep += sizeof "RFC-1006+" - 1;
+                               if ((ep = index (dp = ep, '+')) == NULL)
+                                   goto missing_seperator;
+                               *ep++ = NULL;
+                               if ((ep = index (dp = ep, '+')) == NULL)
+                                   ep = dp + strlen (dp);
+                               else
+                                   *ep++ = NULL;
+
+                               if ((hp = gethostbystring (dp)) == NULL) {
+                                   SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                         ("%s: unknown host", dp));
+                                   return NULLPA;
+                               }
+                               (void) strcpy (na -> na_domain,
+                                              inet_ntoa (*(struct in_addr *)
+                                                               hp -> h_addr));
+                               if (*ep) {
+                                   if ((ep = index (dp = ep, '+')) == NULL)
+                                       ep = dp + strlen (dp);
+                                   else
+                                       *ep++ = NULL;
+                                   na -> na_port = htons ((u_short) atoi(dp));
+
+                                   if (*ep)
+                                       na -> na_tset = atoi (ep);
+                               }
+#ifdef h_addr
+                               for (ap = hp -> h_addr_list + 1; *ap; ap++) {
+                                   ta -> ta_naddr++, na++;
+
+                                   if (ta -> ta_naddr >= NTADDR)
+                                       goto too_many;
+                                   bcopy ((char *) (na - 1), (char *) na,
+                                          sizeof *na);
+                                   (void) strcpy (na -> na_domain,
+                                         inet_ntoa (*(struct in_addr *) *ap));
+                               }
+#endif
+                               break;
+                           }
+                           if (strncmp ("X.25(80)+", ep,
+                                        sizeof "X.25(80)+" - 1) == 0) {
+                               na -> na_stack = NA_X25;
+                               ep += sizeof "X.25(80)+" - 1;
+                               if ((ep = index (dp = ep, '+')) == NULL)
+                                   goto missing_seperator;
+                               *ep++ = NULL;
+                               if ((ep = index (dp = ep, '+')) == NULL)
+                                   ep = dp + strlen (dp);
+                               else
+                                   *ep++ = NULL;
+                               for (np = dp; *np; np++)
+                                   if (!isdigit ((u_char) *np)) {
+invalid_dte: ;
+                                       SLOG (addr_log, LLOG_EXCEPTIONS,
+                                             NULLCP,
+                                             ("invalid DTE \"%s\": %s",
+                                              dp, str));
+                                       return NULLPA;
+                                   }
+                               if (np - dp > NSAP_DTELEN + 1)
+                                   goto invalid_dte;
+                               (void) strcpy (na -> na_dte, dp);
+                               na -> na_dtelen = strlen (na -> na_dte);
+                               if (*ep) {
+                                   char   *cudf,
+                                          *clen;
+
+                                   if ((ep = index (dp = ep, '+')) == NULL)
+                                       goto missing_seperator;
+                                   *ep++ = NULL;
+                                   
+                                   if (lexequ (dp, "CUDF") == 0) {
+                                       cudf = na -> na_cudf;
+                                       clen = &na -> na_cudflen;
+                                       j = sizeof na -> na_cudf;
+                                   }
+                                   else
+                                       if (lexequ (dp, "PID") == 0) {
+                                           cudf = na -> na_pid;
+                                           clen = &na -> na_pidlen;
+                                           j = sizeof na -> na_pid;
+                                       }
+                                       else {
+invalid_field: ;
+                                           SLOG (addr_log, LLOG_EXCEPTIONS,
+                                                 NULLCP,
+                                                 ("invalid field \"%s\": %s",
+                                                  dp, str));
+                                           return NULLPA;
+                                       }
+                                   if (j * 2 < ((int)strlen (ep)))
+                                       goto invalid_field;
+                                   IMPLODE (j, cudf, ep, strlen (ep),
+                                            NULLPA, L4);
+                                   *clen = j & 0xff;
+                               }
+#ifdef BRIDGE_X25
+                               na -> na_stack = bridgediscrim (na) ? NA_BRG
+                                                                  : NA_X25;
+#endif
+                               break;
+                           }
+#ifdef notdef
+                           if (lexequ ("ECMA-117-Binary", ep) == 0) {
+                               /* some day support this... */
+                               break;
+                           }
+                           if (lexequ ("ECMA-117-Decimal", ep) == 0) {
+                               /* some day support this... */
+                               break;
+                           }
+#endif
+                           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                                 ("unknown DSP \"%s\": %s", ep, str));
+                           return NULLPA;
+                   }
+               }
+next: ;
+               ta -> ta_naddr++, na++;
+               break;
+       }
+    
+    switch (sp - sels) {
+        case 3:        /* PSEL+SSEL+TSEL */
+           bcopy (*--sp, ta -> ta_selector,
+                  ta -> ta_selectlen = *--lp);
+           bcopy (*--sp, sa -> sa_selector,
+                  sa -> sa_selectlen = *--lp);
+           bcopy (*--sp, pa -> pa_selector,
+                  pa -> pa_selectlen = *--lp);
+           break;
+
+       case 2: /* SSEL+TSEL */
+           bcopy (*--sp, ta -> ta_selector,
+                  ta -> ta_selectlen = *--lp);
+           bcopy (*--sp, sa -> sa_selector,
+                  sa -> sa_selectlen = *--lp);
+           break;
+
+       case 1: /* TSEL */
+           bcopy (*--sp, ta -> ta_selector,
+                  ta -> ta_selectlen = *--lp);
+           break;
+
+       default:
+           break;
+    }
+    
+    return pa;
+}
+
+/* \f */
+
+int    macro2comm (name, ts)
+char   *name;
+register struct ts_interim *ts;
+{
+    int            j,
+           len;
+    register char  *ap,
+                  *cp,
+                  *dp,
+                  *ep,
+                  *fp,
+                  *np;
+    char    padchar,
+           addr[NASIZE * 2 + 1],
+           buffer[BUFSIZ];
+    register struct afi_info *pp;
+
+    ts -> ts_length = 0, ts -> ts_syntax = NA_NSAP;
+    if ((cp = macro2str (name)) == NULLCP)
+       return NOTOK;
+    ts -> ts_value = cp;
+    (void) strcpy (buffer, cp);
+    ap = addr;
+
+    if ((ep = index (dp = buffer, '+')) == NULL)
+       ep = dp + strlen (dp);
+    else
+       *ep++ = NULL;
+
+    if (lexequ (dp, "NS") == 0) {
+       IMPLODE (ts -> ts_length, ts -> ts_prefix, ep, strlen (ep),
+                NOTOK, L5);
+
+       return OK;
+    }
+    
+    for (pp = afi_entries; pp -> p_name; pp++)
+       if (lexequ (pp -> p_name, dp) == 0)
+           break;
+    if (!pp -> p_name) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("unknown AFI \"%s\": %s", dp, cp));
+       return NOTOK;
+    }
+
+    if (!ep) {
+           /* No IDI */
+           (void) strcpy (ap, pp -> p_dec0);
+           ap += strlen (ap);
+           goto out;
+    }
+
+    if ((ep = index (dp = ep, '+')) == NULL)
+       ep = dp + strlen (dp);
+    else
+       *ep++ = NULL;
+
+    for (fp = dp; *fp; fp++)
+       if (!isdigit ((u_char) *fp))
+           break;
+    if (*fp) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("invalid IDI \"%s\": %s", dp, cp));
+       return NOTOK;
+    }
+
+    if (lexequ (pp -> p_name, "X121") == 0 && *ep == NULL) {
+       /* Only used if there is no DSP */
+       (void) strcpy (ap, dp);
+       ap += strlen (ap);
+
+       ts -> ts_syntax = NA_X25;
+       ts -> ts_subnet = SUBNET_INT_X25;
+       goto out;
+    }
+
+    switch (*ep) {
+       case 'd':
+        case 0:
+           if (*dp == '0' && pp -> p_dec1 != NULL)
+               fp = pp -> p_dec1, padchar = '1';
+           else
+               fp = pp -> p_dec0, padchar = '0';
+           (void) strcpy (ap, fp);
+           ap += strlen (ap);
+           for (len = pp -> p_idi_len - strlen (dp); len > 0; len--)
+               *ap++ = padchar;
+           (void) strcpy (ap, dp);
+           ap += strlen (ap);
+           if (*ep != NULL)
+               (void) strcpy (ap, ep + 1);
+           break;
+
+       case 'x':
+           if (*dp == '0' && pp -> p_hex1 != NULL)
+               fp = pp -> p_hex1, padchar = '1';
+           else
+               fp = pp -> p_hex0, padchar = '0';
+           (void) strcpy (ap, fp);
+           ap += strlen (ap);
+           for (len = pp -> p_idi_len - strlen (dp); len > 0; len--)
+               *ap++ = padchar;
+           (void) strcpy (ap, dp);
+           /* Odd length IDI padded below */
+           break;
+
+       case 'l':
+           if (pp -> p_ia5 == NULL) {
+               SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("No IA5 syntax for AFI \"%s\": %s", pp -> p_name, cp));
+               return NOTOK;
+           }
+           (void) strcpy (ap, pp -> p_ia5);
+           break;
+
+       default:
+           if (*dp == '0' && pp -> p_dec1 != NULL)
+               fp = pp -> p_dec1, padchar = '1';
+           else
+               fp = pp -> p_dec0, padchar = '0';
+           (void) strcpy (ap, fp);
+           ap += strlen (ap);
+           for (len = pp -> p_idi_len - strlen (dp); len > 0; len--)
+               *ap++ = padchar;
+           (void) strcpy (ap, dp);
+           ap += strlen (ap);
+
+           if ((ep = index (dp = ep, '+')) == NULL)
+               ep = dp + strlen (dp);
+           else
+               *ep++ = NULL;
+           if (lexequ (dp, "RFC-1006") == 0)
+               ts -> ts_syntax = NA_TCP;
+           else
+               if (lexequ (dp, "X.25(80)") == 0)
+                   ts -> ts_syntax = NA_X25;
+               else {
+                   SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("unknown DSP \"%s\": %s", dp, cp));
+                   return NOTOK;
+               }
+           if ((ep = index (dp = ep, '+')) == NULL)
+               ep = dp + strlen (dp);
+           else
+               *ep++ = NULL;
+
+           (void) strcpy (ap, dp);
+
+           if (*ep) {
+               SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("invalid MACRO for community \"%s\": %s", name, cp));
+               return NOTOK;
+           }
+           break;
+    }
+
+out: ;
+    ap = addr, np = ts -> ts_prefix;
+    while (*ap) {
+       *np = (*ap++ - '0') << 4;
+       if (*ap)
+           *np++ |= (*ap++ - '0') & 0x0f;
+       else
+           *np++ |= 0x0f;
+    }
+    switch (*ep) {
+       case 'x':
+           IMPLODE (j, np, ep + 1, strlen (ep + 1), NOTOK, L6);
+           np += j;
+           break;
+
+       case 'l':
+           (void) strcpy (np, ep + 1);
+           np += strlen (ep + 1);
+           break;
+
+       default:
+           break;
+    }
+    ts -> ts_length = np - ts -> ts_prefix;
+
+    return OK;
+}
+
+/* \f   PADDR2STR */
+
+static char   *SEL2STR (sel, len)
+char   *sel;
+int    len;
+{
+    register char  *cp,
+                  *dp,
+                  *ep;
+    static char buffer[PSSIZE * 2 + 4];
+
+    if (len <= 0)
+       return "";
+
+    cp = buffer;
+    *cp++ = '"';
+    for (ep = (dp = sel) + len; dp < ep; dp++) {
+       switch (*dp) {
+           case '+':
+           case '-':
+           case '.':
+               break;
+
+           default:
+               if (!isalnum ((u_char) *dp)) {
+                   cp = buffer;
+                   *cp++ = '\'';
+                   cp += explode (cp, (u_char *) sel, len);
+                   (void) strcpy (cp, "'H");
+                   return buffer;
+               }               
+               break;
+       }
+
+       *cp++ = *dp;
+    }
+    *cp++ = '"';
+    *cp = NULL;
+
+    return buffer;
+}
+
+/* \f */
+
+char    *_paddr2str (pa, na, compact)
+register struct PSAPaddr *pa;
+register struct NSAPaddr *na;
+int    compact;
+{
+    register int   n;
+    int            first;
+    register char *bp,
+                 *cp,
+                 *dp;
+    register struct macro *m;
+    register struct SSAPaddr *sa;
+    register struct TSAPaddr *ta;
+    register struct NSAPaddr *ca;
+    static int    i = 0;
+    static char buf1[BUFSIZ],
+               buf2[BUFSIZ];
+    static char *bufs[] = { buf1, buf2 };
+
+    LLOG (addr_log, LLOG_DEBUG,
+       ("paddr2str: pa=%x, na=%x, compact=%d", pa, na, compact));
+
+    bp = cp = bufs[i++];
+    i = i % 2;
+
+    if (pa == NULLPA) {
+bad_pa: ;
+       (void) strcpy (bp, "NULLPA");
+       return bp;
+    }
+    sa = &pa -> pa_addr;
+    ta = &sa -> sa_addr;
+
+    if (na)
+       n = 1;
+    else
+       if ((n = ta -> ta_naddr) > 0)
+           na = ta -> ta_addrs;
+
+    if (pa -> pa_selectlen > 0) {
+       (void) sprintf (cp, "%s/",
+                       SEL2STR (pa -> pa_selector, pa -> pa_selectlen));
+       cp += strlen (cp);
+    }
+    if (sa -> sa_selectlen > 0 || bp != cp) {
+       (void) sprintf (cp, "%s/",
+                       SEL2STR (sa -> sa_selector, sa -> sa_selectlen));
+       cp += strlen (cp);
+    }
+    if (ta -> ta_selectlen > 0 || bp != cp) {
+       (void) sprintf (cp, "%s/",
+                       SEL2STR (ta -> ta_selector, ta -> ta_selectlen));
+       cp += strlen (cp);
+    }
+
+    /*
+    ** This may happen when a wildcard TSAP is bound over a
+    ** wildcard NSAP (i.e. the address of the endpoint onto which 
+    ** a connection is accepted via the TLI under some implementations)
+    **
+    ** Should we do this or return "/"?
+    */
+    if (n == 0 && bp == cp)
+       goto bad_pa;
+
+    for (first = 1; n > 0; na++, n--) {
+       register struct ts_interim *ts;
+
+       if (first)
+           first = 0;
+       else
+           *cp++ = '|';
+
+       if (compact > 0) {
+           if ((ca = na2norm (na)) == NULLNA)
+               goto bad_pa;
+
+           (void) strcpy (cp, "NS+");
+           cp += strlen (cp);
+
+           cp += explode (cp, (u_char *) ca -> na_address, ca -> na_addrlen);
+           *cp = NULL;
+           continue;
+       }
+       
+       for (ts = ts_interim; ts -> ts_name; ts++)
+           if (ts -> ts_subnet == na -> na_community)
+               break;
+       if (!ts -> ts_name) {
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("unable to find community #%d", na -> na_community));
+           goto bad_pa;
+       }
+       if (!ts -> ts_value) {
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("community \"%s\" (subnet #%d) has no corresponding MACRO",
+                  ts -> ts_name, na -> na_community));
+           goto bad_pa;
+       }
+       (void) strcpy (dp = cp, ts -> ts_value);
+       cp += strlen (cp) - 1;
+       if (*cp != '+')
+           *++cp = '+', *++cp = NULL;
+       else
+           cp++;
+
+       switch (na -> na_stack) {
+           struct afi_info *a;
+
+           case NA_NSAP:
+               (void) strcpy (cp = dp, "NS+");
+               cp += strlen (cp);
+
+               cp += explode (cp, (u_char *) na -> na_address, na -> na_addrlen);
+               *cp = NULL;
+
+               /* Use afi_info to pretty print as AFI+IDI+DSP */
+               for (cp = dp + 3, a = afi_entries; a->p_name; a++) {
+                   char pad, dspmark;
+                   char buf[BUFSIZ];
+                   char *dsp;
+       
+                   if (a->p_dec0 && bcmp(a->p_dec0, cp, 2) == 0)
+                       (pad = a->p_dec1 ? '0' : '\0'), dspmark = 'd';
+                   else if (a->p_dec1 && bcmp(a->p_dec1, cp, 2) == 0)
+                       pad = '1', dspmark = 'd';
+                   else if (a->p_hex0 && bcmp(a->p_hex0, cp, 2) == 0)
+                       (pad = a->p_hex1 ? '0' : '\0'), dspmark = 'x';
+                   else if (a->p_hex1 && bcmp(a->p_hex1, cp, 2) == 0)
+                       pad = '1', dspmark = 'x';
+                   else if (a->p_ia5 && bcmp(a->p_ia5, cp, 2) == 0)
+                       pad = '\0', dspmark = 'l';
+                   else
+                       continue;
+                   cp += 2;                            /* skip AFI */
+                   dsp = cp + a->p_idi_len;            /* find DSP */
+                   while (cp < dsp && *cp == pad)
+                       cp++;                   /* skip pad chars */
+                   (void) sprintf(buf, "%s+%.*s", a->p_name, dsp - cp, cp);
+
+                   /*
+                    * If we have an odd number of characters in IDI &
+                    * the next character is 'f' then it must be a pad
+                    * because a pad is only not inserted if the DSP is
+                    * decimal syntax in which case 'f' is illegal,
+                    * otherwise check for a trailing pad if decimal
+                    * syntax.
+                    */
+                   if ((dsp - (dp + 3)) % 2 && *dsp == 'f')
+                       dsp++;
+                   else if (dspmark == 'd' && *(cp = dsp + strlen(dsp) - 1) ==
+ 'f')
+                       *cp = '\0';
+                   if (*dsp)
+                       (void) sprintf(buf+strlen(buf), "+%c%s", dspmark, dsp);
+                   (void) strcpy(dp, buf);
+                   cp = dp + strlen(dp);
+                   break;
+               }
+               break;
+
+
+           case NA_TCP:
+               (void) strcpy (cp, na -> na_domain);
+               cp += strlen (cp);
+               if (na -> na_port) {
+                   (void) sprintf (cp, "+%d", (int) ntohs (na -> na_port));
+                   cp += strlen (cp);
+
+                   if (na -> na_tset) {
+                       (void) sprintf (cp, "+%d", (int) na -> na_tset);
+                       cp += strlen (cp);
+                   }
+               }
+               break;
+
+           case NA_X25:
+           case NA_BRG:
+               if (na -> na_community == SUBNET_INT_X25
+                       && na -> na_cudflen == 0
+                       && na -> na_pidlen == 0
+                       && na -> na_dte[0] != '0') {
+                   (void) sprintf (cp = dp, "X121+%s", na -> na_dte);
+                   cp += strlen (cp);
+               }
+               else {
+                   (void) strcpy (cp, na -> na_dte);
+                   cp += strlen (cp);
+                   if (na -> na_pidlen > 0) {
+                       (void) strcpy (cp, "+PID+");
+                       cp += strlen (cp);
+
+                       cp += explode (cp, (u_char *) na -> na_pid,
+                                      (int) na -> na_pidlen);
+                   }
+                   else
+                       if (na -> na_cudflen > 0) {
+                           (void) strcpy (cp, "+CUDF+");
+                           cp += strlen (cp);
+
+                           cp += explode (cp, (u_char *) na -> na_cudf,
+                                          (int) na -> na_cudflen);
+                       }
+                   *cp = NULL;
+               }
+               break;
+
+           default:
+               SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("unknown address type 0x%x", na -> na_stack));
+               goto bad_pa;
+       }
+
+       SLOG (addr_log, LLOG_DEBUG, NULLCP, ("dp = %s",dp));
+
+       if (!compact && (m = value2macro (dp))) {
+           char    buffer[BUFSIZ];
+
+           (void) sprintf (buffer, "%s=%s", m -> m_name,
+                           dp + strlen (m -> m_value));
+           (void) strcpy (dp, buffer);
+           cp = dp + strlen (dp);
+       }
+    }
+    *cp = NULL;
+
+    return bp;
+}
+
+/* \f */
+
+#ifdef PEP_TEST
+free_macros () {
+    register int    i;
+    register struct macro *m,
+                         *p;
+
+    for (i = MBUCKETS; i-- > 0; )
+       for (p = Mbuckets[i]; p; p = m) {
+           m = p -> m_chain;
+
+           if (p -> m_name)
+               free (p -> m_name);
+           if (p -> m_value)
+               free (p -> m_value);
+
+           free (p);
+       }
+}
+#endif
diff --git a/src/isode/compat/isofiles.c b/src/isode/compat/isofiles.c
new file mode 100644 (file)
index 0000000..393769c
--- /dev/null
@@ -0,0 +1,64 @@
+/* isofiles.c - ISODE files */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:28  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:56  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:57  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f */
+
+char   *_isodefile (path, file)
+char   *path,
+       *file;
+{
+    static char buffer[BUFSIZ];
+
+    isodetailor (NULLCP, 0);   /* not really recursive */
+
+    if (*file == '/'
+           || (*file == '.'
+                   && (file[1] == '/'
+                           || (file[1] == '.' && file[2] == '/'))))
+       (void) strcpy (buffer, file);
+    else
+       (void) sprintf (buffer, "%s%s", path, file);
+
+    return buffer;
+}
diff --git a/src/isode/compat/isohost.c b/src/isode/compat/isohost.c
new file mode 100644 (file)
index 0000000..2f6ddeb
--- /dev/null
@@ -0,0 +1,94 @@
+/* isohost.c - getlocalhost */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:30  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:15:58  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:33:58  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:17:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#ifdef TCP
+#include "internet.h"
+#endif
+#include "tailor.h"
+#ifdef SYS5
+#include <sys/utsname.h>
+#endif
+
+/* \f */
+
+char   *getlocalhost () {
+    register char   *cp;
+#ifdef TCP
+    register struct hostent *hp;
+#endif
+#ifdef SYS5
+    struct utsname uts;
+#endif
+    static char buffer[BUFSIZ];
+
+    if (buffer[0])
+       return buffer;
+
+    isodetailor (NULLCP, 0);
+    if (*isodename)
+       (void) strcpy (buffer, isodename);
+    else {
+#if    !defined(SOCKETS) && !defined(SYS5)
+       (void) strcpy (buffer, "localhost");
+#endif
+#ifdef SOCKETS
+       (void) gethostname (buffer, sizeof buffer);
+#endif
+#ifdef SYS5
+       (void) uname (&uts);
+       (void) strcpy (buffer, uts.nodename);
+#endif
+
+#ifdef TCP
+       if (hp = gethostbyname (buffer))
+           (void) strcpy (buffer, hp -> h_name);
+       else
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("%s: unknown host", buffer));
+#endif
+
+       if (cp = index (buffer, '.'))
+           *cp = NULL;
+    }
+
+    return buffer;
+}
diff --git a/src/isode/compat/isologs.sh b/src/isode/compat/isologs.sh
new file mode 100644 (file)
index 0000000..4cf9c6a
--- /dev/null
@@ -0,0 +1,36 @@
+: run this script through /bin/sh
+
+x=`fgrep logpath @(ETCDIR)isotailor 2>/dev/null | awk '{ print $2 }'`
+if [ "x$x" != x ]; then
+    cd $x
+else
+    cd @(LOGDIR)
+fi
+
+rm -f iso.*.log ros.*.log [0-9]*.log
+
+for A in [a-z]*.log
+do
+    x=2
+    while [ $x -gt 0 ];
+    do
+       y=`expr $x - 1`
+       mv $A-$y $A-$x >/dev/null 2>&1
+       x=$y
+    done
+
+    if [ ! -f $A ];
+    then
+       continue
+    fi
+
+    if [ -s $A ];
+    then
+       mv $A $A-0 >/dev/null 2>&1
+    fi
+
+    > $A
+    chmod 666 $A
+done
+
+exit 0
diff --git a/src/isode/compat/isoman.rf b/src/isode/compat/isoman.rf
new file mode 100644 (file)
index 0000000..1fc2193
--- /dev/null
@@ -0,0 +1,8 @@
+.\" isoman.rf - include file for ISODE manual entries
+.\" Sat Nov  4 23:15:36 1989  Marshall T. Rose <mrose@cheetah.ca.psi.com>
+
+.ds BD @(BINDIR)
+.ds ED @(ETCDIR)
+.ds ID @(INCDIR)
+.ds LD @(LOGDIR)
+.ds SD @(SBINDIR)
diff --git a/src/isode/compat/isoservent.c b/src/isode/compat/isoservent.c
new file mode 100644 (file)
index 0000000..ef2d190
--- /dev/null
@@ -0,0 +1,144 @@
+/* isoservent.c - look-up ISODE services */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:04  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:04  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:00  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+/* \f   DATA */
+
+static char *isoservices = "isoservices";
+
+static FILE *servf = NULL;
+static int  stayopen = 0;
+
+static struct isoservent    iss;
+
+/* \f */
+
+int    setisoservent (f)
+int    f;
+{
+    if (servf == NULL)
+       servf = fopen (isodefile (isoservices, 0), "r");
+    else
+       rewind (servf);
+    stayopen |= f;
+
+    return (servf != NULL);
+}
+
+
+int    endisoservent () {
+    if (servf && !stayopen) {
+       (void) fclose (servf);
+       servf = NULL;
+    }
+
+    return 1;
+}
+
+/* \f */
+
+struct isoservent  *getisoservent () {
+    int            mask,
+           vecp;
+    register char  *cp;
+    register struct isoservent *is = &iss;
+    static char buffer[BUFSIZ + 1],
+               file[BUFSIZ];
+    static char *vec[NVEC + NSLACK + 1];
+
+    if (servf == NULL
+           && (servf = fopen (isodefile (isoservices, 0), "r")) == NULL)
+       return NULL;
+
+    bzero ((char *) is, sizeof *is);
+
+    while (fgets (buffer, sizeof buffer, servf) != NULL) {
+       if (*buffer == '#')
+           continue;
+       if (cp = index (buffer, '\n'))
+           *cp = NULL;
+       if ((vecp = str2vecX (buffer, vec, 1 + 1, &mask, NULL, 1)) < 3)
+           continue;
+
+       if ((cp = index (vec[0], '/')) == NULL)
+           continue;
+       *cp++ = NULL;
+
+       is -> is_provider = vec[0];
+       is -> is_entity = cp;
+       is -> is_selectlen = str2sel (vec[1], (mask & (1 << 1)) ? 1 : 0,
+                               is -> is_selector, ISSIZE);
+
+       is -> is_vec = vec + 2;
+       is -> is_tail = vec + vecp;
+
+       if (strcmp (cp = is -> is_vec[0], "tsapd-bootstrap"))
+           (void) strcpy (is -> is_vec[0] = file, isodefile (cp, 1));
+
+       return is;
+    }
+
+    return NULL;
+}
+
+/* \f */
+
+#ifdef DEBUG
+_printsrv (is)
+register struct isoservent *is;
+{
+    register int    n = is -> is_tail - is -> is_vec - 1;
+    register char **ap = is -> is_vec;
+
+    LLOG (addr_log, LLOG_DEBUG,
+         ("\tENT: \"%s\" PRV: \"%s\" SEL: %s",
+          is -> is_entity, is -> is_provider,
+          sel2str (is -> is_selector, is -> is_selectlen, 1)));
+
+    for (; n >= 0; ap++, n--)
+       LLOG (addr_log, LLOG_DEBUG,
+             ("\t\t%d: \"%s\"\n", ap - is -> is_vec, *ap));
+}
+#endif
diff --git a/src/isode/compat/lexequ.c b/src/isode/compat/lexequ.c
new file mode 100644 (file)
index 0000000..e0f2420
--- /dev/null
@@ -0,0 +1,68 @@
+/* lexequ.c - Compare two strings ignoring case */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:37  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:07  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:06  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:00  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+
+/* \f */
+
+lexequ (str1, str2)
+register char   *str1,
+               *str2;
+{
+    if (str1 == NULL)
+       if (str2 == NULL)
+               return (0);
+       else
+               return (-1);
+
+    if (str2 == NULL)
+       return (1);
+
+    while (chrcnv[*str1] == chrcnv[*str2]) {
+       if (*str1++ == NULL)
+           return (0);
+       str2++;
+    }
+
+    if (chrcnv[*str1] > chrcnv[*str2])
+       return (1);
+    else
+       return (-1);
+}
diff --git a/src/isode/compat/lexnequ.c b/src/isode/compat/lexnequ.c
new file mode 100644 (file)
index 0000000..666f7f4
--- /dev/null
@@ -0,0 +1,73 @@
+/* lexnequ.c - Compare two strings ignoring case upto n octets */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:39  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:08  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:08  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:01  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+
+/* \f */
+
+lexnequ (str1, str2, len)
+register char   *str1,
+               *str2;
+int             len;
+{
+    register int count = 1;
+
+    if (str1 == NULL)
+       if (str2 == NULL)
+               return (0);
+       else
+               return (1);
+
+    if (str2 == NULL)
+       return (-1);
+
+    while (chrcnv[*str1] == chrcnv[*str2++]) {
+       if (count++ >= len)
+           return (0);
+       if (*str1++ == NULL)
+           return (0);
+    }
+
+    str2--;
+    if (chrcnv[*str1] > chrcnv[*str2])
+       return (1);
+    else
+       return (-1);
+}
diff --git a/src/isode/compat/libicompat.3 b/src/isode/compat/libicompat.3
new file mode 100644 (file)
index 0000000..5eea8d7
--- /dev/null
@@ -0,0 +1,35 @@
+.TH LIBICOMPAT 3 "03 Jul 1986"
+.\" $Header$
+.\"
+.\"
+.\" $Log$
+.\" Revision 1.1  1994/06/10 03:27:41  eichin
+.\" autoconfed isode for kerberos work
+.\"
+Revision 1.1  94/06/10  03:16:10  eichin
+autoconfed isode for kerberos work
+
+# Revision 1.1  1994/05/31 20:34:10  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+.\" Revision 8.0  91/07/17  12:18:01  isode
+.\" Release 7.0
+.\" 
+.\"
+.SH NAME
+libicompat \- compatibility library
+.SH SYNOPSIS
+\fIcc\fR\0...\0\fB\-licompat\fR
+.SH DESCRIPTION
+The \fIlibicompat\fR library makes an attempt of providing an interface for
+similar services under different operating systems.
+Currently, the library works on most variants of Berkeley UNIX and AT&T UNIX.
+.SH FILES
+None
+.SH DIAGNOSTICS
+.SH AUTHOR
+Marshall T. Rose
+.SH BUGS
+To misquote M.A.\0Padlipsky,
+\*(lqsometimes when you try to make an apple look like an orange you get back
+something that smells like a lemon.\*(rq
diff --git a/src/isode/compat/log_tai.c b/src/isode/compat/log_tai.c
new file mode 100644 (file)
index 0000000..e45293c
--- /dev/null
@@ -0,0 +1,146 @@
+/* log_tai.c - system tailoring routines */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:43  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:12  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:13  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:03  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "cmd_srch.h"
+#include "general.h"
+#include "manifest.h"
+#include "logger.h"
+
+/* \f */
+
+#define        LG_FILE         1
+#define        LG_SFLAGS       2
+#define        LG_DFLAGS       3
+#define        LG_LEVEL        4
+#define        LG_SIZE         5
+#define        LG_DLEVEL       6
+#define LG_SSLEVEL     7
+#define LG_DSLEVEL     8
+
+static CMD_TABLE log_tbl[] = {
+       "FILE",         LG_FILE,
+       "SFLAGS",       LG_SFLAGS,
+       "DFLAGS",       LG_DFLAGS,
+       "LEVEL",        LG_LEVEL,
+       "SLEVEL",       LG_LEVEL,
+       "DLEVEL",       LG_DLEVEL,
+       "SSLEVEL",      LG_SSLEVEL,
+       "DSLEVEL",      LG_DSLEVEL,
+       "SIZE",         LG_SIZE,
+       0,              -1,
+};
+
+static CMD_TABLE log_lvltbl[] = {
+       "NONE",         LLOG_NONE,
+       "FATAL",        LLOG_FATAL,
+       "EXCEPTIONS",   LLOG_EXCEPTIONS,
+       "NOTICE",       LLOG_NOTICE,
+       "TRACE",        LLOG_TRACE,
+       "DEBUG",        LLOG_DEBUG,
+       "PDUS",         LLOG_PDUS,
+       "ALL",          LLOG_ALL,
+       0,      -1
+};
+
+static CMD_TABLE log_flgtbl[] = {
+       "CLOSE",        LLOGCLS,
+       "CREATE",       LLOGCRT,
+       "ZERO",         LLOGZER,
+       "TTY",          LLOGTTY,
+       0,              -1
+};
+
+/* \f */
+
+log_tai(lgptr, av, ac) /* for now only alter the level - files etc later */
+LLog    *lgptr;
+char    **av;
+int     ac;
+{
+       register int i;
+       register char *p;
+       int      val;
+
+       for(i = 0; i < ac; i++)
+       {
+               if((p = index(av[i], '=')) == NULLCP)
+                       continue;
+               *p++ = NULL;
+               switch(cmd_srch(av[i], log_tbl))
+               {
+                       case LG_LEVEL:
+                               val = cmd_srch(p,log_lvltbl);
+                               if (val != -1)
+                                       lgptr->ll_events |= val;
+                               break;
+                       case LG_DSLEVEL:
+                               val = cmd_srch (p, log_lvltbl);
+                               if (val != -1)
+                                       lgptr -> ll_syslog &= ~val;
+                               break;
+                       case LG_SSLEVEL:
+                               val = cmd_srch (p, log_lvltbl);
+                               if (val != -1)
+                                       lgptr -> ll_syslog |= val;
+                               break;
+                       case LG_DLEVEL:
+                               val = cmd_srch(p,log_lvltbl);
+                               if (val != -1)
+                                       lgptr->ll_events &= ~ val;
+                               break;
+                       case LG_FILE:
+                               lgptr->ll_file = strdup (p);
+                               break;
+                       case LG_SFLAGS:
+                               val = cmd_srch(p,log_flgtbl);
+                               if (val != -1)
+                                       lgptr->ll_stat |= val;
+                               break;
+                       case LG_DFLAGS:
+                               val = cmd_srch(p,log_flgtbl);
+                               if (val != -1)
+                                       lgptr->ll_stat &= ~ val;
+                               break;
+                       case LG_SIZE:
+                               lgptr->ll_msize = atoi(p);
+                               break;
+               }
+       }
+}
diff --git a/src/isode/compat/logger.c b/src/isode/compat/logger.c
new file mode 100644 (file)
index 0000000..8ad5cfc
--- /dev/null
@@ -0,0 +1,622 @@
+/* logger.c - system logging routines */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:44  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:14  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:15  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:03  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "logger.h"
+#include "tailor.h"
+
+#ifdef NULL
+#undef NULL
+#endif
+#include <sys/param.h>
+#ifndef        NULL
+#define        NULL    0
+#endif
+#include "sys.file.h"
+#include <sys/stat.h>
+
+#if linux
+/*
+ * Linux's syslog.h includes stdargs.h, which is not compatible with
+ * varargs.h.
+ */
+#define        LOG_EMERG       0       /* system is unusable */
+#define        LOG_ALERT       1       /* action must be taken immediately */
+#define        LOG_CRIT        2       /* critical conditions */
+#define        LOG_ERR         3       /* error conditions */
+#define        LOG_WARNING     4       /* warning conditions */
+#define        LOG_NOTICE      5       /* normal but significant condition */
+#define        LOG_INFO        6       /* informational */
+#define        LOG_DEBUG       7       /* debug-level messages */
+#else
+#ifndef        SYS5
+#include <syslog.h>
+#endif
+#endif
+
+/* \f */
+
+#ifndef        lint
+static
+#endif
+int  _ll_printf ();
+
+struct ll_private {
+    int            ll_checks;
+#define        CHKINT  15              /* call ll_check 1 in every 15 uses... */
+};
+
+static struct ll_private *llp = NULL;
+static IFP _ll_header_routine = ll_defmhdr;
+
+long   lseek ();
+
+/* \f */
+
+/* [eichin:19940412.1858EST] to supply getdtablesize for solaris... */
+#if defined(hpux) || defined(__svr4__)
+#include <sys/resource.h>
+int getdtablesize() {
+  struct rlimit rl;
+  getrlimit(RLIMIT_NOFILE, &rl);
+  return rl.rlim_cur;
+}
+#endif
+
+int    ll_open (lp)
+register LLog *lp;
+{
+    int            mask,
+           mode;
+    char   *bp,
+           buffer[BUFSIZ];
+
+    if (llp == NULL
+           && (llp = (struct ll_private *)
+                       calloc ((unsigned int) getdtablesize (),
+                               sizeof *llp)) == NULL)
+       goto you_lose;
+
+    if (lp -> ll_file == NULLCP
+           || *lp -> ll_file == NULL) {
+you_lose: ;
+       (void) ll_close (lp);
+       lp -> ll_stat |= LLOGERR;
+       return NOTOK;
+    }
+
+    lp -> ll_stat &= ~LLOGERR;
+
+    if (lp -> ll_fd != NOTOK)
+       return OK;
+
+    if (strcmp (lp -> ll_file, "-") == 0) {
+       lp -> ll_stat |= LLOGTTY;
+       return OK;
+    }
+
+    (void) sprintf (bp = buffer, _isodefile (isodelogpath, lp -> ll_file),
+                   getpid ());
+
+    mode = O_WRONLY | O_APPEND;
+    if (lp -> ll_stat & LLOGCRT)
+       mode |= O_CREAT;
+
+    mask = umask (~0666);
+    lp -> ll_fd = open (bp, mode, 0666);
+    (void) umask (mask);
+
+    if (ll_check (lp) == NOTOK)
+       return (NOTOK);
+    if (lp -> ll_fd != NOTOK)
+       llp[lp -> ll_fd].ll_checks = CHKINT;
+
+    return (lp -> ll_fd != NOTOK ? OK : NOTOK);
+}
+
+/* \f */
+
+int    ll_close (lp)
+register LLog *lp;
+{
+    int            status;
+    
+    if (lp -> ll_fd == NOTOK)
+       return OK;
+
+    status = close (lp -> ll_fd);
+    lp -> ll_fd = NOTOK;
+
+    return status;
+}
+
+/* \f */
+
+#ifndef        lint
+int    ll_log (va_alist)
+va_dcl
+{
+    int            event,
+           result;
+    LLog   *lp;
+    va_list ap;
+
+    va_start (ap);
+
+    lp = va_arg (ap, LLog *);
+    event = va_arg (ap, int);
+
+    result = _ll_log (lp, event, ap);
+
+    va_end (ap);
+
+    return result;
+}
+#else
+/* VARARGS4 */
+
+int    ll_log (lp, event, what, fmt)
+LLog   *lp;
+int    event;
+char   *what,
+       *fmt;
+{
+    return ll_log (lp, event, what, fmt);
+}
+#endif
+
+/* \f */
+
+int    _ll_log (lp, event, ap) /* what, fmt, args ... */
+register LLog *lp;
+int    event;
+va_list        ap;
+{
+    int            cc,
+           status;
+    register char *bp;
+    char   *what,
+           buffer[BUFSIZ];
+
+    if (!(lp -> ll_events & event))
+       return OK;
+
+    bp = buffer;
+
+    /* Create header */
+    (*_ll_header_routine)(bp, lp -> ll_hdr, lp -> ll_dhdr);
+
+    bp += strlen (bp);
+
+    what = va_arg (ap, char *);
+
+    _asprintf (bp, what, ap);
+
+#ifndef        SYS5
+    if (lp -> ll_syslog & event) {
+       int     priority;
+
+       switch (event) {
+           case LLOG_FATAL:
+               priority = LOG_ERR;
+               break;
+
+           case LLOG_EXCEPTIONS:
+               priority = LOG_WARNING;
+               break;
+
+           case LLOG_NOTICE:
+               priority = LOG_INFO;
+               break;
+
+           case LLOG_PDUS:
+           case LLOG_TRACE:
+           case LLOG_DEBUG:
+               priority = LOG_DEBUG;
+               break;
+
+           default:
+               priority = LOG_NOTICE;
+               break;
+       }
+
+       (void) syslog (priority, "%s", buffer + 13);
+
+       if (lp -> ll_stat & LLOGCLS)
+           (void) closelog ();
+    }
+#endif
+
+    if (!(lp -> ll_stat & LLOGTTY)
+           && lp -> ll_fd == NOTOK
+           && strcmp (lp -> ll_file, "-") == 0)
+       lp -> ll_stat |= LLOGTTY;
+
+    if (lp -> ll_stat & LLOGTTY) {
+       (void) fflush (stdout);
+
+       if (lp -> ll_fd != NOTOK)
+           (void) fprintf (stderr, "LOGGING: ");
+       (void) fputs (bp, stderr);
+       (void) fputc ('\n', stderr);
+       (void) fflush (stderr);
+    }
+    bp += strlen (bp);
+
+    if (lp -> ll_fd == NOTOK) {
+       if ((lp -> ll_stat & (LLOGERR | LLOGTTY)) == (LLOGERR | LLOGTTY))
+           return OK;
+       if (ll_open (lp) == NOTOK)
+           return NOTOK;
+    }
+    else
+       if ((!llp || llp[lp -> ll_fd].ll_checks-- < 0)
+               && ll_check (lp) == NOTOK)
+           return NOTOK;
+
+    *bp++ = '\n', *bp = NULL;
+    cc = bp - buffer;
+
+    if ((status = write (lp -> ll_fd, buffer, cc)) != cc) {
+       if (status == NOTOK) {
+           (void) ll_close (lp);
+error: ;
+           lp -> ll_stat |= LLOGERR;
+           return NOTOK;
+       }
+
+       status = NOTOK;
+    }
+    else
+       status = OK;
+
+    if ((lp -> ll_stat & LLOGCLS) && ll_close (lp) == NOTOK)
+       goto error;
+
+    return status;
+}
+
+/* \f */
+
+void   ll_hdinit (lp, prefix)
+register LLog *lp;
+char   *prefix;
+{
+    register char  *cp,
+                  *up;
+    char    buffer[BUFSIZ],
+           user[10];
+
+    if (prefix == NULLCP) {
+       if ((lp -> ll_stat & LLOGHDR) && strlen (lp -> ll_hdr) == 25)
+           (cp = lp -> ll_hdr)[8] = NULL;
+       else
+           cp = "unknown";
+    }
+    else {
+       if ((cp = rindex (prefix, '/')))
+           cp++;
+       if (cp == NULL || *cp == NULL)
+           cp = prefix;
+    }
+
+    if ((up = getenv ("USER")) == NULLCP
+           && (up = getenv ("LOGNAME")) == NULLCP) {
+       (void) sprintf (user, "#%d", getuid ());
+       up = user;
+    }
+    (void) sprintf (buffer, "%-8.8s %05d (%-8.8s)",
+                   cp, getpid () % 100000, up);
+
+    if (lp -> ll_stat & LLOGHDR)
+       free (lp -> ll_hdr);
+    lp -> ll_stat &= ~LLOGHDR;
+
+    if ((lp -> ll_hdr = malloc ((unsigned) (strlen (buffer) + 1))) == NULLCP)
+       return;
+
+    (void) strcpy (lp -> ll_hdr, buffer);
+    lp -> ll_stat |= LLOGHDR;
+}
+
+/* \f */
+
+void   ll_dbinit (lp, prefix)
+register LLog *lp;
+char   *prefix;
+{
+    register char  *cp;
+    char    buffer[BUFSIZ];
+
+    ll_hdinit (lp, prefix);
+
+    if (prefix) {
+       if ((cp = rindex (prefix, '/')))
+           cp++;
+       if (cp == NULL || *cp == NULL)
+           cp = prefix;
+
+       (void) sprintf (buffer, "./%s.log", cp);
+
+       if ((lp -> ll_file = malloc ((unsigned) (strlen (buffer) + 1)))
+               == NULLCP)
+           return;
+
+       (void) strcpy (lp -> ll_file, buffer);
+    }
+
+    lp -> ll_events |= LLOG_ALL;
+    lp -> ll_stat |= LLOGTTY;
+}
+
+/* \f */
+
+#ifndef        lint
+int    ll_printf (va_alist)
+va_dcl
+{
+    int            result;
+    LLog    *lp;
+    va_list ap;
+
+    va_start (ap);
+
+    lp = va_arg (ap, LLog *);
+
+    result = _ll_printf (lp, ap);
+
+    va_end (ap);
+
+    return result;
+}
+#else
+/* VARARGS2 */
+
+int    ll_printf (lp, fmt)
+LLog   *lp;
+char   *fmt;
+{
+    return ll_printf (lp, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef        lint
+static
+#endif
+int  _ll_printf (lp, ap)               /* fmt, args ... */
+register LLog *lp;
+va_list        ap;
+{
+    int            cc,
+           status;
+    register char   *bp;
+    char     buffer[BUFSIZ];
+    char    *fmt;
+    va_list fp = ap;
+
+    fmt = va_arg (fp, char *);
+    if (strcmp (fmt, "%s") != 0) {
+       bp = buffer;
+       _asprintf (bp, NULLCP, ap);
+    }
+    else {
+       bp = NULL;
+       fmt = va_arg (fp, char *);
+    }
+
+    if (!(lp -> ll_stat & LLOGTTY)
+           && lp -> ll_fd == NOTOK
+           && strcmp (lp -> ll_file, "-") == 0)
+       lp -> ll_stat |= LLOGTTY;
+
+    if (lp -> ll_stat & LLOGTTY) {
+       (void) fflush (stdout);
+
+       if (bp)
+           (void) fputs (bp, stderr);
+       else
+           (void) fputs (fmt, stderr);
+       (void) fflush (stderr);
+    }
+    if (bp)
+       bp += strlen (bp);
+
+    if (lp -> ll_fd == NOTOK) {
+       if ((lp -> ll_stat & (LLOGERR | LLOGTTY)) == (LLOGERR | LLOGTTY))
+           return OK;
+       if (ll_open (lp) == NOTOK)
+           return NOTOK;
+    }
+    else
+       if ((!llp || llp[lp -> ll_fd].ll_checks-- < 0)
+               && ll_check (lp) == NOTOK)
+           return NOTOK;
+
+    if (bp)
+       cc = bp - buffer;
+    else
+       cc = strlen (fmt);
+
+    if ((status = write (lp -> ll_fd, bp ? buffer : fmt, cc)) != cc) {
+       if (status == NOTOK) {
+           (void) ll_close (lp);
+           lp -> ll_stat |= LLOGERR;
+           return NOTOK;
+       }
+
+       status = NOTOK;
+    }
+    else
+       status = OK;
+
+    return status;
+}
+
+/* \f */
+
+int    ll_sync (lp)
+register LLog *lp;
+{
+    if (lp -> ll_stat & LLOGCLS)
+       return ll_close (lp);
+
+    return OK;
+}
+
+/* \f */
+
+#ifndef        lint
+char   *ll_preset (va_alist)
+va_dcl
+{
+    va_list ap;
+    static char buffer[BUFSIZ];
+
+    va_start (ap);
+
+    _asprintf (buffer, NULLCP, ap);
+
+    va_end (ap);
+
+    return buffer;
+}
+#else
+/* VARARGS1 */
+
+char   *ll_preset (fmt)
+char   *fmt;
+{
+    return ll_preset (fmt);
+}
+#endif
+
+/* \f */
+
+int    ll_check (lp)
+register LLog *lp;
+{
+#ifndef        BSD42
+    int            fd;
+    char    buffer[BUFSIZ];
+#endif
+    long    size;
+    struct stat st;
+
+    if ((size = lp -> ll_msize) <= 0)
+       return OK;
+
+    if (llp && lp -> ll_fd != NOTOK)
+       llp[lp -> ll_fd].ll_checks = CHKINT;
+    if (lp -> ll_fd == NOTOK
+           || (fstat (lp -> ll_fd, &st) != NOTOK
+                   && st.st_size < (size <<= 10)))
+       return OK;
+
+    if (!(lp -> ll_stat & LLOGZER)) {
+       (void) ll_close (lp);
+
+#ifndef        BSD42
+error: ;
+#endif
+       lp -> ll_stat |= LLOGERR;
+       return NOTOK;
+    }
+
+#ifdef BSD42
+#ifdef SUNOS4
+    (void) ftruncate (lp -> ll_fd, (off_t) 0);
+#else
+    (void) ftruncate (lp -> ll_fd, 0);
+#endif
+    (void) lseek (lp -> ll_fd, 0L, 0);
+    return OK;
+#else
+    (void) sprintf (buffer, _isodefile (isodelogpath, lp -> ll_file),
+                   getpid ());
+    if ((fd = open (buffer, O_WRONLY | O_APPEND | O_TRUNC)) == NOTOK)
+       goto error;
+    (void) close (fd);
+    return OK;
+#endif
+}
+
+/* \f */
+
+/*
+ * ll_defmhdr - Default "make header" routine.
+ */
+int    ll_defmhdr(bufferp, headerp, dheaderp)
+char   *bufferp;               /* Buffer pointer */
+char   *headerp;               /* Static header string */
+char   *dheaderp;              /* Dynamic header string */
+{
+    time_t    clock;
+    register struct tm *tm;
+
+    (void) time (&clock);
+    tm = localtime (&clock);
+
+    (void) sprintf (bufferp, "%2d/%2d %2d:%02d:%02d %s %s ",
+                   tm -> tm_mon + 1, tm -> tm_mday,
+                   tm -> tm_hour, tm -> tm_min, tm -> tm_sec,
+                   headerp ? headerp : "",
+                   dheaderp ? dheaderp : "");
+    return OK;
+}
+
+/* \f */
+
+/*
+ * ll_setmhdr - Set "make header" routine, overriding default.
+ */
+IFP    ll_setmhdr (make_header_routine) 
+IFP    make_header_routine;
+{
+    IFP result = _ll_header_routine;
+
+    _ll_header_routine = make_header_routine;
+
+    return result;
+
+}
diff --git a/src/isode/compat/na2norm.c b/src/isode/compat/na2norm.c
new file mode 100644 (file)
index 0000000..254faa8
--- /dev/null
@@ -0,0 +1,163 @@
+/* na2norm.c - normalize NSAPaddr */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:46  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:16  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:18  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:04  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+#include "internet.h"
+#include "tailor.h"
+
+/* Encoding based on
+
+       "An interim approach to use of Network Addresses",
+       S.E. Kille, January 16, 1989
+
+ */
+
+/* \f */
+
+struct NSAPaddr *na2norm (na)
+register struct NSAPaddr *na;
+{
+    int            ilen;
+    register char  *cp,
+                  *dp;
+    char    nsap[NASIZE * 2 + 1];
+    register struct hostent *hp;
+    register struct ts_interim *ts;
+    static struct NSAPaddr nas;
+    register struct NSAPaddr *ca = &nas;
+
+    if (na -> na_stack == NA_NSAP) {
+       *ca = *na;      /* struct copy */
+       return ca;
+    }
+
+    bzero ((char *) ca, sizeof *ca);
+    ca -> na_stack = NA_NSAP;
+
+    for (ts = ts_interim; ts -> ts_name; ts++)
+       if (ts -> ts_subnet == na -> na_community)
+           break;
+    if (!ts -> ts_name) {
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("unable to find community #%d", na -> na_community));
+       return NULLNA;
+    }
+    
+    cp = nsap;
+    switch (na -> na_stack) {
+       case NA_TCP:
+           if ((hp = gethostbystring (na -> na_domain)) == NULL) {
+               SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("%s: unknown host", na -> na_domain));
+               return NULLNA;
+           }
+#define        s2a(b)  (((int) (b)) & 0xff)
+           (void) sprintf (cp, "%03d%03d%03d%03d",
+                           s2a (hp -> h_addr[0]),
+                           s2a (hp -> h_addr[1]),
+                           s2a (hp -> h_addr[2]),
+                           s2a (hp -> h_addr[3]));
+           cp += strlen (cp);
+#undef s2a
+
+           if (na -> na_port) {
+               (void) sprintf (cp, "%05d", (int) ntohs (na -> na_port));
+               cp += strlen (cp);
+
+               if (na -> na_tset || na -> na_tset != NA_TSET_TCP) {
+                   (void) sprintf (cp, "%05d", (int) na -> na_tset);
+                   cp += strlen (cp);
+               }
+           }
+           break;
+
+       case NA_X25:
+       case NA_BRG:
+           if (na -> na_community == SUBNET_INT_X25
+                   && na -> na_cudflen == 0
+                   && na -> na_pidlen == 0
+                   && na -> na_dte[0] != '0') {        /* SEK - X121 form */
+                                               /* should be more general */
+               (void) sprintf (nsap, "36%014s", na -> na_dte);
+               ts = NULL;
+               break;
+           }
+
+           if (ilen = na -> na_pidlen & 0xff)
+               *cp++ = '1', dp = na -> na_pid;
+           else
+               if (ilen = na -> na_cudflen & 0xff)
+                   *cp++ = '2', dp = na -> na_cudf;
+               else
+                   *cp++ = '0';
+           if (ilen) {
+               (void) sprintf (cp, "%01d", ilen);
+               cp += strlen (cp);
+
+               for (; ilen-- > 0; cp += 3)
+                   (void) sprintf (cp, "%03d", *dp++ & 0xff);
+           }
+           (void) strcpy (cp, na -> na_dte);
+           break;
+
+       default:
+           SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("unknown address type 0x%x", na -> na_stack));
+           return NULLNA;
+    }
+
+    cp = nsap, dp = ca -> na_address;
+    if (ts) {
+       bcopy (ts -> ts_prefix, dp, ts -> ts_length);
+       dp += ts -> ts_length;
+    }
+    while (*cp) {
+       *dp = (*cp++ - '0') << 4;
+       if (*cp)
+           *dp++ |= (*cp++ - '0') & 0x0f;
+       else
+           *dp++ |= 0x0f;
+    }
+    ca -> na_addrlen = dp - ca -> na_address;
+
+    return ca;    
+}
diff --git a/src/isode/compat/na2str.c b/src/isode/compat/na2str.c
new file mode 100644 (file)
index 0000000..21bbf30
--- /dev/null
@@ -0,0 +1,62 @@
+/* na2str.c - pretty-print NSAPaddr */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:48  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:17  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:20  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:05  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f   Network Address to String */
+
+char   *na2str (na)
+register struct NSAPaddr *na;
+{
+    switch (na -> na_stack) {
+       case NA_TCP: 
+           return na -> na_domain;
+
+       case NA_X25:
+       case NA_BRG: 
+           return na -> na_dte;
+
+       case NA_NSAP:
+       default:
+           return sel2str (na -> na_address, na -> na_addrlen, 0);
+    }
+}
diff --git a/src/isode/compat/nochrcnv.c b/src/isode/compat/nochrcnv.c
new file mode 100644 (file)
index 0000000..4377c0d
--- /dev/null
@@ -0,0 +1,81 @@
+/* nochrcnv.c - character conversion table, no case folding */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:50  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:20  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:21  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:05  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+
+/* \f */
+
+char                    /* straight mapping - Non case sensive */
+                       /* used for consistency */
+       nochrcnv[] =
+{
+    '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7',
+    '\10', '\11', '\12', '\13', '\14', '\15', '\16', '\17',
+    '\20', '\21', '\22', '\23', '\24', '\25', '\26', '\27',
+    '\30', '\31', '\32', '\33', '\34', '\35', '\36', '\37',
+    '\40', '\41', '\42', '\43', '\44', '\45', '\46', '\47',
+    '\50', '\51', '\52', '\53', '\54', '\55', '\56', '\57',
+    '\60', '\61', '\62', '\63', '\64', '\65', '\66', '\67',
+    '\70', '\71', '\72', '\73', '\74', '\75', '\77', '\77',
+    '\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
+    '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
+    '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
+    '\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137',
+    '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+    '\170', '\171', '\172', '\173', '\174', '\175', '\177', '\177',
+    '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7',
+    '\10', '\11', '\12', '\13', '\14', '\15', '\16', '\17',
+    '\20', '\21', '\22', '\23', '\24', '\25', '\26', '\27',
+    '\30', '\31', '\32', '\33', '\34', '\35', '\36', '\37',
+    '\40', '\41', '\42', '\43', '\44', '\45', '\46', '\47',
+    '\50', '\51', '\52', '\53', '\54', '\55', '\56', '\57',
+    '\60', '\61', '\62', '\63', '\64', '\65', '\66', '\67',
+    '\70', '\71', '\72', '\73', '\74', '\75', '\77', '\77',
+    '\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107',
+    '\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117',
+    '\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127',
+    '\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137',
+    '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+    '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+    '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+    '\170', '\171', '\172', '\173', '\174', '\175', '\177', '\177'
+};
diff --git a/src/isode/compat/norm2na.c b/src/isode/compat/norm2na.c
new file mode 100644 (file)
index 0000000..7a872ab
--- /dev/null
@@ -0,0 +1,287 @@
+/* norm2na.c - normalize NSAPaddr to NSAP struct */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:52  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:22  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:23  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:06  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "isoaddrs.h"
+#include "tailor.h"
+#include "internet.h"
+
+/* Encoding on "unrealNS" addresses based on
+
+       "An interim approach to use of Network Addresses",
+       S.E. Kille, January 16, 1989
+
+ */
+
+/* \f */
+
+int    norm2na (p, len, na)
+char   *p;
+int    len;
+struct NSAPaddr *na;
+{
+    na -> na_stack = NA_NSAP;
+
+    if ((len == 8) && ((p[0] == 0x36) || (p[0] == 0x37))) {
+       int     xlen;                   /* SEK - X121 form */
+       register char   *cp,
+                       *cp2,
+                       *dp;
+       char    nsap[14];
+
+       dp = nsap;
+       for (cp2 = (cp = p + 1) + 7; cp < cp2; cp++) {
+           register int     j;
+
+           if ((j = ((*cp & 0xf0) >> 4)) > 9)
+               goto concrete;
+           *dp++ = j + '0';
+
+           if ((j = (*cp & 0x0f)) > 9) {
+               if (j != 0x0f)
+                   goto concrete;
+           }
+           else
+               *dp++ = j + '0';
+       }
+
+       for (cp = nsap, xlen = 14; *cp == '0'; cp++, xlen--)
+           continue;
+       na -> na_dtelen = xlen;
+       for (cp2 = na -> na_dte; xlen-- > 0; )
+               *cp2++ = *cp++;
+       *cp2 = NULL;
+#ifdef BRIDGE_X25
+       na -> na_stack = bridgediscrim (na) ? NA_BRG : NA_X25;
+#else
+       na -> na_stack = NA_X25;
+#endif
+       na -> na_community = SUBNET_INT_X25;
+    }
+    else {
+       register struct ts_interim *ts,
+                                  *tp;
+
+       tp = NULL;
+       for (ts = ts_interim; ts -> ts_name; ts++)
+           if (len > ts -> ts_length
+                   && (tp == NULL || ts -> ts_length > tp -> ts_length)
+                   && bcmp (p, ts -> ts_prefix, ts -> ts_length) == 0)
+               tp = ts;
+       if (tp) {
+           int     i,
+                   ilen,
+                   rlen;
+           register char   *cp,
+                           *dp,
+                           *ep;
+           char    nsap[NASIZE * 2 + 1];
+
+           if (tp -> ts_syntax == NA_NSAP)
+               goto lock_and_load;
+           dp = nsap;
+           for (cp = p + tp -> ts_length, ep = p + len;
+                    cp < ep;
+                    cp++) {
+               register int     j;
+
+               if ((j = ((*cp & 0xf0) >> 4)) > 9) {
+concrete: ;
+                   LLOG (addr_log, LLOG_EXCEPTIONS,
+                         ("invalid concrete encoding"));
+                   goto realNS;
+               }
+               *dp++ = j + '0';
+
+               if ((j = (*cp & 0x0f)) > 9) {
+                   if (j != 0x0f)
+                       goto concrete;
+               }
+               else
+                   *dp++ = j + '0';
+           }
+           *dp = NULL;
+
+           cp = nsap;
+lock_and_load: ;
+           na -> na_community = tp -> ts_subnet;
+           switch (na -> na_stack = tp -> ts_syntax) {
+               case NA_NSAP:
+                   goto unrealNS;
+
+               case NA_X25:
+                   if ((int)strlen (cp) < 1) {
+                       LLOG (addr_log, LLOG_EXCEPTIONS,
+                             ("missing DTE+CUDF indicator: %s", nsap));
+                       goto realNS;
+                   }
+                   (void) sscanf (cp, "%1d", &i);
+                   cp += 1;
+                   switch (i) {
+                       case 0: /* DTE only */
+                           break;
+
+                       case 1: /* DTE+PID */
+                       case 2: /* DTE+CUDF */
+                           if ((int)strlen (cp) < 1) {
+                               LLOG (addr_log, LLOG_EXCEPTIONS,
+                                     ("missing DTE+CUDF indicator: %s",
+                                      nsap));
+                               goto realNS;
+                           }
+                           (void) sscanf (cp, "%1d", &ilen);
+                           cp += 1;
+                           rlen = ilen * 3;
+                           if ((int)strlen (cp) < rlen) {
+                               LLOG (addr_log, LLOG_EXCEPTIONS,
+                                     ("bad DTE+CUDF length: %s", nsap));
+                               goto realNS;
+                           }
+                           if (i == 1) {
+                               if (ilen > NPSIZE) {
+                                   LLOG (addr_log, LLOG_EXCEPTIONS,
+                                         ("PID too long: %s", nsap));
+                                   goto realNS;
+                               }
+                               dp = na -> na_pid;
+                               na -> na_pidlen = ilen;
+                           }
+                           else {
+                               if (ilen > CUDFSIZE) {
+                                   LLOG (addr_log, LLOG_EXCEPTIONS,
+                                         ("CUDF too long: %s", nsap));
+                                   goto realNS;
+                               }
+                               dp = na -> na_cudf;
+                               na -> na_cudflen = ilen;
+                           }
+                           for (; rlen > 0; rlen -= 3) {
+                               (void) sscanf (cp, "%3d", &i);
+                               cp += 3;
+
+                               if (i > 255) {
+                                   LLOG (addr_log, LLOG_EXCEPTIONS,
+                                         ("invalid PID/CUDF: %s", nsap));
+                                   goto realNS;
+                               }
+                               *dp++ = i & 0xff;
+                           }
+                           break;
+
+                       default:
+                           LLOG (addr_log, LLOG_EXCEPTIONS,
+                                 ("invalid DTE+CUDF indicator: %s", nsap));
+                           goto realNS;
+                       }
+                   (void) strcpy (na -> na_dte, cp);
+                   na -> na_dtelen = strlen (na -> na_dte);
+
+#ifdef BRIDGE_X25
+                   if (bridgediscrim (na))
+                       na -> na_stack = NA_BRG;
+#endif
+                   break;
+
+               case NA_TCP:
+                   if ((int)strlen (cp) < 12) {
+                       LLOG (addr_log, LLOG_EXCEPTIONS,
+                             ("missing IP address: %s", nsap));
+                       goto realNS;
+                   }
+                   {
+                       int         q[4];
+
+                       (void) sscanf (cp, "%3d%3d%3d%3d", q, q + 1, q + 2,
+                                      q + 3);
+                       (void) sprintf (na -> na_domain,
+                                       "%d.%d.%d.%d", q[0], q[1], q[2], q[3]);
+                   }
+                   cp += 12;
+
+                   if (*cp) {
+                       if ((int)strlen (cp) < 5) {
+                           LLOG (addr_log, LLOG_EXCEPTIONS,
+                                 ("missing port: %s", nsap));
+                           goto realNS;
+                       }
+                       (void) sscanf (cp, "%5d", &i);
+                       cp += 5;
+                       na -> na_port = htons ((u_short) i);
+
+                       if (*cp) {
+                           if ((int)strlen (cp) < 5) {
+                               LLOG (addr_log, LLOG_EXCEPTIONS,
+                                     ("missing tset: %s", nsap));
+                               goto realNS;
+                           }
+                           (void) sscanf (cp, "%5d", &i);
+                           cp += 5;
+                           na -> na_tset = (u_short) i;
+
+                           if (*cp)
+                               LLOG (addr_log, LLOG_EXCEPTIONS,
+                                     ("extra TCP information: %s", nsap));
+                       }
+                   }
+                   break;
+
+               default:
+                   LLOG (addr_log, LLOG_NOTICE,
+                         ("unknown syntax %d for DSP: %s", ts -> ts_syntax,
+                          nsap));
+                   goto realNS;
+               }
+       }
+       else {
+realNS: ;
+           na -> na_stack = NA_NSAP;
+           na -> na_community = SUBNET_REALNS;
+unrealNS: ;
+           if (len > sizeof na -> na_address) {
+               LLOG (addr_log, LLOG_EXCEPTIONS,
+                     ("NSAP address too long: %d octets", len));
+               return NOTOK;
+           }
+           bcopy (p, na -> na_address, na -> na_addrlen = len);
+       }
+    }
+
+    return OK;
+}
diff --git a/src/isode/compat/pa2str.c b/src/isode/compat/pa2str.c
new file mode 100644 (file)
index 0000000..8ea39c5
--- /dev/null
@@ -0,0 +1,107 @@
+/* pa2str.c - pretty-print PSAPaddr */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:23  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:25  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:07  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f   Presentation Address to String */
+
+char   *pa2str (px)
+register struct PSAPaddr *px;
+{
+    register char *bp;
+    struct PSAPaddr pas;
+    register struct PSAPaddr *pa = &pas;
+    register struct TSAPaddr *ta = &pa -> pa_addr.sa_addr;
+    static char buffer[BUFSIZ];
+
+    bp = buffer;
+
+    *pa = *px; /* struct copy */
+    if (ta -> ta_selectlen > 0
+           && ta -> ta_selectlen < sizeof ta -> ta_selector) {
+       register char *dp,
+                     *ep;
+       register struct TSAPaddr *tz;
+       register int n, m;
+
+       /* does this look like an encoded TSEL? */
+       m = ta -> ta_selectlen;
+       n = ta -> ta_selector[0];
+       if (m > 4 &&
+           ta -> ta_selector[0] == ta -> ta_selector[1] &&
+           n > 2 && n <= m - 2) 
+       {                                               /* encoded! */
+           tz = &px -> pa_addr.sa_addr;
+           bzero ((char *)ta, sizeof *ta);
+           if ((ta -> ta_selectlen = m - n - 2) > 0)
+                   bcopy (&tz -> ta_selector[n+2], ta -> ta_selector,
+                          ta -> ta_selectlen);
+           if (norm2na (&tz -> ta_selector[2], n, ta -> ta_addrs) != OK) {
+                   *pa = *px;
+                   goto normal;
+           }
+           ta -> ta_naddr = 1;
+           goto bridge;
+       }
+       for (ep = (dp = ta -> ta_selector) + ta -> ta_selectlen, *ep = NULL;
+                dp < ep;
+                dp++)
+           if (!isprint ((u_char) *dp) && *dp != ' ')
+               break;
+       if (dp >= ep && (tz = str2taddr (ta -> ta_selector))) {
+           pa -> pa_addr.sa_addr = *tz;            /* struct copy */
+       bridge:
+           (void) sprintf (bp, "%s through TS bridge at ",
+                           paddr2str (pa, NULLNA));
+           bp += strlen (bp);
+
+           bzero ((char *) pa, sizeof *pa);
+           *ta = px -> pa_addr.sa_addr;    /* struct copy */
+           ta -> ta_selectlen = 0;
+       }
+    }
+normal:
+    (void) strcpy (bp, paddr2str (pa, NULLNA));
+
+    return buffer;
+}
diff --git a/src/isode/compat/putenv.c b/src/isode/compat/putenv.c
new file mode 100644 (file)
index 0000000..24013dc
--- /dev/null
@@ -0,0 +1,116 @@
+/* putenv.c - generic putenv() */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:55  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:25  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:26  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:07  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f */
+
+extern  char **environ;
+static nvmatch ();
+
+/* \f */
+
+int     setenv (name, value)
+register char  *name,
+               *value;
+{
+    register int    i;
+    register char **ep,
+                  **nep,
+                   *cp;
+
+    if ((cp = malloc ((unsigned) (strlen (name) + strlen (value) + 2)))
+           == NULL)
+       return 1;
+    (void) sprintf (cp, "%s=%s", name, value);
+
+    for (ep = environ, i = 0; *ep; ep++, i++)
+       if (nvmatch (name, *ep)) {
+           *ep = cp;
+           return 0;
+       }
+
+    if ((nep = (char **) malloc ((unsigned) ((i + 2) * sizeof *nep)))
+           == NULL) {
+       free (cp);
+       return 1;
+    }
+    for (ep = environ, i = 0; *ep; nep[i++] = *ep++)
+       continue;
+    nep[i++] = cp;
+    nep[i] = NULL;
+    environ = nep;
+    return 0;
+}
+
+/* \f */
+
+int    unsetenv (name)
+char   *name;
+{
+    char  **ep,
+          **nep;
+
+    for (ep = environ; *ep; ep++)
+       if (nvmatch (name, *ep))
+           break;
+    if (*ep == NULL)
+       return 1;
+
+    for (nep = ep + 1; *nep; nep++)
+       continue;
+    *ep = *--nep;
+    *nep = NULL;
+    return 0;
+}
+
+/* \f */
+
+static nvmatch (s1, s2)
+register char  *s1,
+               *s2;
+{
+    while (*s1 == *s2++)
+       if (*s1++ == '=')
+           return 1;
+
+    return (*s1 == '\0' && *--s2 == '=');
+}
diff --git a/src/isode/compat/rcmd_srch.c b/src/isode/compat/rcmd_srch.c
new file mode 100644 (file)
index 0000000..c8a0747
--- /dev/null
@@ -0,0 +1,53 @@
+/* rcmd_srch.c: search a lookup table: return string value */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:57  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:27  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:28  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:08  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "manifest.h"
+#include "cmd_srch.h"
+
+/* \f */
+
+char   *rcmd_srch(val, cmd)
+register int   val;
+register CMD_TABLE *cmd;
+{
+       for(;cmd->cmd_key != NULLCP; cmd++)
+               if(val == cmd->cmd_value)
+                       return(cmd->cmd_key);
+       return(NULLCP);
+}
diff --git a/src/isode/compat/saddr2str.c b/src/isode/compat/saddr2str.c
new file mode 100644 (file)
index 0000000..9d8fb65
--- /dev/null
@@ -0,0 +1,59 @@
+/* saddr2str.c - SSAPaddr to string value */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:27:59  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:29  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:29  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:08  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f */
+
+char   *saddr2str (sa)
+register struct SSAPaddr *sa;
+{
+    struct PSAPaddr pas;
+    register struct PSAPaddr *pa = &pas;
+
+    if (!sa)
+       return NULL;
+    bzero ((char *) pa, sizeof *pa);
+    pa -> pa_addr = *sa;               /* struct copy */
+
+    return paddr2str (pa, NULLNA);
+}
diff --git a/src/isode/compat/sel2str.c b/src/isode/compat/sel2str.c
new file mode 100644 (file)
index 0000000..6a94682
--- /dev/null
@@ -0,0 +1,98 @@
+/* sel2str.c - selector to string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:02  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:31  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:31  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:09  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f */
+
+char   *sel2str (sel, len, quoted)
+char   *sel;
+int    len,
+       quoted;
+{
+    register char *cp,
+                 *dp,
+                 *ep;
+    static int    i = 0;
+    static char buf1[NASIZE * 2 + 1],
+               buf2[NASIZE * 2 + 1],
+               buf3[NASIZE * 2 + 1],
+               buf4[NASIZE * 2 + 1];
+    static char *bufs[] = { buf1, buf2, buf3, buf4 };
+
+    cp = bufs[i++];
+    i = i % 4;
+
+    if (quoted) {
+#ifndef        NOGOSIP
+       if (len == 2) {
+           if (quoted < 0)
+               goto ugly;
+           (void) sprintf (cp, "#%d",
+                           (sel[0] & 0xff) << 8 | (sel[1] & 0xff));
+           goto out;
+       }
+#endif
+
+       for (ep = (dp = sel) + len; dp < ep; dp++)
+           if (!isprint ((u_char) *dp))
+               goto ugly;
+
+       if (len > NASIZE * 2)
+           len = NASIZE * 2;
+
+       (void) sprintf (cp, len ? "\"%*.*s\"" : "\"\"", len, len, sel);
+    }
+    else {
+ugly: ;
+       if (len > NASIZE)       /* XXX */
+           len = NASIZE;
+
+       cp[explode (cp, (u_char *) sel, len)] = NULL;
+    }
+#ifndef        NOGOSIP
+out: ;
+#endif
+       
+    return cp;
+}
diff --git a/src/isode/compat/select.c b/src/isode/compat/select.c
new file mode 100644 (file)
index 0000000..9bfb13e
--- /dev/null
@@ -0,0 +1,389 @@
+/* select.c - select() abstractions */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:04  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:33  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:33  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:09  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <errno.h>
+#include <stdio.h>
+#include "manifest.h"
+#include "tailor.h"
+#include <sys/stat.h>
+
+
+extern int errno;
+
+
+int    xselect_blocking_on_intr = 0;
+
+/* \f */
+
+#if    defined(SOCKETS) && !defined(TLI_POLL)
+
+#include <sys/time.h>
+
+
+/* Synchronous multiplexing:
+       < 0 :   block indefinately
+       = 0 :   poll
+       > 0 :   wait
+ */
+
+int    selsocket (nfds, rfds, wfds, efds, secs)
+int    nfds;
+fd_set *rfds,
+       *wfds,
+       *efds;
+int    secs;
+{
+    int     n;
+    fd_set  ifds,
+            ofds,
+           xfds;
+#if defined(masscomp) && defined(_ATT)
+    int msecs;
+#else
+    struct timeval  tvs;
+    register struct timeval *tv = &tvs;
+#endif
+
+#if defined(masscomp) && defined(_ATT)
+    if (secs != NOTOK)
+       msecs = secs * 1000;
+    else
+       msecs = -1;
+#else
+    if (secs != NOTOK)
+       tv -> tv_sec = secs, tv -> tv_usec = 0;
+    else
+       tv = NULL;
+#endif
+
+    if (rfds)
+       ifds = *rfds;
+    if (wfds)
+       ofds = *wfds;
+    if (efds)
+       xfds = *efds;
+#if defined(masscomp) && defined(_ATT)
+    if (efds)
+       FD_ZERO(efds);
+#endif
+
+    for (;;) {
+#if defined(masscomp) && defined(_ATT)
+       switch (n = select (nfds, rfds, wfds, msecs)) {
+#else
+       switch (n = select (nfds, rfds, wfds, efds, tv)) {
+#endif
+           case OK: 
+               if (secs == NOTOK)
+                   break;
+               return OK;
+
+           case NOTOK:
+               if (xselect_blocking_on_intr
+                       && errno == EINTR
+                       && secs == NOTOK)
+                   continue;
+               /* else fall... */
+                   
+           default: 
+               return n;
+       }
+
+       if (rfds)
+           *rfds = ifds;
+       if (wfds)
+           *wfds = ofds;
+       if (efds)
+           *efds = xfds;
+    }
+}
+#endif
+
+/* \f */
+
+#ifdef EXOS
+
+#ifdef SYS5
+
+/* There seems to be a bug in the SYS5 EXOS select() routine when a socket can
+   be read immediately (don't know about write).  The bug is that select()
+   returns ZERO, and the mask is zero'd as well.  The code below explicitly
+   checks for this case.
+*/
+
+#include "sys/soioctl.h"
+
+
+int    selsocket (nfds, rfds, wfds, efds, secs)
+int    nfds;
+fd_set *rfds,
+       *wfds,
+       *efds;
+int    secs;
+{
+    register int    fd;
+    int     n;
+    fd_set  ifds,
+            ofds;
+    long    nbytes,
+           usecs;
+
+    if (secs != NOTOK)
+       usecs = secs * 1000;
+    else
+       usecs = 0xffff; /* used to be ~(1L << (8 * sizeof usecs - 1)) */
+
+    if (rfds)
+       ifds = *rfds;
+    if (wfds)
+       ofds = *wfds;
+    if (efds)
+       FD_ZERO (efds);
+
+    for (;;) {
+       switch (n = select (nfds + 1, rfds, wfds, usecs)) {  /* +1 for UNISYS */
+           case OK: 
+               if (rfds)
+                   for (fd = 0; fd < nfds; fd++)
+                       if (FD_ISSET (fd, &ifds)
+                               && ioctl (fd, FIONREAD, (char *) &nbytes)
+                                           != NOTOK
+                               && nbytes > 0) {
+                           FD_SET (fd, rfds);
+                           n++;
+                       }
+               if (n == 0 && secs == NOTOK)
+                   break;
+               return n;
+
+           case NOTOK: 
+           default: 
+               return n;
+       }
+
+       if (rfds)
+           *rfds = ifds;
+       if (wfds)
+           *wfds = ofds;
+    }
+}
+#endif
+#endif
+
+#if defined(TLI_TP) && defined(TLI_POLL)
+#include <poll.h>
+
+int selsocket (nfds, rfds, wfds, efds, secs)
+int    nfds;
+fd_set *rfds, *wfds, *efds;
+int    secs;
+{
+    int i, j, n;
+    struct pollfd pollfds[128];
+
+    for (i = j = 0; i < nfds; i++) {
+       pollfds[j].fd = NOTOK;
+       pollfds[j].events = 0;
+       if (rfds && FD_ISSET (i, rfds)) {
+           pollfds[j].fd = i;
+           pollfds[j].events |= POLLIN | POLLPRI;
+       }
+       if (wfds && FD_ISSET (i, wfds)) {
+           pollfds[j].fd = i;
+           pollfds[j].events |= POLLOUT;
+       }
+       if (efds && FD_ISSET(i, efds)) {
+           pollfds[j].fd = i;
+           /* one always gets notified of exceptions */
+       }
+       if (pollfds[j].fd == i)
+           j ++;
+                       
+    }
+
+    if (rfds) FD_ZERO(rfds);
+    if (wfds) FD_ZERO(wfds);
+    if (efds) FD_ZERO(efds);
+
+    if (secs != 0 && secs != NOTOK)
+       secs *= 1000;
+
+again:
+    n = poll (pollfds, (unsigned long)j, secs);
+    if (n == NOTOK) {
+       if (errno == EAGAIN)
+           goto again;
+       if (errno != EINTR)
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("poll"));
+       return NOTOK;
+    }
+
+    for (i = 0; i < j; i++) {
+       if (rfds && (pollfds[i].revents & (POLLIN | POLLPRI)))
+           FD_SET (pollfds[i].fd, rfds);
+       if (wfds && (pollfds[i].revents & POLLOUT))
+           FD_SET (pollfds[i].fd, wfds);
+       if (efds && (pollfds[i].revents & (POLLERR | POLLHUP | POLLNVAL)))
+           FD_SET (pollfds[i].fd, efds);
+    }
+    return n;
+}
+
+#endif
+
+/* \f */
+
+/* This routine used to be used for devices that didn't support real select.
+   Those devices are no longer supported.
+
+   Instead the routine is used to check if an I/O abstraction has some data
+   buffered in user-space for reading...
+ */
+
+static IFP     sfnx[FD_SETSIZE] = { NULL };
+static caddr_t sdata[FD_SETSIZE] = { NULL };
+
+
+IFP    set_check_fd (fd, fnx, data)
+int    fd;
+IFP    fnx;
+caddr_t        data;
+{
+    IFP            ofnx;
+
+    if (fd < 0 || fd >= FD_SETSIZE)
+       return NULLIFP;
+
+    ofnx = sfnx[fd];
+    sfnx[fd] = fnx, sdata[fd] = data;
+
+    return ofnx;
+}
+
+/* \f */
+
+int    xselect (nfds, rfds, wfds, efds, secs)
+int    nfds;
+fd_set *rfds,
+       *wfds,
+       *efds;
+int    secs;
+{
+    register int    fd;
+    int            n;
+    fd_set  ifds,
+           ofds,
+           xfds;
+    static int nsysfds = NOTOK;
+
+    if (nsysfds == NOTOK)
+       nsysfds = getdtablesize ();
+    if (nfds > FD_SETSIZE)
+       nfds = FD_SETSIZE;
+    if (nfds > nsysfds + 1)
+       nfds = nsysfds + 1;
+
+    FD_ZERO (&ifds);
+    n = 0;
+
+    for (fd = 0; fd < nfds; fd++)
+       if (sfnx[fd] != NULLIFP
+               && rfds
+               && FD_ISSET (fd, rfds)
+               && (*sfnx[fd]) (fd, sdata[fd]) == DONE) {
+           FD_SET (fd, &ifds);
+           n++;
+       }
+
+    if (n > 0) {
+       *rfds = ifds;   /* struct copy */
+       if (wfds)
+           FD_ZERO (wfds);
+       if (efds)
+           FD_ZERO (efds);
+       
+       return n;
+    }
+
+    if (rfds)
+       ifds = *rfds;   /* struct copy */
+    if (wfds)
+       ofds = *wfds;   /* struct copy */
+    if (efds)
+       xfds = *efds;   /* struct copy */
+
+    if ((n = selsocket (nfds, rfds, wfds, efds, secs)) != NOTOK)
+       return n;
+
+    if (errno == EBADF) {
+       struct stat st;
+
+       if (rfds)
+           FD_ZERO (rfds);
+       if (wfds)
+           FD_ZERO (wfds);
+       if (efds)
+           FD_ZERO (efds);
+
+       n = 0;
+       for (fd = 0; fd < nfds; fd++)
+           if (((rfds && FD_ISSET (fd, &ifds))
+                       || (wfds && FD_ISSET (fd, &ofds))
+                       || (efds && FD_ISSET (fd, &xfds)))
+                   && fstat (fd, &st) == NOTOK) {
+               if (rfds && FD_ISSET (fd, &ifds))
+                   FD_SET (fd, rfds);
+               if (wfds && FD_ISSET (fd, &ofds))
+                   FD_SET (fd, wfds);
+               if (efds && FD_ISSET (fd, &xfds))
+                   FD_SET (fd, efds);
+
+               SLOG (compat_log, LLOG_EXCEPTIONS, "",
+                     ("fd %d has gone bad", fd));
+               n++;
+           }
+
+       if (n)
+           return n;
+
+       errno = EBADF;
+    }
+
+    return NOTOK;
+}
diff --git a/src/isode/compat/serror.c b/src/isode/compat/serror.c
new file mode 100644 (file)
index 0000000..e757942
--- /dev/null
@@ -0,0 +1,61 @@
+/* serror.c - get system error */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:06  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:35  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:34  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:10  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f   DATA */
+
+extern int sys_nerr;
+extern  char *sys_errlist[];
+
+/* \f */
+
+char   *sys_errname (i)
+int    i;
+{
+    static char buffer[30];
+
+    if (0 < i && i < sys_nerr)
+       return sys_errlist[i];
+    (void) sprintf (buffer, "Error %d", i);
+
+    return buffer;
+}
diff --git a/src/isode/compat/servbyname.c b/src/isode/compat/servbyname.c
new file mode 100644 (file)
index 0000000..1b8be30
--- /dev/null
@@ -0,0 +1,76 @@
+/* servbyname.c - getisoserventbyname */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:09  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:37  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:36  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:10  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+/* \f */
+
+struct isoservent *getisoserventbyname (entity, provider)
+char *entity,
+     *provider;
+{
+    register struct isoservent *is;
+
+    isodetailor (NULLCP, 0);
+    DLOG (addr_log, LLOG_TRACE,
+         ("getisoserventbyname \"%s\" \"%s\"", entity, provider));
+
+    (void) setisoservent (0);
+    while (is = getisoservent ())
+       if (strcmp (entity, is -> is_entity) == 0
+               && strcmp (provider, is -> is_provider) == 0)
+           break;
+    (void) endisoservent ();
+
+    if (is) {
+#ifdef DEBUG
+       if (addr_log -> ll_events & LLOG_DEBUG)
+           _printsrv (is);
+#endif
+    }
+    else
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("lookup of local service %s/%s failed", provider, entity));
+
+    return is;
+}
diff --git a/src/isode/compat/servbyport.c b/src/isode/compat/servbyport.c
new file mode 100644 (file)
index 0000000..9beb333
--- /dev/null
@@ -0,0 +1,79 @@
+/* servbyport.c - getisoserventbyport */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:11  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:39  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:38  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:11  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoservent.h"
+#include "tailor.h"
+#include "internet.h"
+
+/* \f */
+
+struct isoservent *getisoserventbyport (provider, port)
+char   *provider;
+unsigned short port;
+{
+    register struct isoservent *is;
+
+    isodetailor (NULLCP, 0);
+    DLOG (addr_log, LLOG_TRACE,
+          ("getisoserventbyport \"%s\" %d", provider, (int) ntohs (port)));
+
+    (void) setisoservent (0);
+    while (is = getisoservent ())
+       if (sizeof (port) == is -> is_selectlen
+               && port == is -> is_port
+               && strcmp (provider, is -> is_provider) == 0)
+           break;
+    (void) endisoservent ();
+
+    if (is) {
+#ifdef DEBUG
+       if (addr_log -> ll_events & LLOG_DEBUG)
+           _printsrv (is);
+#endif
+    }
+    else
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("lookup of local service %s/%d failed",
+              provider, (int) ntohs (port)));
+
+    return is;
+}
diff --git a/src/isode/compat/servbysel.c b/src/isode/compat/servbysel.c
new file mode 100644 (file)
index 0000000..bda1f15
--- /dev/null
@@ -0,0 +1,80 @@
+/* servbysel.c - getisoserventbyselector */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:12  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:41  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:41  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:11  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+/* \f */
+
+struct isoservent *getisoserventbyselector (provider, selector, selectlen)
+char   *provider,
+       *selector;
+int    selectlen;
+{
+    register struct isoservent *is;
+
+    isodetailor (NULLCP, 0);
+    DLOG (addr_log, LLOG_TRACE,
+          ("getisoserventbyselector \"%s\" %s",
+           provider, sel2str (selector, selectlen, 1)));
+
+    (void) setisoservent (0);
+    while (is = getisoservent ())
+       if (selectlen == is -> is_selectlen
+               && bcmp (selector, is -> is_selector, is -> is_selectlen) == 0
+               && strcmp (provider, is -> is_provider) == 0)
+           break;
+    (void) endisoservent ();
+
+    if (is) {
+#ifdef DEBUG
+       if (addr_log -> ll_events & LLOG_DEBUG)
+           _printsrv (is);
+#endif
+    }
+    else
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("lookup of local service %s %s failed",
+              provider, sel2str (selector, selectlen, 1)));
+
+    return is;
+}
diff --git a/src/isode/compat/signals.c b/src/isode/compat/signals.c
new file mode 100644 (file)
index 0000000..7c4d3bb
--- /dev/null
@@ -0,0 +1,151 @@
+/* signals.c - signal handling */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:14  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:43  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:42  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:12  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <signal.h>
+#ifndef        BADSIG
+#define        BADSIG  ((SFP) -1)
+#endif
+#include "manifest.h"
+
+/* \f */
+
+int    _iosignals_set = 0;
+
+/* \f   Berkeley UNIX: 4.2 */
+
+#ifndef        XOS_2
+#ifdef BSDSIGS
+
+/* Simply including <signal.h> is sufficient for everything but AIX */
+
+#ifdef AIX             /* #define'd to be _signal */
+IFP    signal (sig, func)
+int    sig;
+IFP    func;
+{
+    struct sigvec   sv1,
+                   sv2;
+
+    sv1.sv_handler = func;
+    sv1.sv_mask = sv1.sv_onstack = 0;
+    return (sigvec (sig, &sv1, &sv2) != NOTOK ? sv2.sv_handler : BADSIG);
+}
+#endif
+
+#else
+
+/* \f   AT&T UNIX: 5 */
+
+
+/* Probably a race condition or two in this code */
+
+
+static int blocked = 0;
+static int pending = 0;
+
+static SFP handler[NSIG];
+
+static SFD sigser (sig)
+int    sig;
+{
+    (void) signal (sig, sigser);
+
+    pending |= sigmask (sig);
+}
+
+/* \f */
+#ifndef SVR4_UCB
+
+int    sigblock (mask)
+int    mask;
+{
+    register int    sig,
+                    smask;
+    long    omask = blocked;
+
+    if (mask == 0)
+       return blocked;
+
+    for (sig = 1, smask = sigmask (sig); sig < NSIG; sig++, smask <<= 1)
+       if ((smask & mask) && !(smask & blocked)) {
+           pending &= ~smask;
+           handler[sig] = signal (sig, sigser);
+           blocked |= smask;
+       }
+
+    return omask;
+}
+
+#ifdef linux
+sigset_t       sigsetmask (mask)
+#else
+int    sigsetmask (mask)
+#endif
+int    mask;
+{
+    register int    sig,
+                    smask;
+    long    omask = blocked;
+
+    for (sig = 1, smask = sigmask (sig); sig < NSIG; sig++, smask <<= 1)
+       if (smask & mask) {
+           if (smask & blocked)
+               continue;
+
+           pending &= ~smask;
+           handler[sig] = signal (sig, sigser);
+           blocked |= smask;
+       }
+       else
+           if (smask & blocked) {
+               blocked &= ~smask;
+               (void) signal (sig, handler[sig] != BADSIG ? handler[sig]
+                       : SIG_DFL);
+               if (smask & pending) {
+                   pending &= ~smask;
+                   (void) kill (getpid (), sig);
+               }
+           }
+
+    return omask;
+}
+
+#endif
+#endif
+#endif
diff --git a/src/isode/compat/smalloc.c b/src/isode/compat/smalloc.c
new file mode 100644 (file)
index 0000000..fbd471a
--- /dev/null
@@ -0,0 +1,60 @@
+/* smalloc.c - error checking malloc */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:16  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:44  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:44  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:12  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f */
+
+char *
+smalloc(size)
+int    size;
+{
+       register char *ptr;
+
+       if ((ptr = malloc((unsigned) size)) == NULL){
+           LLOG (compat_log,LLOG_FATAL, ("malloc() failure"));
+           abort ();
+           /* NOTREACHED */
+       }
+
+       return(ptr);
+}
diff --git a/src/isode/compat/sprintb.c b/src/isode/compat/sprintb.c
new file mode 100644 (file)
index 0000000..b1c4136
--- /dev/null
@@ -0,0 +1,77 @@
+/* sprintb.c - sprintf on bits */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:18  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:46  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:46  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:13  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+
+/* \f */
+
+char  *sprintb (v, bits)
+register int   v;
+register char  *bits;
+{
+    register int    i,
+                    j;
+    register char   c,
+                   *bp;
+    static char buffer[BUFSIZ];
+
+    (void) sprintf (buffer, bits && *bits == 010 ? "0%o" : "0x%x", v);
+    bp = buffer + strlen (buffer);
+
+    if (bits && *++bits) {
+       j = 0;
+       *bp++ = '<';
+       while (i = *bits++)
+           if (v & (1 << (i - 1))) {
+               if (j++)
+                   *bp++ = ',';
+               for (; (c = *bits) > 32; bits++)
+                   *bp++ = c;
+           }
+           else
+               for (; *bits > 32; bits++)
+                   continue;
+       *bp++ = '>';
+       *bp = NULL;
+    }
+
+    return buffer;
+}
diff --git a/src/isode/compat/sstr2arg.c b/src/isode/compat/sstr2arg.c
new file mode 100644 (file)
index 0000000..d52c379
--- /dev/null
@@ -0,0 +1,164 @@
+/* sstr2arg: convert string into argument list */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:48  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:47  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:13  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "manifest.h"
+#include "general.h"
+#include <errno.h>
+extern int errno;
+
+/* \f */
+
+/*
+   stash a pointer to each field into the passed array. any common seperators
+   split the words.  extra white-space between fields is ignored.
+
+   specially-interpreted characters:
+       double-quote, backslash (preceding a special char with a backslash
+       removes its interpretation.  A backslash not followed by a special is
+       used to preface an octal specification for one character a string begun
+       with double-quote has only double-quote and backslash as special
+       characters.
+
+*/
+
+
+
+
+sstr2arg (srcptr, maxpf, argv, dlmstr)
+register char *srcptr;  /* source data */
+int maxpf;              /* maximum number of permitted fields */
+char *argv[];           /* where to put the pointers */
+char *dlmstr;           /* Delimiting character */
+{
+    char gotquote;             /* currently parsing quoted string */
+    register int ind;
+    register char *destptr;
+    char idex[256];
+
+    if (srcptr == 0)
+       return (NOTOK);
+
+    bzero (idex, sizeof idex);
+    for (destptr = dlmstr; *destptr; destptr++)
+       idex[*destptr] = 1;
+
+    for (ind = 0, maxpf -= 2;; ind++) {
+       if (ind >= maxpf) 
+           return (NOTOK);
+
+       /* Skip leading white space */
+       for (; *srcptr == ' ' || *srcptr == '\t'; srcptr++);
+
+       argv [ind] = srcptr;
+       destptr = srcptr;
+
+       for (gotquote = 0; ; ) {
+
+           if (idex[*srcptr])
+           {
+               if (gotquote) { /* don't interpret the char */
+                   *destptr++ = *srcptr++;
+                   continue;
+               }
+
+               srcptr++;
+               *destptr = '\0';
+               goto nextarg;
+           } else {
+               switch (*srcptr) {
+               default:        /* just copy it                     */
+                   *destptr++ = *srcptr++;
+                   break;
+
+               case '\"':      /* beginning or end of string       */
+                   gotquote = (gotquote) ? 0 : 1 ;
+                   srcptr++;   /* just toggle */
+                   break;
+
+               case '\\':      /* quote next character     */
+                   srcptr++;   /* skip the back-slash      */
+                   switch (*srcptr) {
+                       /* Octal character          */
+                   case '0': case '1':
+                   case '2': case '3': 
+                   case '4': case '5':
+                   case '6': case '7': 
+                       *destptr = '\0';
+                       do
+                           *destptr = (*destptr << 3) | (*srcptr++ - '0');
+                       while (*srcptr >= '0' && *srcptr <= '7');
+                       destptr++;
+                       break;
+                       /* C escape char            */
+                   case 'b':
+                       *destptr++ = '\b';
+                       srcptr++;
+                       break;
+                   case 'n':
+                       *destptr++ = '\n';
+                       srcptr++;
+                       break;
+                   case 'r':
+                       *destptr++ = '\r';
+                       srcptr++;
+                       break;
+                   case 't':
+                       *destptr++ = '\t';
+                       srcptr++;
+                       break;
+                                               
+                       /* Boring -- just copy ASIS */
+                   default:
+                       *destptr++ = *srcptr++;
+                   }
+                   break;
+
+               case '\0':
+                   *destptr = '\0';
+                   ind++;
+                   argv[ind] = (char *) 0;
+                   return (ind);
+               }
+           }
+       }
+    nextarg:
+       continue;
+    }
+}
diff --git a/src/isode/compat/str2elem.c b/src/isode/compat/str2elem.c
new file mode 100644 (file)
index 0000000..b0858ec
--- /dev/null
@@ -0,0 +1,71 @@
+/* str2elem.c - string to list of integers */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:27  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:50  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:49  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:14  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+
+/* \f */
+
+int    str2elem (s, elements)
+char   *s;
+unsigned int elements[];
+{
+    register int    i;
+    register unsigned int  *ip;
+    register char  *cp,
+                   *dp;
+
+    ip = elements, i = 0;
+    for (cp = s; *cp && i <= NELEM; cp = ++dp) {
+       for (dp = cp; isdigit ((u_char) *dp); dp++)
+           continue;
+       if ((cp == dp) || (*dp && *dp != '.'))
+           break;
+       *ip++ = (unsigned int) atoi (cp), i++;
+       if (*dp == NULL)
+           break;
+    }
+    if (*dp || i >= NELEM)
+       return NOTOK;
+    *ip = 0;
+
+    return i;
+}
diff --git a/src/isode/compat/str2saddr.c b/src/isode/compat/str2saddr.c
new file mode 100644 (file)
index 0000000..f5f9971
--- /dev/null
@@ -0,0 +1,56 @@
+/* str2saddr.c - string value to SSAPaddr */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:29  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:52  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:51  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:16  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f */
+
+struct SSAPaddr *str2saddr (str)
+char   *str;
+{
+    register struct PSAPaddr *pa;
+
+    if (pa = str2paddr (str))
+       return (&pa -> pa_addr);
+
+    return NULLSA;
+}
diff --git a/src/isode/compat/str2sel.c b/src/isode/compat/str2sel.c
new file mode 100644 (file)
index 0000000..b8089f6
--- /dev/null
@@ -0,0 +1,135 @@
+/* str2sel.c - string to selector */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:31  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:54  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.2  1994/06/06 19:51:31  eichin
+ * NULL is not a char
+ *
+ * Revision 1.1  1994/05/31 20:34:52  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:18  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+
+#define        QUOTE   '\\'
+
+/* \f   STR2SEL */
+
+int    str2sel (s, quoted, sel, n)
+char   *s,
+       *sel;
+int    quoted,
+       n;
+{
+    int     i,
+            r;
+    register char  *cp;
+
+    if (*s == NULL)
+       return 0;
+
+    if (quoted <= 0) {
+       for (cp = s; *cp; cp++)
+           if (!isxdigit ((u_char) *cp))
+               break;
+
+       if (*cp == NULL && (i = (cp - s)) >= 2 && (i & 0x01) == 0) {
+           if (i > (r = n * 2))
+               i = r;
+           i = implode ((u_char *) sel, s, i);
+           if ((r = (n - i)) > 0)
+               bzero (sel + i, r);
+           return i;
+       }
+       if (*s == '#') {        /* gosip style, network byte-order */
+           i = atoi (s + 1);
+           sel[0] = (i >> 8) & 0xff;
+           sel[1] = i & 0xff;
+
+           return 2;
+       }
+
+       DLOG (compat_log, LLOG_EXCEPTIONS, ("invalid selector \"%s\"", s));
+    }
+
+    for (cp = sel; *s && n > 0; cp++, s++, n--)
+       if (*s != QUOTE)
+           *cp = *s;
+       else
+           switch (*++s) {
+               case 'b':
+                   *cp = '\b';
+                   break;
+               case 'f':
+                   *cp = '\f';
+                   break;
+               case 'n':
+                   *cp = '\n';
+                   break;
+               case 'r':
+                   *cp = '\r';
+                   break;
+               case 't':
+                   *cp = '\t';
+                   break;
+
+               case 0:
+                   s--;
+               case QUOTE: 
+                   *cp = QUOTE;
+                   break;
+
+               default: 
+                   if (!isdigit ((u_char) *s)) {
+                       *cp++ = QUOTE;
+                       *cp = *s;
+                       break;
+                   }
+                   r = *s != '0' ? 10 : 8;
+                   for (i = 0; isdigit ((u_char) *s); s++)
+                       i = i * r + *s - '0';
+                   s--;
+                   *cp = toascii (i);
+                   break;
+           }
+    if (n > 0)
+       *cp = NULL;
+
+    return (cp - sel);
+}
diff --git a/src/isode/compat/str2taddr.c b/src/isode/compat/str2taddr.c
new file mode 100644 (file)
index 0000000..63fdd29
--- /dev/null
@@ -0,0 +1,56 @@
+/* str2taddr.c - string value to TSAPaddr */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:33  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:56  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:54  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:18  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f */
+
+struct TSAPaddr *str2taddr (str)
+char   *str;
+{
+    register struct PSAPaddr *pa;
+
+    if (pa = str2paddr (str))
+       return (&pa -> pa_addr.sa_addr);
+
+    return NULLTA;
+}
diff --git a/src/isode/compat/str2vec.c b/src/isode/compat/str2vec.c
new file mode 100644 (file)
index 0000000..93dfa82
--- /dev/null
@@ -0,0 +1,105 @@
+/* str2vec.c - string to vector */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:35  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:16:58  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:56  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:19  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+
+
+#define        QUOTE   '\\'
+
+/* \f */
+
+int    str2vecX (s, vec, nmask, mask, brk, docomma)
+register char  *s,
+             **vec,
+               brk;
+int    nmask,
+       *mask,
+       docomma;
+{
+    register int    i;
+    char    comma = docomma ? ',' : ' ';
+
+    if (mask)
+       *mask = 0;
+
+    for (i = 0; i <= NVEC;) {
+       vec[i] = NULL;
+       if (brk > 0) {
+           if (i > 0 && *s == brk)
+               *s++ = NULL;
+       }
+       else
+           while (isspace ((u_char) *s) || *s == comma)
+               *s++ = NULL;
+       if (*s == NULL)
+           break;
+
+       if (*s == '"') {
+           if (i < nmask)
+               *mask |= 1 << i;
+           for (vec[i++] = ++s; *s != NULL && *s != '"'; s++)
+               if (*s == QUOTE) {
+                   if (*++s == '"')
+                       (void) strcpy (s - 1, s);
+                   s--;
+               }
+           if (*s == '"')
+               *s++ = NULL;
+           continue;
+       }
+       if (*s == QUOTE && *++s != '"')
+           s--;
+       vec[i++] = s;
+
+       if (brk > 0) {
+           if (*s != brk)
+               for (s++; *s != NULL && *s != brk; s++)
+                   continue;
+       }
+       else
+           for (s++; *s != NULL && !isspace ((u_char) *s) && *s != comma; s++)
+               continue;
+    }
+    vec[i] = NULL;
+
+    return i;
+}
diff --git a/src/isode/compat/strdup.c b/src/isode/compat/strdup.c
new file mode 100644 (file)
index 0000000..736396b
--- /dev/null
@@ -0,0 +1,69 @@
+/* strdup.c - create a duplicate copy of the given string */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:37  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:00  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:57  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:19  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f */
+#if (!defined(SVR4) && !defined(linux))
+
+char   *strdup (str)
+register char   *str;
+{
+       register char *ptr;
+
+       if ((ptr = malloc((unsigned) (strlen (str) + 1))) == NULL){
+           LLOG (compat_log,LLOG_FATAL, ("strdup malloc() failure"));
+           abort ();
+           /* NOTREACHED */
+       }
+
+       (void) strcpy (ptr, str);
+
+       return ptr;
+}
+
+#else
+
+strdup_stub ()
+{;}
+
+#endif
diff --git a/src/isode/compat/sunlink.c b/src/isode/compat/sunlink.c
new file mode 100644 (file)
index 0000000..493e967
--- /dev/null
@@ -0,0 +1,683 @@
+/* sunlink.c - X.25 abstractions for SunLink X25 */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by John Pavel, Department of Trade and Industry/National
+ * Physical Laboratory in the UK
+ * much hacked my others since then - i.e., don't blame John!
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:39  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:02  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:34:59  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:20  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "tailor.h"
+
+/* \f   SUN UNIX: SunLink X25 */
+
+#ifdef  X25
+
+#include "x25.h"
+#include "isoaddrs.h"
+
+#ifdef  SUN_X25
+
+#define CALLING 0
+#define CALLED  1
+#define        PROBE   (-1)
+
+/* \f */
+
+#ifdef  DEBUG
+void    print_x25_facilities ();
+static int  log_x25_facilities ();
+#endif
+
+/* \f */
+
+/* ARGSUSED */
+
+int     start_x25_client (local, priv)
+struct  NSAPaddr *local;
+int     priv;
+{
+    int     sd;
+
+    if ((sd = socket (AF_X25, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK;
+    }
+
+    return sd;
+}
+
+/* \f */
+
+int     start_x25_server (local, backlog, opt1, opt2)
+struct  NSAPaddr *local;
+int     backlog,
+       opt1,
+       opt2;
+{
+    CONN_DB     sbuf,
+               xbuf;
+    CONN_DB     *sock = &sbuf,
+               *xs = &xbuf;
+    int     sd, onoff;
+
+    if ((sd = socket (AF_X25, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK;
+    }
+
+    onoff = 0;
+    if (ioctl (sd, X25_CALL_ACPT_APPROVAL, (char *) &onoff) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+             ("X25_CALL_ACPT_APPROVAL"));
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+
+#ifdef AEF_NSAP
+    if (local -> na_stack == NA_NSAP) {
+       FACILITY f;
+
+       f.type = T_CALLED_AEF;
+       if (nsap2if (local, &f.f_called_aef) == NOTOK)
+           return NOTOK;
+       if (ioctl (sd, X25_SET_FACILITY, &f) == NOTOK)
+           return NOTOK;
+       bzero ((char *)xs, sizeof *xs);
+       if (bind (sd, (struct sockaddr *)xs, sizeof *xs) == NOTOK) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+           (void) close_x25_socket (sd);
+           return NOTOK;
+       }
+    }
+    else {
+#endif
+       if (ioctl (sd, X25_RD_HOSTADR, (char *) xs) == NOTOK) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_HOSTADR"));
+           (void) close_x25_socket (sd);
+           return NOTOK;
+       }
+       /* if null DTE in /etc/x25params
+          then ALWAYS use null DTE for
+          listen if PID is specified */
+       if (xs -> hostlen == 0 && local -> na_pidlen > 0) {
+           if (local -> na_pidlen > NPSIZE)
+               local -> na_pidlen = NPSIZE;
+           *sock = *xs;        /* struct copy */
+           bzero((char *) sock -> data, NPSIZE);
+           bcopy (local -> na_pid, (char *) sock -> data, local -> na_pidlen);
+           bcopy (local -> na_cudf, (char *) sock -> data + NPSIZE,
+                  local -> na_cudflen);
+           sock -> datalen = local -> na_pidlen + local -> na_cudflen;
+       }
+       else
+           sock = gen2if(local, sock, ADDR_LISTEN);
+
+       /* Adopt the convention that if a null DTE is given,
+          we should get the one from /etc/x25params */
+       if(!local->na_dtelen) {
+           /* Now set the generic local address */
+           local = if2gen(local, xs, ADDR_LOCAL);
+           /* Modified by INRIA to avoid a null local address */
+           if (!local->na_dtelen) {
+               local->na_dtelen = 1;
+               local->na_dte[0] = '0';
+           }
+       }
+       if (bind (sd, (struct sockaddr *) sock, sizeof(CONN_DB)) == NOTOK) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+           (void) close_x25_socket (sd);
+           return NOTOK;
+       }
+#ifdef AEF_NSAP
+    }
+#endif
+
+#ifndef        BSD43
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
+#else
+    onoff = 1;
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
+#endif
+
+    if (set_x25_facilities(sd, CALLED, "Acceptable") == NOTOK) {
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+
+    (void) listen (sd, backlog);
+
+    return sd;
+}
+
+/* \f */
+
+int     join_x25_server (fd, remote)
+register int fd;
+register struct NSAPaddr *remote;
+{
+    CONN_DB sbuf;
+    CONN_DB *sock = &sbuf;
+    register int nfd;
+
+    if ((sock = gen2if (remote, sock, ADDR_REMOTE)) == NULL)
+       return NOTOK;
+
+    if (set_x25_facilities(fd, CALLING, "Proposed") == NOTOK)
+       return NOTOK;
+#ifdef ANY_LINK
+    sock -> hostlen |= ANY_LINK;
+#endif
+#ifdef AEF_NONE /* sunnet 7.0 or > */
+
+    /*
+     * For sunnet 7.0 - if we have a real nsap then use that. The
+     * X121 should be filled in as NULL.
+     */
+
+    if (remote -> na_stack == NA_NSAP) {
+       FACILITY f;
+       f.type = T_CALLED_AEF;
+       if (nsap2if (remote, &f.f_called_aef) == NOTOK)
+           return NOTOK;
+       if (ioctl (fd, X25_SET_FACILITY, &f) == NOTOK)
+           return NOTOK;
+    }
+#endif
+    if ((nfd = connect (fd, (struct sockaddr *)sock, sizeof (CONN_DB)))
+           == NOTOK) {
+       if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+           (void) log_cause_and_diag(fd);      /* Sun's documentation throwns
+                                                  no light as to whether, or
+                                                  not this will result in any
+                                                  useful information */
+    }
+#ifdef  DEBUG
+    else
+       if (compat_log -> ll_events & LLOG_DEBUG)
+           (void) log_x25_facilities(fd, CALLING, "Effective Calling");
+#endif
+
+    return nfd;
+}
+
+/* \f */
+
+int     join_x25_client (fd, remote)
+int     fd;
+struct  NSAPaddr *remote;
+{
+    CONN_DB     sbuf;
+    CONN_DB     *sock = &sbuf;
+    int     len = sizeof *sock;
+    int     nfd;
+#ifdef AEF_NSAP
+    FACILITY f;
+#endif
+
+    if ((nfd = accept (fd, (struct sockaddr *) sock, &len)) == NOTOK) {
+       if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+           (void) log_cause_and_diag(fd);      /* Sun's documentation throwns
+                                                  no light as to whether, or
+                                                  not this will result in any
+                                                  useful information */
+    }
+#ifdef  DEBUG
+    else
+        if (compat_log -> ll_events & LLOG_DEBUG)
+            (void) log_x25_facilities(fd, CALLED, "Effective Called");
+#endif
+    if (nfd < 0) return nfd;
+
+    /* May also need to send call accept packet if using
+     * FAST_ACPT_CLR, or X25_CALL_ACPT_APPROVAL
+     * there was a SUNLINK bug in this area
+     *
+     * May as well try it -- if it fails, so what ??
+     */
+    if (ioctl(nfd,X25_SEND_CALL_ACPT, NULLCP) < 0)
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("X25_SEND_CALL_ACPT"));
+
+#ifdef AEF_NONE /* sunnet 7.0 or > */
+
+    /*
+     * For sunnet 7.0 - see if we have a real nsap and use that.
+     */
+
+    f.type = T_CALLING_AEF;
+    if (ioctl (nfd, X25_GET_FACILITY, &f) == NOTOK ||
+       if2nsap (&f.f_calling_aef, remote) == NOTOK)
+#endif
+    
+    remote = if2gen (remote, sock, ADDR_REMOTE);
+
+    return nfd;
+}
+
+/* \f */
+
+/* There is a bug whereby if the thruput is set, calls fail. pb@cl.cam.ac.uk */
+
+int    sun_fixed_thruput = 0;
+
+/* Set up X.25 Facilities.  Note that setting even one value causes
+   the default (/etc/x25params) values to be set explicitly on the
+   call request (and probably also call accept).  This can screw
+   things up, if your /etc/x25params has not been properly
+   localised as is normally the case.  */
+
+/* ARGSUSED */
+int     set_x25_facilities(sd, coc, caption)
+int     sd, coc;
+char *caption;
+{
+    FACILITY_DB facilities;
+
+    bzero ((char *) &facilities, sizeof facilities);
+
+    if (coc != CALLED
+           && ioctl (sd, X25_RD_FACILITY, (char *) &facilities) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_FACILITY"));
+       return NOTOK;
+    }
+
+    if (coc == PROBE
+           || !(coc == CALLED
+                   || reverse_charge   || recvpktsize || sendpktsize
+                   || recvwndsize      || sendwndsize || recvthruput
+                   || sendthruput      || cug_req  /* || cug_index */
+                   || fast_select_type || rpoa_req /* || rpoa */)) {
+       if (facilities.recvpktsize)
+           recvpktsize = facilities.recvpktsize;
+       if (facilities.sendpktsize)
+           sendpktsize = facilities.sendpktsize;
+
+       return OK;
+    }
+
+    if (reverse_charge)
+       facilities.reverse_charge = reverse_charge;
+    if (recvpktsize)
+       facilities.recvpktsize = recvpktsize;
+    if (sendpktsize)
+       facilities.sendpktsize = sendpktsize;
+    if (recvwndsize)
+       facilities.recvwndsize = recvwndsize;
+    if (sendwndsize)
+       facilities.sendwndsize = sendwndsize;
+    if (sun_fixed_thruput) {   /* get round Sun bug */
+       if (recvthruput)
+           facilities.recvthruput = recvthruput;
+       if (sendthruput)
+           facilities.sendthruput = sendthruput;
+    }
+    else
+       facilities.recvthruput = facilities.sendthruput = 0;
+    if (cug_req)
+       facilities.cug_req = cug_req;
+    if (cug_index)
+       facilities.cug_index = cug_index;
+    if (fast_select_type)
+       facilities.fast_select_type = fast_select_type;
+      /* May as well accept FCS calls */
+    else
+       if (coc == CALLED)
+           facilities.fast_select_type = FAST_ACPT_CLR;
+    if (rpoa_req)
+       facilities.rpoa_req = rpoa_req;
+    if (rpoa)
+       facilities.rpoa = rpoa;
+
+#undef DO_NOT_USE_FACILITIES
+#ifndef DO_NOT_USE_FACILITIES
+#ifdef  DEBUG
+    if (compat_log -> ll_events & LLOG_DEBUG)
+       print_x25_facilities (facilities, coc, caption);
+#endif
+
+    if (ioctl (sd, X25_WR_FACILITY, (char *) &facilities) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("X25_WR_FACILITY"));
+       return NOTOK;
+    }
+#endif
+
+#ifdef notyet
+    if (facilities.recvpktsize)
+       recvpktsize = facilities.recvpktsize;
+    if (facilities.sendpktsize)
+       sendpktsize = facilities.sendpktsize;
+#endif
+
+    return OK;
+}
+
+/* \f */
+
+int     log_cause_and_diag(fd)
+int fd;
+{
+    X25_CAUSE_DIAG      diag;
+
+    if (ioctl(fd, X25_RD_CAUSE_DIAG, (char *) &diag) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_CAUSE_DIAG"));
+       return NOTOK;
+    }
+
+    return elucidate_x25_err ((int) diag.flags, diag.data);
+
+}
+
+/* \f */
+
+#ifdef  DEBUG
+
+static int  log_x25_facilities (fd, coc, caption)
+int     fd;
+int     coc;
+char   *caption;
+{
+    FACILITY_DB f;
+
+    if (ioctl (fd, X25_RD_FACILITY, (char *) &f) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("X25_RD_FACILITY"));
+       return NOTOK;
+    }
+
+    print_x25_facilities (f, coc, caption);
+
+    return OK;
+}
+
+/* \f */
+
+static void  print_x25_facilities (f, coc, caption)
+FACILITY_DB f;
+int     coc;
+char   *caption;
+{
+    int     baud;
+
+    DLOG (compat_log, LLOG_DEBUG, ("%s X.25 Facilities:", caption));
+
+    switch (f.reverse_charge) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ((coc == CALLED)
+                     ? "reverse charging not requested"
+                     : "reverse charging not allowed"));
+           break;
+
+       case 1:
+           DLOG (compat_log, LLOG_DEBUG, ((coc == CALLING)
+                     ? "reverse charging requested"
+                     : "reverse charging allowed"));
+           break;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid reverse_charge: %d",
+                     f.reverse_charge));
+           break;
+    }
+
+    switch (f.recvpktsize) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ("default recv packet size"));
+           break;
+
+       case 16:
+       case 32:
+       case 64:
+       case 128:
+       case 256:
+       case 512:
+       case 1024:
+           DLOG (compat_log, LLOG_DEBUG, ("recv packet size %d",
+                     f.recvpktsize));
+           break;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid recv packet size %d",
+                     f.recvpktsize));
+           break;
+    }
+
+    switch (f.sendpktsize) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ("default send packet size"));
+           break;
+
+       case 16:
+       case 32:
+       case 64:
+       case 128:
+       case 256:
+       case 512:
+       case 1024:
+           DLOG (compat_log, LLOG_DEBUG, ("send packet size %d",
+                     f.sendpktsize));
+           break;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid send packet size %d",
+                     f.sendpktsize));
+           break;
+    }
+
+    DLOG (compat_log, LLOG_DEBUG,
+         (f.recvwndsize == 0 ? "default recv window size"
+                 : 1 <= f.recvwndsize && f.recvwndsize <= 127
+                     ? "recv window size %d"
+                     : "invalid recv window size %d",
+             f.recvwndsize));
+
+    DLOG (compat_log, LLOG_DEBUG,
+         (f.sendwndsize == 0 ? "default send window size"
+                 : 1 <= f.sendwndsize && f.sendwndsize <= 127
+                     ? "send window size %d"
+                     : "invalid send window size %d",
+             f.sendwndsize));
+
+    switch (f.recvthruput) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ("default recv throughput"));
+           break;
+
+       case 3:
+           baud = 75;
+print_recv: ;
+           DLOG (compat_log, LLOG_DEBUG, ("recv throughput %dbps", baud));
+           break;
+
+       case 4:
+           baud = 150;
+           goto print_recv;
+
+       case 5:
+           baud = 300;
+           goto print_recv;
+
+       case 6:
+           baud = 600;
+           goto print_recv;
+
+       case 7:
+           baud = 1200;
+           goto print_recv;
+
+       case 8:
+           baud = 2400;
+           goto print_recv;
+
+       case 9:
+           baud = 4800;
+           goto print_recv;
+
+       case 10:
+           baud = 9600;
+           goto print_recv;
+
+       case 11:
+           baud = 19200;
+           goto print_recv;
+
+       case 12:
+           baud = 48000;
+           goto print_recv;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid recv throughput %d",
+                     f.recvthruput));
+           break;
+    }
+
+    switch (f.sendthruput) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ("default send throughput"));
+           break;
+
+       case 3:
+           baud = 75;
+print_send: ;
+           DLOG (compat_log, LLOG_DEBUG, ("send throughput %dbps", baud));
+           break;
+
+       case 4:
+           baud = 150;
+           goto print_send;
+
+       case 5:
+           baud = 300;
+           goto print_send;
+
+       case 6:
+           baud = 600;
+           goto print_send;
+
+       case 7:
+           baud = 1200;
+           goto print_send;
+
+       case 8:
+           baud = 2400;
+           goto print_send;
+
+       case 9:
+           baud = 4800;
+           goto print_send;
+
+       case 10:
+           baud = 9600;
+           goto print_send;
+
+       case 11:
+           baud = 19200;
+           goto print_send;
+
+       case 12:
+           baud = 48000;
+           goto print_send;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid send throughput %d",
+                     f.sendthruput));
+           break;
+    }
+
+    switch (f.cug_req) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ("no closed user group"));
+           break;
+
+       case 1:
+           DLOG (compat_log, LLOG_DEBUG, ("closed user group 0x%x (BCD)",
+                     f.cug_req));
+           break;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid closed user group %d",
+                     f.cug_req));
+           break;
+    }
+
+    switch (f.fast_select_type) {
+       case FAST_OFF:
+           DLOG (compat_log, LLOG_DEBUG, ("don't use fast select"));
+           break;
+
+       case FAST_CLR_ONLY:
+           DLOG (compat_log, LLOG_DEBUG, ("clear is fast select response"));
+           break;
+
+       case FAST_ACPT_CLR:
+           DLOG (compat_log, LLOG_DEBUG,
+                 ("clear or call accepted is fast select response"));
+           break;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid fast select type %d",
+                     f.fast_select_type));
+           break;
+    }
+
+    switch (f.rpoa_req) {
+       case 0:
+           DLOG (compat_log, LLOG_DEBUG, ("no RPOA transit request"));
+           break;
+
+       case 1:
+           DLOG (compat_log, LLOG_DEBUG, ("RPOA transit request 0x%x",
+                     f.rpoa_req));
+           break;
+
+       default:
+           DLOG (compat_log, LLOG_DEBUG, ("invalid RPOA transit request %d",
+                     f.rpoa_req));
+    }
+}
+#endif
+#endif
+#else
+int    _sunlink_stub () {}
+#endif
diff --git a/src/isode/compat/taddr2str.c b/src/isode/compat/taddr2str.c
new file mode 100644 (file)
index 0000000..049b2e5
--- /dev/null
@@ -0,0 +1,59 @@
+/* taddr2str.c - TSAPaddr to string value */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:41  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:04  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:35:01  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:21  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+
+/* \f */
+
+char   *taddr2str (ta)
+register struct TSAPaddr *ta;
+{
+    struct PSAPaddr pas;
+    register struct PSAPaddr *pa = &pas;
+
+    if (!ta)
+       return NULL;
+    bzero ((char *) pa, sizeof *pa);
+    pa -> pa_addr.sa_addr = *ta;       /* struct copy */
+
+    return paddr2str (pa, NULLNA);
+}
diff --git a/src/isode/compat/tailor.c b/src/isode/compat/tailor.c
new file mode 100644 (file)
index 0000000..cef583b
--- /dev/null
@@ -0,0 +1,962 @@
+/* tailor.c - ISODE tailoring */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:43  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:06  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.2  1994/06/06 19:51:33  eichin
+ * NULL is not a char
+ *
+ * Revision 1.1  1994/05/31 20:35:02  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:21  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "isoaddrs.h"
+#include "tailor.h"
+#include "internet.h"
+
+static int  events_value ();
+
+#define        SUBNET_MAX      (6 + 10)  /* maximum number of subnet entries */
+
+/* \f   DATA */
+
+struct pair {
+    char   *p_name;
+    int            p_value;
+};
+
+
+static char   *isotailor = "isotailor";
+
+
+char   *isodename = "";
+
+char   *isodebinpath = BINPATH;
+char   *isodesbinpath = SBINPATH;
+char   *isodetcpath = ETCPATH;
+char   *isodelogpath = LOGPATH;
+
+
+static struct pair ll_pairs[] = {
+    "none", LLOG_NONE,
+    "fatal", LLOG_FATAL,
+    "exceptions", LLOG_EXCEPTIONS,
+    "notice", LLOG_NOTICE,
+    "pdus", LLOG_PDUS,
+    "trace", LLOG_TRACE,
+    "debug", LLOG_DEBUG,
+    "all", LLOG_ALL,
+
+    NULL
+};
+
+static char *compatdebug = "none";
+LLog _compat_log = {
+    "%d.log", NULLCP, "compat", LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *compat_log = &_compat_log;
+
+static char *addrdebug = "none";
+LLog _addr_log = {
+    "%d.log", "addr", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *addr_log = &_addr_log;
+
+static char *tsapdebug = "none";
+LLog _tsap_log = {
+    "%d.tpkt", "tsap", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *tsap_log = &_tsap_log;
+
+static char *ssapdebug = "none";
+LLog _ssap_log = {
+    "%d.spkt", "ssap", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *ssap_log = &_ssap_log;
+
+static char *psapdebug = "none";
+LLog _psap_log = {
+    "%d.pe", NULLCP, "psap", LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *psap_log = &_psap_log;
+
+static char *psap2debug = "none";
+LLog _psap2_log = {
+    "%d.ppkt", "psap2", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *psap2_log = &_psap2_log;
+
+static char *acsapdebug = "none";
+LLog _acsap_log = {
+    "%d.acpkt", "acsap", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *acsap_log = &_acsap_log;
+
+static char *rtsapdebug = "none";
+LLog _rtsap_log = {
+    "%d.rtpkt", "rtsap", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *rtsap_log = &_rtsap_log;
+
+static char *rosapdebug = "none";
+LLog _rosap_log = {
+    "%d.ropkt", "rosap", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *rosap_log = &_rosap_log;
+
+
+#define        TS_MASK "\020\01TCP\02X25\03BRG\04TP4\05X2584"
+
+static struct pair ts_pairs[] = {
+    "tcp", TS_TCP,
+    "x25", TS_X25,
+    "x25-84", TS_X2584,
+    "bridge", TS_BRG,
+    "tp4", TS_TP4,
+    "all", TS_ALL,
+
+    NULL
+};
+
+static char *_ts_stacks = "all";
+int    ts_stacks = TS_ALL;
+
+static char *_ts_interim = "";
+struct ts_interim ts_interim[SUBNET_MAX + 1] = {
+    "realNS",  NULL,   SUBNET_REALNS,          NA_NSAP,        "",     0,
+    "Int-X25", NULL,   SUBNET_INT_X25,         NA_X25,         "",     0,
+    "Internet",        NULL,   SUBNET_INTERNET,        NA_TCP,         "",     0,
+    "Janet",   NULL,   SUBNET_DYNAMIC - 1,     NA_X25,         "",     0,
+    "localTCP", NULL,   SUBNET_DYNAMIC - 2,    NA_TCP,         "",     0,
+    "IXI",     NULL,   SUBNET_DYNAMIC - 3,     NA_X25,         "",     0,
+
+    NULL
+};
+
+static char *_ts_communities = "all";
+int    ts_communities[SUBNET_MAX + 1];
+
+static char *_ts_comm_nsap_default = "realNS";
+int    ts_comm_nsap_default = SUBNET_REALNS;
+
+static char *_ts_comm_x25_default = "Int-X25";
+int    ts_comm_x25_default = SUBNET_INT_X25;
+
+static char *_ts_comm_tcp_default = "Internet";
+int    ts_comm_tcp_default = SUBNET_INTERNET;
+
+int    tsb_communities[SUBNET_MAX + 1];
+char   *tsb_addresses[SUBNET_MAX + 1];
+static char    *_tsb_config = "";
+char   *tsb_default_address = "undefined";
+
+
+#ifdef  X25
+char    *x25_local_dte = "";
+char    *x25_local_pid = "";
+
+static char    *x25_intl_zero_str = "off";
+char     x25_intl_zero = 0;
+
+static char     *x25_strip_dnic_str = "off";
+char    x25_strip_dnic = 0;
+
+char    *x25_dnic_prefix = "";
+
+               /* 0 = don't request/allow reverse charging
+                * 1 = reverse charge request/allowed
+                */
+static char *reverse_charge_default = "0";
+u_char reverse_charge = 0;
+
+               /* 0= default recv packet size.
+                * 16, 32, 64, 128,
+                * 256, 512, 1024
+                * ( octets in decimal )
+                */
+static char *recvpktsize_default = "0";
+u_short recvpktsize = 0;
+
+               /* same as above, but for send packet size */
+static char *sendpktsize_default = "0";
+u_short sendpktsize = 0;
+
+               /* 0= default recv window size.
+                * 7, 127 ( in decimal )
+                */
+static char *recvwndsize_default = "0";
+u_char recvwndsize = 0;
+
+               /* same as above, but for send window size */
+static char *sendwndsize_default = "0";
+u_char sendwndsize = 0;
+
+               /* 0= default recv throughtput.
+                * 3= 75    8= 2400
+                * 4= 150   9= 4800
+                * 5= 300  10= 9600
+                * 6= 600  11= 19200
+                * 7= 1200 12= 48000
+                * ( bps in decimal )
+                */
+static char *recvthruput_default = "0";
+u_char recvthruput = 0;
+
+               /* same as above, but for send throughput */
+               /* 1 = use closed user group in cug_index */
+static char *sendthruput_default = "0";
+u_char sendthruput = 0;
+
+               /* 0 = no closed user group. */
+               /* 1 = use closed user group in cug_index */
+static char *cug_req_default = "0";
+u_char cug_req = 0;
+
+               /* valid when cug_req= 1.
+                * 0x00 ~ 0x99 ( closed user group in BCD)
+                */
+static char *cug_index_default = "0";
+u_char     cug_index = 0;
+
+               /* 0= don't use fast select
+                * 1= clear is fast select response
+                * 2= clear or call accepted
+                *    is fast select response
+                */
+static char *fast_select_type_default = "0";
+u_char fast_select_type = 0;
+
+               /* 0= no RPOA transit request
+                * 1= use RPOA transit request in rpoa
+                */
+static char *rpoa_req_default = "0";
+u_char rpoa_req = 0;
+
+               /* valid when rpoa_req= 1 */
+               /* 0x0000 ~ 0x9999 (RPOA transit group in BCD) */
+static char *rpoa_default = "0";
+u_short rpoa = 0;
+
+static char *x25debug = "none";
+static LLog _x25_log = {
+    "x25log", "x25", NULLCP, LLOG_NONE, LLOG_NONE, -1,
+    LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *x25_log = &_x25_log;
+
+#ifdef CAMTEC_CCL
+static char *x25_outgoing_port_str = "A";
+char    x25_outgoing_port = 'A';
+#endif
+#endif
+
+
+#ifdef BRIDGE_X25
+char    *x25_bridge_host = "x25bridge";
+char    *x25_bridge_addr = "000021000018";
+char   *x25_bridge_listen = "";
+char   *x25_bridge_pid = "";
+char   *x25_bridge_discrim = "0000";
+#endif
+
+#ifdef ULTRIX_X25
+char   *x25_default_filter = "Isode";
+char   *x25_default_template = "Default";
+char   *x25_default_class = "dte-0";
+#endif
+
+#if    defined (BRIDGE_X25) || defined (X25)
+static char *x25_bridge_port_default = "146";
+u_short x25_bridge_port = 0;
+#endif
+
+
+static char *_ses_ab_timer = "30";    /* drain for 30 seconds on ABORTs */
+int    ses_ab_timer = 30;
+
+static char *_ses_dn_timer = "30";    /* drain for 30 seconds on DISCONNECTs */
+int    ses_dn_timer = 30;
+
+static char *_ses_rf_timer = "30";    /* drain for 30 seconds on REFUSEs */
+int    ses_rf_timer = 30;
+
+
+char   ns_enabled = 0;
+static char *usens = "off";
+
+char   *ns_address = "undefined";
+
+/* \f */
+
+static struct bind {
+    char   *b_key;
+
+    char  **b_value;
+    int            b_dynamic;
+}      binds[] = {
+    "localname",       &isodename,                     0,
+    "binpath",         &isodebinpath,                  0,
+    "sbinpath",                &isodesbinpath,                 0,
+    "etcpath",         &isodetcpath,                   0,
+    "logpath",         &isodelogpath,                  0,
+
+    "compatlevel",     &compatdebug,                   0,
+    "compatfile",      &_compat_log.ll_file,           0,
+
+    "addrlevel",       &addrdebug,                     0,
+    "addrfile",                &_addr_log.ll_file,             0,
+
+    "tsaplevel",       &tsapdebug,                     0,
+    "tsapfile",                &_tsap_log.ll_file,             0,
+
+    "ssaplevel",       &ssapdebug,                     0,
+    "ssapfile",                &_ssap_log.ll_file,             0,
+
+    "psaplevel",       &psapdebug,                     0,
+    "psapfile",                &_psap_log.ll_file,             0,
+
+    "psap2level",      &psap2debug,                    0,
+    "psap2file",       &_psap2_log.ll_file,            0,
+
+    "acsaplevel",      &acsapdebug,                    0,
+    "acsapfile",       &_acsap_log.ll_file,            0,
+
+    "rtsaplevel",      &rtsapdebug,                    0,
+    "rtsapfile",       &_rtsap_log.ll_file,            0,
+
+    "rosaplevel",      &rosapdebug,                    0,
+    "rosapfile",       &_rosap_log.ll_file,            0,
+
+    "ts_stacks",       &_ts_stacks,                    0,
+    "ts_interim",      &_ts_interim,                   0,
+    "ts_communities",  &_ts_communities,               0,
+
+    "default_nsap_community", &_ts_comm_nsap_default,  0,
+    "default_x25_community", &_ts_comm_x25_default,    0,
+    "default_tcp_community", &_ts_comm_tcp_default,    0,
+
+    "tsb_communities", &_tsb_config,                   0,
+    "tsb_default_address", &tsb_default_address,       0,
+
+#ifdef  X25
+    "x25_local_dte",   &x25_local_dte,                 0,
+    "x25_local_pid",   &x25_local_pid,                 0,
+    "x25_dnic_prefix", &x25_dnic_prefix,               0,
+    "x25_intl_zero",   &x25_intl_zero_str,             0,
+    "x25_strip_dnic",  &x25_strip_dnic_str,            0,
+
+    "reverse_charge",   &reverse_charge_default,       0,
+    "recvpktsize",      &recvpktsize_default,          0,
+    "sendpktsize",      &sendpktsize_default,          0,
+    "recvwndsize",      &recvwndsize_default,          0,
+    "sendwndsize",      &sendwndsize_default,          0,
+    "recvthruput",      &recvthruput_default,          0,
+    "sendthruput",      &sendthruput_default,          0,
+    "cug_req",          &cug_req_default,              0,
+    "cug_index",        &cug_index_default,            0,
+    "fast_select_type", &fast_select_type_default,     0,
+    "rpoa_req",         &rpoa_req_default,             0,
+    "rpoa",             &rpoa_default,                 0,
+
+    "x25level",                &x25debug,                      0,
+    "x25file",         &_x25_log.ll_file,              0,
+
+#ifdef CAMTEC_CCL
+    "x25_outgoing_port",        &x25_outgoing_port_str,        0,
+#endif
+
+#ifdef ULTRIX_X25
+    "x25_default_filter",              &x25_default_filter     ,0,
+    "x25_default_template",            &x25_default_template   ,0,
+    "x25_default_class",               &x25_default_class      ,0,
+#endif
+
+#endif
+
+#ifdef BRIDGE_X25
+    "x25_bridge_host",         &x25_bridge_host,       0,
+    "x25_bridge_addr",         &x25_bridge_addr,       0,
+    "x25_bridge_listen",       &x25_bridge_listen,     0,
+    "x25_bridge_pid",          &x25_bridge_pid,        0,
+    "x25_bridge_discrim",      &x25_bridge_discrim,    0,
+#endif
+
+
+#if    defined (BRIDGE_X25) || defined (X25)
+    "x25_bridge_port",         &x25_bridge_port_default,0,
+#endif
+
+    "ses_abort_timer",         &_ses_ab_timer,         0,
+    "ses_disconnect_timer",    &_ses_dn_timer,         0,
+    "ses_refuse_timer",                &_ses_rf_timer,         0,
+
+    "ns_enable",               &usens,                 0,
+    "ns_address",              &ns_address,            0,
+
+    NULL
+};
+
+
+int    tailor_read ();
+char   *tailor_value ();
+
+/* \f */
+
+char  *isodesetailor (file)
+char  *file;
+{
+    char   *ofile = isotailor;
+
+    if ((isotailor = file) == NULLCP)
+       isotailor = "isotailor";
+
+    return ofile;
+}
+
+/* \f */
+
+void   isodetailor (myname, wantuser)
+char   *myname;
+int    wantuser;
+{
+    register char *hp,
+                 *mp;
+    char   buffer[BUFSIZ];
+    static int  inited = 0;
+
+    if (inited)
+       return;
+    inited = 1;
+
+    tsb_addresses[0] = NULL;
+
+    tailor_read (isodefile (isotailor, 0));
+
+    if (wantuser) {
+       if ((hp = getenv ("HOME")) == NULL)
+           hp = ".";
+       if (myname) {
+           if (mp = rindex (myname, '/'))
+               mp++;
+           if (mp == NULL || *mp == NULL)
+               mp = myname;
+       }
+       else
+           mp = "isode";
+       (void) sprintf (buffer, "%s/.%s_tailor", hp, mp);
+       tailor_read (buffer);
+    }
+
+    isodexport (myname);
+}
+
+/* \f */
+
+static int  tailor_read (file)
+char   *file;
+{
+    register char  *bp,
+                   *cp;
+    char    buffer[BUFSIZ];
+    register FILE *fp;
+
+    if (fp = fopen (file, "r")) {
+       while (fgets (buffer, sizeof buffer, fp)) {
+           if ((cp = index (buffer, '\n')) == NULL) {
+               (void) fprintf (stderr, "%s: line too long\n", file);
+               break;
+           }
+           *cp = NULL;
+           if (*buffer == '#' || *buffer == NULL)
+               continue;
+           if ((bp = index (buffer, ':')) == NULL) {
+               (void) fprintf (stderr, "%s: invalid syntax in \"%s\"\n",
+                        file, buffer);
+               break;
+           }
+           for (cp = bp - 1; cp >= buffer; cp--)
+               if (isspace ((u_char) *cp))
+                   *cp = NULL;
+               else
+                   break;
+
+           *bp++ = NULL;
+           while (isspace ((u_char) *bp))
+               *bp++ = NULL;
+
+           for (cp = bp + strlen (bp) - 1; cp >= bp; cp--)
+               if (isspace ((u_char) *cp))
+                   *cp = NULL;
+               else
+                   break;
+                       
+           if ((cp = tailor_value (bp))
+                    && isodesetvar (buffer, cp, 1) == NOTOK)
+               free (cp);
+       }
+
+       (void) fclose (fp);
+    }
+}
+
+/* \f */
+
+int    isodesetvar (name, value, dynamic)
+char   *name,
+       *value;
+int    dynamic;
+{
+    register struct bind   *b;
+
+    for (b = binds; b -> b_key; b++)
+       if (strcmp (b -> b_key, name) == 0) {
+           if (b -> b_dynamic && *b -> b_value)
+               free (*b -> b_value);
+           *b -> b_value = value, b -> b_dynamic = dynamic;
+           return OK;
+       }
+
+    return NOTOK;
+}
+
+/* \f */
+
+void   isodexport (myname)
+char   *myname;
+{
+    compat_log -> ll_events = events_value (ll_pairs, compatdebug, "compatlevel");
+    addr_log -> ll_events = events_value (ll_pairs, addrdebug, "addrlevel");
+    tsap_log -> ll_events = events_value (ll_pairs, tsapdebug, "tsaplevel");
+    ssap_log -> ll_events = events_value (ll_pairs, ssapdebug, "ssaplevel");
+    psap_log -> ll_events = events_value (ll_pairs, psapdebug, "psaplevel");
+    psap2_log -> ll_events = events_value (ll_pairs, psap2debug, "psap2level");
+    acsap_log -> ll_events = events_value (ll_pairs, acsapdebug, "acsaplevel");
+    rtsap_log -> ll_events = events_value (ll_pairs, rtsapdebug, "rtsaplevel");
+    rosap_log -> ll_events = events_value (ll_pairs, rosapdebug, "rosaplevel");
+#ifdef X25
+    x25_log -> ll_events = events_value (ll_pairs, x25debug, "x25level");
+#endif
+
+    ll_hdinit (compat_log, myname);
+    ll_hdinit (addr_log, myname);
+    ll_hdinit (tsap_log, myname);
+    ll_hdinit (ssap_log, myname);
+    ll_hdinit (psap_log, myname);
+    ll_hdinit (psap2_log, myname);
+    ll_hdinit (acsap_log, myname);
+    ll_hdinit (rtsap_log, myname);
+    ll_hdinit (rosap_log, myname);
+#ifdef X25
+    ll_hdinit (x25_log, myname);
+#endif
+
+    ts_stacks = events_value (ts_pairs, _ts_stacks, "ts_stacks");
+#ifndef        TCP
+    ts_stacks &= ~TS_TCP;
+#endif
+#ifndef        X25
+    ts_stacks &= ~(TS_X25|TS_X2584);
+#endif
+#ifndef        BRIDGE_X25
+    ts_stacks &= ~TS_BRG;
+#endif
+#ifndef        TP4
+    ts_stacks &= ~TS_TP4;
+#endif
+
+    {
+       register int  *ip,
+                     *jp,
+                     *kp;
+       int     j;
+       register char *cp,
+                     *adrp,
+                    **ap,
+                    **cpp;
+       register struct ts_interim *ts;
+       static struct ts_interim *te = NULL;
+       char    buffer[BUFSIZ],
+              *vec[NVEC + NSLACK + 1];
+
+       if (te)
+           te -> ts_name = NULL;
+       for (ts = ts_interim; ts -> ts_name; ts++)
+           if (macro2comm (ts -> ts_name, ts) == NOTOK)
+               (void) fprintf (stderr, "internal error for community \"%s\"\n",
+                        ts -> ts_name);
+       if (te == NULL)
+           te = ts;
+
+       (void) strcpy (buffer, _ts_interim);
+       (void) str2vec (buffer, ap = vec);
+       j = SUBNET_DYNAMIC;
+       while (cp = *ap++) {
+           register struct ts_interim *tp;
+
+           ts -> ts_subnet = 0;
+           if (macro2comm (cp, ts) == NOTOK) {
+               (void) fprintf (stderr, "invalid community name \"%s\"\n", cp);
+               break;
+           }
+           for (tp = ts_interim; tp < ts; tp++)
+               if (tp -> ts_length == ts -> ts_length
+                       && bcmp (tp -> ts_prefix, ts -> ts_prefix,
+                                tp -> ts_length) == 0) {
+                   (void) fprintf (stderr,
+                            "duplicate prefixes for communities \"%s\" and \"%s\"\n",
+                            tp -> ts_name, cp);
+                   break;
+               }
+           if (tp < ts)
+               continue;
+
+           ts -> ts_name = strdup (cp);
+           if (ts -> ts_subnet == 0)
+               ts -> ts_subnet = j++;
+           ts++;
+       }
+       ts -> ts_name = NULL;
+
+       (void) strcpy (buffer, _ts_communities);
+       (void) str2vec (buffer, ap = vec);
+       ip = ts_communities;
+       while (cp = *ap++) {
+           if (strcmp (cp, "all") == 0) {
+               for (ts = ts_interim; ts -> ts_name; ts++) {
+                   for (jp = ts_communities; jp < ip; jp++)
+                       if (*jp == ts -> ts_subnet)
+                           break;
+                   if (jp >= ip)
+                       *ip++ = ts -> ts_subnet;
+               }
+               break;
+           }
+
+           for (ts = ts_interim; ts -> ts_name; ts++)
+               if (lexequ (ts -> ts_name, cp) == 0)
+                   break;
+           if (!ts -> ts_name) {
+               (void) fprintf (stderr,
+                        "unknown community name \"%s\" for variable ts_communities\n",
+                        cp);
+               continue;
+           }
+
+           for (jp = ts_communities; jp < ip; jp++)
+               if (*jp == ts -> ts_subnet)
+                   break;
+           if (jp >= ip)
+               *ip++ = ts -> ts_subnet;
+       }
+       *ip = NULL;
+
+       for (ap = tsb_addresses; *ap; ap++)
+           free (*ap);
+       (void) strcpy (buffer, _tsb_config);
+       (void) str2vec (buffer, ap = vec);
+       ip = tsb_communities, cpp = tsb_addresses;
+       while (cp = *ap++) {
+           if ((adrp = *ap++) == NULLCP) {
+               (void) fprintf (stderr,
+                        "missing address for tsb_community \"%s\"\n", cp);
+               break;
+           }
+
+           for (ts = ts_interim; ts -> ts_name; ts++)
+               if (lexequ (ts -> ts_name, cp) == 0)
+                   break;
+           if (!ts -> ts_name) {
+               (void) fprintf (stderr,
+                        "unknown community name \"%s\" for variable tsb_communities\n",
+                        cp);
+               continue;
+           }
+
+           for (jp = tsb_communities; jp < ip; jp++)
+               if (*jp == ts -> ts_subnet)
+                   break;
+           if (jp >= ip) {
+               *ip++ = ts -> ts_subnet, *cpp++ = strdup (adrp);
+
+               for (kp = ts_communities; *kp; kp++)
+                   if (*kp == ts -> ts_subnet)
+                       break;
+               if (!*kp)
+                   *kp++ = ts -> ts_subnet, *kp = NULL;
+           }
+       }
+       *ip = NULL, *cpp = NULLCP;
+
+       cp = _ts_comm_nsap_default;
+       for (ts = ts_interim; ts -> ts_name; ts++)
+           if (lexequ (ts -> ts_name, cp) == 0)
+               break;
+       if (ts -> ts_name && ts -> ts_syntax == NA_NSAP)
+           ts_comm_nsap_default = ts -> ts_subnet;
+       else
+           (void) fprintf (stderr,
+                    "bad community name \"%s\" for variable default_nsap_community\n",
+                    cp);
+
+       cp = _ts_comm_x25_default;
+       for (ts = ts_interim; ts -> ts_name; ts++)
+           if (lexequ (ts -> ts_name, cp) == 0)
+               break;
+       if (ts -> ts_name && ts -> ts_syntax == NA_X25)
+           ts_comm_x25_default = ts -> ts_subnet;
+       else
+           (void) fprintf (stderr,
+                    "bad community name \"%s\" for variable default_x25_community\n",
+                    cp);
+
+       cp = _ts_comm_tcp_default;
+       for (ts = ts_interim; ts -> ts_name; ts++)
+           if (lexequ (ts -> ts_name, cp) == 0)
+               break;
+       if (ts -> ts_name && ts -> ts_syntax == NA_TCP)
+           ts_comm_tcp_default = ts -> ts_subnet;
+       else
+           (void) fprintf (stderr,
+                    "bad community name \"%s\" for variable default_tcp_community\n",
+                    cp);
+
+       if (addr_log -> ll_events & LLOG_DEBUG) {
+           LLOG (addr_log, LLOG_DEBUG,
+                 ("ts_stacks: %s", sprintb (ts_stacks, TS_MASK)));
+
+           for (ts = ts_interim; ts -> ts_name; ts++) {
+               LLOG (addr_log, LLOG_DEBUG,
+                     ("community %s value \"%s\" subnet %d syntax %d",
+                      ts -> ts_name, ts -> ts_value ? ts -> ts_value : "",
+                      ts -> ts_subnet, ts -> ts_syntax));
+               buffer[explode(buffer, (u_char *) ts -> ts_prefix,
+                              ts -> ts_length)] = NULL;
+               LLOG (addr_log, LLOG_DEBUG,
+                     ("    prefix \"%s\" (%d octets)", buffer,
+                      ts -> ts_length));
+           }
+
+           for (ip = ts_communities; *ip; ip++)
+               LLOG (addr_log, LLOG_DEBUG, ("community %d enabled", *ip));
+
+           LLOG (addr_log, LLOG_DEBUG,
+                 ("default communities: nsap=%d x25=%d tcp=%d",
+                  ts_comm_nsap_default, ts_comm_x25_default,
+                  ts_comm_tcp_default));
+
+           for (ip = tsb_communities, cpp = tsb_addresses; *ip; ip++, cpp++) {
+               LLOG (addr_log, LLOG_DEBUG,
+                     ("TSB for community %d residing at %s", *ip, *cpp));
+               if (str2taddr (*cpp) == NULLTA)
+                   LLOG (addr_log, LLOG_EXCEPTIONS,
+                         ("invalid address for TSB to community %d: %s",
+                          *ip, *cpp));
+           }
+       }
+    }
+
+#ifdef X25
+    reverse_charge = (u_char) atoi (reverse_charge_default);
+    recvpktsize = (u_short) atoi (recvpktsize_default);
+    sendpktsize = (u_short) atoi (sendpktsize_default);
+    recvwndsize = (u_char) atoi (recvwndsize_default);
+    sendwndsize = (u_char) atoi (sendwndsize_default);
+    recvthruput = (u_char) atoi (recvthruput_default);
+    sendthruput = (u_char) atoi (sendthruput_default);
+    cug_req = (u_char) atoi (cug_req_default);
+    cug_index = (u_char) atoi (cug_index_default);
+    fast_select_type = (u_char) atoi (fast_select_type_default);
+    rpoa_req = atoi (rpoa_req_default);
+    rpoa = (u_short) atoi (rpoa_default);
+
+#ifdef CAMTEC_CCL
+    x25_outgoing_port = *x25_outgoing_port_str;
+#endif
+
+    x25_intl_zero = !strcmp (x25_intl_zero_str, "on");
+    x25_strip_dnic =  !strcmp (x25_strip_dnic_str, "on");
+#endif
+
+#if    defined (BRIDGE_X25) || defined (X25)
+    x25_bridge_port = htons ((u_short) atoi (x25_bridge_port_default));
+#endif
+
+    ns_enabled = !strcmp (usens, "on");
+}
+
+/* \f */
+
+#define        QUOTE   '\\'
+
+
+static char *tailor_value (s)
+register char   *s;
+{
+    register int    i,
+                    r;
+    register char  *bp;
+    char    buffer[BUFSIZ];
+
+    for (bp = buffer; *s; bp++, s++)
+       if (*s != QUOTE)
+           *bp = *s;
+       else
+           switch (*++s) {
+               case '0':
+                   *bp = '\0';
+                   break;
+               case 'b':
+                   *bp = '\b';
+                   break;
+               case 'f':
+                   *bp = '\f';
+                   break;
+               case 'n':
+                   *bp = '\n';
+                   break;
+               case 'r':
+                   *bp = '\r';
+                   break;
+               case 't':
+                   *bp = '\t';
+                   break;
+
+               case 0: s--;
+               case QUOTE: 
+                   *bp = QUOTE;
+                   break;
+
+               default: 
+                   if (!isdigit ((u_char) *s)) {
+                       *bp++ = QUOTE;
+                       *bp = *s;
+                       break;
+                   }
+                   r = *s != '0' ? 10 : 8;
+                   for (i = 0; isdigit ((u_char) *s); s++)
+                       i = i * r + *s - '0';
+                   s--;
+                   *bp = toascii (i);
+                   break;
+           }
+    *bp = NULL;
+
+    if ((bp = malloc ((unsigned) (strlen (buffer) + 1))) != NULL)
+       (void) strcpy (bp, buffer);
+
+    return bp;
+}
+
+/* \f */
+
+static int  events_value (pairs, s, var)
+struct pair *pairs;
+char   *s,
+       *var;
+{
+    int     value;
+    register char  *cp,
+                  **ap;
+    register struct pair   *pp;
+    char    buffer[BUFSIZ],
+          *vec[NVEC + NSLACK + 1];
+
+    value = 0;
+    (void) strcpy (buffer, s);
+    (void) str2vec (buffer, ap = vec);
+    while (cp = *ap++) {
+       for (pp = pairs; pp -> p_name; pp++) 
+           if (strcmp (pp -> p_name, cp) == 0) {
+               value |= pp -> p_value;
+               break;
+           }
+       if (!pp -> p_name)
+           (void) fprintf (stderr, "unknown value \"%s\" for variable %s\n",
+                    cp, var);
+    }
+
+    return value;
+}
+
+/* \f */
+
+#ifdef PEP_TEST
+tailorfree () {
+    register struct bind   *b;
+
+    for (b = binds; b -> b_key; b++)
+       if (b -> b_dynamic && *b -> b_value) {
+           free (*b -> b_value);
+           *b -> b_value = NULL;
+       }
+
+    ll_hdfree (compat_log);
+    ll_hdfree (addr_log);
+    ll_hdfree (tsap_log);
+    ll_hdfree (ssap_log);
+    ll_hdfree (psap_log);
+    ll_hdfree (psap2_log);
+    ll_hdfree (acsap_log);
+    ll_hdfree (rtsap_log);
+    ll_hdfree (rosap_log);
+#ifdef X25
+    ll_hdfree (x25_log);
+#endif
+
+    free_macros ();
+    free_bp ();
+    free_oid ();
+}
+
+
+ll_hdfree (lp)
+register LLog *lp;
+{
+    if (lp -> ll_stat & LLOGHDR)
+        free (lp -> ll_hdr);
+    lp -> ll_stat &= ~LLOGHDR;
+}
+#endif
diff --git a/src/isode/compat/ubcx25.c b/src/isode/compat/ubcx25.c
new file mode 100644 (file)
index 0000000..cdabf65
--- /dev/null
@@ -0,0 +1,320 @@
+/* ubcx25.c - X.25 abstractions for UBC X25 */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by Julian Onions, Nottingham University in the UK
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:45  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:08  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:35:04  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:22  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+#include "tpkt.h"
+
+/* \f   4.[23] UNIX: UBC X25 */
+
+#ifdef  X25
+#ifdef  UBC_X25
+
+#include "x25.h"
+#include <sys/uio.h>
+
+#define         X25_MBIT        0x40
+#define         X25_QBIT        0x80
+
+/* \f */
+
+int     start_x25_client (local)
+struct NSAPaddr *local;
+{
+    int     sd, pgrp;
+
+    if (local != NULLNA)
+       local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+    if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    return sd;
+}
+
+/* \f */
+
+int     start_x25_server (local, backlog, opt1, opt2)
+struct NSAPaddr *local;
+int     backlog,
+       opt1,
+       opt2;
+{
+    int     sd, pgrp;
+#ifdef notyet
+#ifdef BSD43
+    int            onoff;
+#endif
+#endif
+    CONN_DB     zsck;
+    CONN_DB     *sck = &zsck;
+
+    if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+       return NOTOK; /* Can't get an X.25 socket */
+    }
+
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    if (local != NULLNA) {
+       local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+       if (local -> na_dtelen == 0) {
+           (void) strcpy (local -> na_dte, x25_local_dte);
+           local -> na_dtelen = strlen(x25_local_dte);
+           if (local -> na_pidlen == 0 && *x25_local_pid)
+               local -> na_pidlen =
+                   str2sel (x25_local_pid, -1, local -> na_pid, NPSIZE);
+       }
+    }
+
+    (void) gen2if (local, sck, ADDR_LISTEN);
+    if (bind (sd, sck, sizeof(CONN_DB)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+
+
+#ifdef notyet          /* not sure if these are supported... */
+#ifndef        BSD43
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
+#else
+    onoff = 1;
+    if (opt1)
+       (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
+    if (opt2)
+       (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
+#endif
+#endif
+
+    (void) listen (sd, backlog);
+
+    return sd;
+}
+
+/* \f */
+
+int     join_x25_client (fd, remote)
+int     fd;
+struct NSAPaddr *remote;
+{
+    CONN_DB     sck;
+    int     len = sizeof sck;
+    int         nfd;
+
+    if((nfd = accept (fd, (struct sockaddr *) &sck, &len)) == NOTOK)
+       return NOTOK;
+    (void) if2gen (remote, &sck, ADDR_REMOTE);
+    return nfd;
+}
+
+int     join_x25_server (fd, remote)
+int     fd;
+struct NSAPaddr *remote;
+{
+    CONN_DB zsck;
+    CONN_DB *sck = &zsck;
+
+    if (remote == NULLNA || remote -> na_stack != NA_X25)
+    {
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+             ("Invalid type na%d", remote->na_stack));
+       return NOTOK;
+    }
+    (void) gen2if (remote, sck, ADDR_REMOTE);
+    return connect (fd, sck, sizeof (CONN_DB));
+}
+
+int     read_x25_socket (fd, buffer, len)
+int     fd, len;
+char    *buffer;
+{
+    static u_char mode;
+    static struct iovec iov[2] = {
+       (char *)&mode, 1,
+       "", 0
+    };
+    char        *p = buffer;
+    int         cc, count = 0, total = len;
+
+    do {
+       iov[1].iov_base = p;
+       iov[1].iov_len = total > X25_PACKETSIZE ? X25_PACKETSIZE : total;
+
+       switch (cc = readv (fd, iov, 2)) {
+               /*
+                * for the -1,0 & 1 cases these returns should be ok
+                * if it's the first time through, then they are valid anyway
+                * later stages means the M bit is set so there must
+                * be more data else someone is violating the
+                * protocol badly.
+                */
+
+           case NOTOK:
+           case 0:
+               return cc;
+
+           case 1:
+               SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("strange return from read_x25_socket"));
+               return NOTOK;
+
+           default:
+               cc --;          /* discount the info byte */
+               count += cc;
+               p += cc;
+               total -= cc;
+       }
+    } while (len > 0 && (mode & X25_MBIT));
+    DLOG (compat_log, LLOG_DEBUG, ("X25 read, total %d/%d", count, len));
+
+    return count;
+}
+
+#ifdef UBC_X25_WRITEV
+/* God this all very bizarre - iovecs work on read but not write!! */
+
+/*
+ * OK, this is due to a bug in UBC implementation. It may or may not
+ * be fixed in later versions. If writev allows you to write single
+ * bytes in the first vector then use this version. It's much more
+ * efficient.
+ */
+
+int     write_x25_socket (fd, buffer, len)
+int     fd, len;
+char    *buffer;
+{
+    static u_char mode;
+    static struct iovec iov[2] = {
+       (char *)&mode, 1,
+       "", 0
+       };
+    int cc;
+    char        *p = buffer;
+    int         count, total = 0;
+
+    do {
+       count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len;
+       mode = len > X25_PACKETSIZE ? X25_MBIT : 0;
+       iov[1].iov_base = p;
+       iov[1].iov_len = count;
+       switch (cc = writev (fd, iov, 2))
+       {
+           case NOTOK:
+           case 0:
+               return cc;
+
+           case 1:
+               SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("strange return from write_x25_socket"));
+               return NOTOK;
+
+           default:
+               cc --;
+               len -= cc;
+               p += cc;
+               total += cc;
+       }
+    } while (len > 0);
+    DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len));
+    return total;
+}
+#else
+int     write_x25_socket (fd, buffer, len)
+int     fd, len;
+char    *buffer;
+{
+    char        mybuffer[X25_PACKETSIZE+1];
+    char        *p = buffer;
+    int         count, total = 0;
+    int         cc;
+
+    do {
+       count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len;
+       mybuffer[0] = len > X25_PACKETSIZE ? X25_MBIT : 0;
+       bcopy (p, &mybuffer[1], count);
+       switch (cc = write (fd, mybuffer, count + 1))
+       {
+           case NOTOK:
+           case 0:
+               return cc;
+
+           case 1:
+               SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("strange return from write_x25_socket"));
+               return NOTOK;
+
+           default:
+               cc --;
+               len -= cc;
+               p += cc;
+               total += cc;
+       }
+    } while (len > 0);
+    DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len));
+    return total;
+}
+#endif
+
+#else   /* UBC_X25 */
+int     _ubcx25_stub2 () {}
+#endif  /* UBC_X25 */
+#else  /* X25 */
+int    _ubcx25_stub () {}
+#endif  /* X25 */
diff --git a/src/isode/compat/ultrix25.c b/src/isode/compat/ultrix25.c
new file mode 100644 (file)
index 0000000..47c2d4f
--- /dev/null
@@ -0,0 +1,773 @@
+/* ultrix25.c - X.25 abstractions for Ultrix X25 */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+
+/* 
+ * $Header$
+ *
+ * Contributed by George Michaelson, University of Queensland in Australia
+ *
+ *  -based on the ubcx25.c and sunlink.c modules 
+ *   by Julian Onions and John Pavel respectively,
+ *
+ *   Using the example code for the Ultrix X.25 interface 
+ *   written by DEC NAC here in Australia
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:47  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:10  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:35:06  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:23  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/* LINTLIBRARY */
+
+#include <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+#include "tpkt.h"
+
+/* \f   Ultrix: X25 */
+
+#ifdef  X25
+#ifdef  ULTRIX_X25
+
+#include "x25.h"
+
+/* are these needed george? */
+#define         X25_MBIT        0x40
+#define         X25_QBIT        0x80
+
+/*
+ * from examples/socket_incoming.c et al
+ */
+
+/*
+ * these routines in the Ultrix X.25 library do encoding and decoding
+ * of call params. They'll probably be unused, but if I get clever 
+ * enough It'd be nice to use them to build up non-standard facilities
+ * and other X.25 call stuff.
+ *
+ * I think they're varargs. should this be ansi-ized at some point???
+ */
+
+extern int X25Decode();
+extern int X25Encode();
+
+/*
+ * Definitions for Call
+ */
+
+#define CALLING        0
+#define CALLED 1
+
+#define BACKLOG        2
+#define MAXMESSAGESIZE   4096
+
+/*
+ * global structs used during decoding and encoding of call params.
+ * -these are probably way oversize.
+ */
+
+static     char        enc_buf[1024];
+static     int enc_buf_len;
+
+/* \f */
+
+int     start_x25_client (local)
+struct NSAPaddr *local;
+{
+    int     sd, pgrp;
+
+    if (local != NULLNA)
+       local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+    if ((sd = socket (AF_X25, SOCK_SEQPACKET, X25_ACCESS)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 socket()"));
+       return NOTOK; /* Error can be found in errno */
+    }
+
+    /*
+     * somebody tell me sometime why setting the process group on
+     * the socket is such a big deal. This is getting like alchemy
+     * with myself doing this 'cos its in the other fellers code...
+     * 
+     * camtec & ubc does it, sunlink doesn't.
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 ioctl(SIOCSPGRP)"));
+       return NOTOK; 
+    }
+     */
+
+    return sd;
+}
+
+/* \f */
+
+int     start_x25_server (local, backlog, opt1, opt2)
+struct NSAPaddr *local;
+int     backlog,
+       /*
+        * in Ultrix  X.25 socket functions like turn off/on packet
+        * assembly and call acceptance are done with setsockopt.
+        * it looks like other X.25 socket interfaces are using
+        * "traditional" features like SO_KEEPALIVE, and this
+        * is being passed down in the call from tsap/tsaplisten.c
+        * but I really don't think it applies here.
+        *
+        * thus, the following two arguments are ignored in this
+        * module.
+        */
+       opt1,
+       opt2;
+{
+    int     sd, pgrp;
+    CONN_DB     zsck;
+    CONN_DB     *sck = &zsck;
+    sockaddr_x25       addr;
+
+    if ((sd = socket (AF_X25, SOCK_SEQPACKET, X25_ACCESS)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 socket()"));
+       return NOTOK; /* Can't get an X.25 socket */
+    }
+
+    /*
+     * somebody tell me sometime why setting the process group on
+     * the socket is such a big deal. This is getting like alchemy
+     * with myself doing this 'cos its in the other fellers code...
+     * 
+     * camtec & ubc does it, sunlink doesn't.
+    pgrp = getpid();
+    if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 ioctl(SIOCSPGRP)"));
+       return NOTOK; 
+    }
+     */
+
+    if (local != NULLNA) {
+       local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+       if (local -> na_dtelen == 0) {
+           (void) strcpy (local -> na_dte, x25_local_dte);
+           local -> na_dtelen = strlen(x25_local_dte);
+           if (local -> na_pidlen == 0 && *x25_local_pid)
+               local -> na_pidlen =
+                   str2sel (x25_local_pid, -1, local -> na_pid, NPSIZE);
+       }
+    }
+
+    (void) gen2if (local, sck, ADDR_LISTEN);
+    /*
+     * now munge this into DEC format.
+     */
+    addr.sx25_family = AF_X25;
+    addr.sx25_flags  = 0;
+    addr.sx25_namelen = strlen(x25_default_filter);
+    strcpy(addr.sx25_name, x25_default_filter);
+
+    if (bind (sd, &addr, sizeof(addr)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 bind()"));
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+    if (listen (sd, backlog) < 0) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 listen()"));
+       (void) close_x25_socket (sd);
+       return NOTOK;
+    }
+    return sd;
+}
+
+/* \f */
+
+int     join_x25_client (fd, remote)
+int     fd;
+struct NSAPaddr *remote;
+{
+    CONN_DB            zsck;
+    CONN_DB            *sck = &zsck;
+    sockaddr_x25       filter;
+    int                        len = sizeof filter;
+    int                        stat;
+    int                nfd;
+
+    if((nfd = accept (fd, &filter, &len)) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 accept()"));
+        if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+            (void) log_call_status(fd);      /* decode useful information */
+       return NOTOK;
+    }
+    /*
+     * as well as doing a socket level accept, have to accept responsibilty
+     * for the X.25 incoming request as well...
+     */
+    enc_buf_len = sizeof(enc_buf);
+    if ((stat = getsockopt(nfd,X25_ACCESS,XSO_TAKECALL,enc_buf,&enc_buf_len) < 0 ) ) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Taking inbound X.25 Call"));
+        if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+            (void) log_call_status(fd);      /* decode useful information */
+        return NOTOK;
+    }
+#ifdef  DEBUG
+    if (compat_log -> ll_events & LLOG_DEBUG)
+        (void) print_x25_facilities(fd, CALLED, "Effective Called");
+#endif
+    /*
+     * snarf the incoming call details. could permit some local 
+     * sanityclaus checks on the X.25 guff but what the hell...
+     */
+
+    sck->na_dtelen = sizeof(sck->na_dte);
+    if ((stat = X25Decode(enc_buf, enc_buf_len, X25I_CALLINGDTE, sck->na_dte, &(sck->na_dtelen) ) ) <0 ) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Getting remote DTE"));
+        if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+            (void) log_call_status(fd);      /* decode useful information */
+        return NOTOK;
+    }
+
+    sck->na_cudflen = sizeof(sck->na_cudf);
+    if ((stat = X25Decode(enc_buf, enc_buf_len, X25I_USERDATA, sck->na_cudf, &(sck->na_cudflen) ) ) <0 ) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Getting remote CUDF"));
+        if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+            (void) log_call_status(fd);      /* decode useful information */
+        return NOTOK;
+    }
+
+    (void) if2gen (remote, sck, ADDR_REMOTE);
+
+    /*
+     * now send the poor bozo the X.25 acceptance (at last!)
+     */
+    if (setsockopt(nfd,X25_ACCESS,XSO_ACCEPTCALL,(caddr_t)0, 0) <0 ) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Sending Ultrix X.25 Connect Accept"));
+        if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+            (void) log_call_status(fd);      /* decode useful information */
+        return NOTOK;
+    }
+    return nfd;
+}
+
+int     join_x25_server (fd, remote)
+int     fd;
+struct NSAPaddr *remote;
+{
+    CONN_DB zsck;
+    CONN_DB *sck = &zsck;
+    sockaddr_x25 template;
+
+    register int nfd;
+
+    if (remote == NULLNA || remote -> na_stack != NA_X25)
+    {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+             ("Invalid type na%d", remote->na_stack));
+       return NOTOK;
+    }
+    (void) gen2if (remote, sck, ADDR_REMOTE);
+    /*
+     * now we have to re-map the generic forms of the DTE/CUDF/facil 
+     * into DECspeak using the X25Encode() call.
+     */
+    if ((enc_buf_len = X25Encode (enc_buf, 1024, X25I_NULL)) <0) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Initializing Ultrix X.25 Call Template"));
+        return NOTOK;
+    }
+    if ((enc_buf_len = X25Encode (enc_buf, 1024,
+              X25I_DTECLASS,
+              strlen(x25_default_class), x25_default_class,
+             X25I_CALLEDDTE,
+              sck->na_dtelen, sck->na_dte,
+              X25I_USERDATA,
+              sck->na_cudflen, sck->na_cudf, 
+              X25I_NULL)) < 0) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Encoding Ultrix X.25 Call Template"));
+        return NOTOK;
+    }
+    if (setsockopt(fd,X25_ACCESS,XSO_SETCONN,enc_buf,enc_buf_len) <0) { 
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Overriding Ultrix X.25 Template Values"));
+        return NOTOK;
+    }
+    template.sx25_family = AF_X25;
+    template.sx25_flags  = 0;
+    template.sx25_namelen = strlen(x25_default_template);
+    strcpy(template.sx25_name, x25_default_template);
+
+    /*
+     * poached from sunlink.c
+     */
+    if ((nfd = connect (fd, &template, sizeof (template))) == NOTOK) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("x25 connect()"));
+        if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+            (void) log_call_status(fd);      /* decode useful information */
+       return NOTOK;
+   }
+#ifdef  DEBUG
+    else
+        if (compat_log -> ll_events & LLOG_DEBUG)
+               (void) log_x25_facilities(fd, CALLING, "Effective Calling");
+#endif
+    remote = if2gen (remote, sck, ADDR_REMOTE);
+    return nfd;
+}
+
+close_x25_socket(fd)
+int    fd;
+{
+    struct     X25ClearData    cbuf;
+    struct     X25ClearData    *cdata = &cbuf;
+    int                        cbl     = sizeof(cbuf);
+    int                        stat;
+
+    cdata->clearCause = 0;             /* DTE originated */
+    cdata->clearDiagnostic = 0;                /* no additional information */
+    cdata->clearDetailsLength = 0;     /* no Clear Details information */
+
+    if ((stat = setsockopt(fd, X25_ACCESS, XSO_CLEARCALL, cdata, cbl)) < 0) {
+       if (errno != EACCES)
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed", 
+               ("x25 setsockopt(XSO_CLEARCALL)"));
+    }
+
+    log_call_status(fd);
+    close(fd);
+}
+
+log_call_status(fd)
+int    fd;
+{
+       struct  X25PortStatus   sbuf;
+       struct  X25PortStatus   *stats = &sbuf;
+       int                     sbl     = sizeof(sbuf);
+       int                     stat;
+
+       /*
+        * get X25PortStatus information
+        */
+       if ((stat = getsockopt(fd,X25_ACCESS,XSO_SHOWSTATUS,stats,&sbl) < 0)) {
+               SLOG (compat_log, LLOG_EXCEPTIONS, "failed", 
+                       ("x25 getsockopt(XSO_SHOWSTATUS)"));
+               return; 
+       }
+       switch (stats->portState) {
+       case    X25S_OPEN:
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_OPEN: No connection is in Progress."));
+               log_call_clear(fd, 0);
+               break;
+
+       case    X25S_CLEARED:
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_CLEARED: The connection has been cleared."));
+               log_call_clear(fd, 0);
+               break;
+
+       case    X25S_RUNNING:
+#ifdef DEBUG
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_RUNNING: The connection is still open."));
+               log_call_clear(fd, 0);
+#endif DEBUG
+               break;
+
+       case X25S_CALLING:         /* Connection in progress       */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_CALLING: Connection in progress."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_CALLED:          /* Call received and taken      */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_CALLED: Call received and taken."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_SYNC:            /* Unconfirmed user reset       */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_SYNC: Unconfirmed user reset."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_UNSYNC:          /* Unconfirmed reset indic      */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_UNSYNC: Unconfirmed reset indication."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_CLEARING:        /* User requested clearing      */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_CLEARING: User requested clearing."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_NOCOMM:          /* No communication with net    */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_NOCOMM: No communication with net."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_CLEARBYDIR:     /* Cleared by directive         */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_CLEARBYDIR: Cleared by directive."));
+               log_call_clear(fd, 0);
+               break;
+
+       case X25S_INCALL:          /* Untaken incoming call        */
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("X25S_INCALL: Untaken incoming call."));
+               log_call_clear(fd, 0);
+               break;
+
+       default:
+               SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+                       ("unknown return from getsockopt(XSO_SHOWSTATUS)= %d [see /usr/include/netx25/x25.h]", stats->portState));
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("restricted = %d", stats->restrictedInterface));
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("Int Msg Size = %d", stats->interruptMessageSize));
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("Data Msg Size in = %d", stats->dataMessageSizeIn));
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("Data Msg Size out = %d", stats->dataMessageSizeOut));
+               SLOG (compat_log, LLOG_DEBUG, NULLCP, 
+                       ("Error BitMap = %2x", stats->errorBitMap));
+       }
+       return;
+}
+
+log_call_clear(fd, type)
+int    fd;
+int    type;
+{
+       struct  X25ClearData    cbuf;
+       struct  X25ClearData    *cdata = &cbuf;
+       int                     cbl     = sizeof(cbuf);
+       int                     stat;
+       int                     flags;
+       unsigned char           buf[2];
+       extern  void            elucidate_x25_err();
+       char                    dbuf[128];
+       int                     dlen = sizeof(dbuf);
+
+       /*
+        * get X25ClearData information
+        */
+       if ((stat = getsockopt(fd,X25_ACCESS,XSO_CLEARDATA,cdata,&cbl) < 0) &&
+            errno != ENOMSG) {
+               SLOG (compat_log, LLOG_EXCEPTIONS, "failed", 
+                       ("x25 getsockopt(XSO_CLEARDATA)"));
+               return; 
+       }
+       if (errno == ENOMSG)
+               return;
+       /*
+        * set up argbuf to call elucidate_x25_err()
+        */
+       flags = 0;
+       flags = 1 << RECV_DIAG;         /* we have diagnostics */
+       if (type == 0)                  /*  diag type (clear/reset) */
+           flags |= 1 << DIAG_TYPE;    /* we have call clear diagnostics */
+       buf[0] = cdata->clearCause;
+       buf[1] = cdata->clearDiagnostic;
+       elucidate_x25_err(flags, buf);
+
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+               ("[Clear origin was %s]", 
+                       cdata->clearOrigin == X25R_ORIGINREMOTE ? "remote" :
+                        cdata->clearOrigin == X25R_ORIGINLOCAL ? "local" :
+                         "unknown" ));
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+               ("and %d bytes of info", cdata->clearDetailsLength));
+
+       dlen = sizeof(dbuf);
+       if ((stat = X25Decode(cdata->clearDetails, 
+                             cdata->clearDetailsLength, 
+                             X25I_CHARGEMON, 
+                             dbuf, &dlen) ) <0 ) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+                         ("X25Decode(X25I_CHARGEMON)"));
+           return;
+       }
+       if (stat > 0) 
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+               ("%*s Money Units", stat, dlen, dlen, dbuf));
+       dlen = sizeof(dbuf);
+       if ((stat = X25Decode(cdata->clearDetails, 
+                             cdata->clearDetailsLength, 
+                             X25I_CHARGESEG, 
+                             dbuf, &dlen) ) <0 ) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+                         ("X25Decode(X25I_CHARGESEG)"));
+           return;
+       }
+       if (stat > 0) 
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+               ("%*s Segments", dlen, dbuf));
+       dlen = sizeof(dbuf);
+       if ((stat = X25Decode(cdata->clearDetails, 
+                             cdata->clearDetailsLength, 
+                             X25I_CHARGETIME, 
+                             dbuf, &dlen) ) <0 ) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+                         ("X25Decode(X25I_CHARGETIME)"));
+           return;
+       }
+       if (stat > 0) 
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+               ("%*s Time Units", dlen, dbuf));
+       dlen = sizeof(dbuf);
+       if ((stat = X25Decode(cdata->clearDetails, 
+                             cdata->clearDetailsLength, 
+                             X25I_USERDATA, 
+                             dbuf, &dlen) ) <0 ) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+                         ("X25Decode(X25I_USERDATA)"));
+           return;
+       }
+       if (stat > 0) 
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, 
+               ("%d Bytes User Data", dlen));
+       return;
+}
+
+
+#ifdef  DEBUG
+
+static int  log_x25_facilities (fd, coc, caption)
+int     fd;
+int     coc;
+char   *caption;
+{
+    int        stat;
+
+    enc_buf_len = sizeof(enc_buf);
+    if (coc == CALLING) {
+        if ((stat = getsockopt(fd,
+                              X25_ACCESS,
+                              XSO_ACCEPTDETAILS,
+                              enc_buf,&enc_buf_len) < 0 ) ) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed", 
+                       ("getsockopt(XSO_ACCEPTDETAILS)"));
+           return NOTOK;
+        }
+    }
+
+    print_x25_facilities (fd, coc, caption);
+
+    return OK;
+}
+
+/* \f */
+
+void   *
+epl_prtstr (fmt, val, vallen)
+char   *fmt;
+char   *val;
+int    vallen;
+{
+       static char     abuf[128];
+       static char     tbuf[128];
+       char    *c, *d;
+
+       abuf[0] = 0;
+       if (vallen > 0) {
+           for (c = val, d = abuf; vallen; c++, vallen--) {
+               if (!isprint(*c)) {
+                   sprintf(d, " 0x%02x ", *c & 0xff);
+                   d += 6;
+               } else {
+                   sprintf(d, "%c", *c);
+                   d++;
+               }
+           }
+           *d = 0;
+       }
+       sprintf(tbuf, fmt, abuf);
+       return tbuf;
+}
+
+void   *
+epl_prtbool (fmt, val, vallen)
+char   *fmt;
+short  *val;
+int    vallen;
+{
+       static char     *true = "true";
+       static char     *false = "false";
+
+       if (*val == 0)
+               return (true);
+       else
+               return (false);
+}
+
+void   *
+epl_prtint (fmt, val, vallen)
+char   *fmt;
+short  *val;
+int    vallen;
+{
+       static char     tbuf[128];
+
+       sprintf(tbuf, fmt, *val);
+       return tbuf;
+}
+
+void   *
+epl_prtlst (fmt, val, vallen)
+char   *fmt;
+short  *val;
+int    vallen;
+{
+       static char     *list = "[LIST]";
+
+       return list;
+}
+
+static struct {
+       short   code;
+       char    type;
+#define        EPL_STR         0
+#define        EPL_BOOL        1
+#define        EPL_INT         2
+#define        EPL_LIST        3
+       char    *fmt;
+} epl_tab[] = {
+    X25I_CALLEDEXTISO,      EPL_STR,   "Address ext for dest (ISO): %s",
+    X25I_CALLEDEXTNONISO,    EPL_STR,  "Non-ISO format: %s",
+    X25I_CALLINGEXTISO,             EPL_STR,   "Address ext for target (ISO): %s",
+    X25I_CALLINGEXTNONISO,   EPL_STR,  "Non-ISO format: %s",
+    X25I_CHARGEMON,         EPL_STR,   "Call charge in monetary units: %s",
+    X25I_CHARGESEG,         EPL_STR,   "Call charge in segment counts: %s",
+    X25I_CHARGETIME,        EPL_STR,   "Call charge in elapsed time: %s",
+    X25I_CHARGEINFO,        EPL_BOOL,  "Charging information request: %s",
+    X25I_CUG,               EPL_STR,   "Closed User Group: %s",
+    X25I_ETETRANSITDELAY,    EPL_LIST, "End-to-end transit delay request: %s",
+    X25I_EXPEDITE,          EPL_BOOL,  "Interrupts allowed: %s",
+    X25I_NOEXPEDITE,        EPL_BOOL,  "Interrupts not allowed: %s",
+    X25I_FASTSELECT,        EPL_BOOL,  "Fast select facility: %s",
+    X25I_FASTSELECTRESTR,    EPL_BOOL, "Fast select restricted response : %s",
+    X25I_NONX25FACILITIES,   EPL_STR,  "Non-X.25 facilities: %s",
+    X25I_CALLINGSUBADDR,     EPL_STR,  "Calling DTE subaddress: %s",
+    X25I_MINTHRUCLSIN,      EPL_INT,   "Minimum throughput class incoming: %d",
+    X25I_MINTHRUCLSOUT,             EPL_INT,   "Minimum throughput class outgoing: %d",
+    X25I_NETUSERID,         EPL_STR,   "Network-specific user ID: %s",
+    X25I_NSAPMAP,           EPL_BOOL,  "NSAP mapping to DTE: %s",
+    X25I_PKTSIZEIN,         EPL_INT,   "Requested incoming packet size: %d",
+    X25I_PKTSIZEOUT,        EPL_INT,   "Requested outgoing packet size: %d",
+    X25I_PRIORITY,          EPL_STR,   "Connection priority: %s",
+    X25I_PROTECTION,        EPL_STR,   "Protection: %s",
+    X25I_CALLINGDTE,        EPL_STR,   "Calling DTE address: %s",
+    X25I_RPOA,              EPL_LIST,  "Specify how call is to be routed: %s",
+    X25I_THRUCLSIN,         EPL_INT,   "Maximum incoming data rate for VC: %d",
+    X25I_THRUCLSOUT,        EPL_INT,   "Maximum outgoing data rate for VC: %d",
+    X25I_TRANSITDELAY,      EPL_INT,   "Actual transit delay for our call: %d",
+    X25I_USERDATA,          EPL_STR,   "User data: %s",
+    X25I_WINSIZEIN,         EPL_INT,   "Window size for incoming call: %d",
+    X25I_WINSIZEOUT,        EPL_INT,   "Window size for outgoing call: %d",
+    X25I_DTECLASS,          EPL_STR,   "DTE class name: %s",
+    X25I_TEMPLATE,          EPL_STR,   "Template for XSO_ACCEPTCALL: %s",
+    X25I_BUFFPREALLOC,      EPL_BOOL,  "Buffer pre-allocation by gateway: %s",
+    X25I_CALLEDDTE,         EPL_STR,   "Requested DTE address: %s",
+    X25I_LOCALDTE,          EPL_STR,   "DTE receiving incoming call: %s",
+    X25I_REDIRECTREASON,     EPL_INT,  "Reason for call redirection: %d",
+    0,  0, 0,
+};
+
+print_x25_facilities (fd, coc, caption)
+int    fd;
+int     coc;
+char   *caption;
+{
+    int                numitems,stat,baud,i,j;
+    char       cbuf[128];
+    int                cbl = sizeof(cbuf);
+    char       *cptr = cbuf;
+    short      lbuf[128];
+    int                lbl;
+
+    DLOG (compat_log, LLOG_DEBUG, ("%s X.25 Facilities:", caption));
+
+    lbl = sizeof(lbuf);
+    if ((numitems = X25GetItemList(enc_buf, enc_buf_len, lbuf, &lbl)) < 0) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Getting Returned Facilities List"));
+    }
+    for (i=0;i < numitems; i++) {
+        cbl = sizeof(cbuf);
+        if ((stat = X25Decode(enc_buf, enc_buf_len, 
+                         lbuf[i], cbuf, &cbl)) < 0) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, "failed",
+              ("Getting Facility [%d] = X25I_%d", i, lbuf[i]));
+        }
+       if (stat > 0)  {
+       char    *tptr;
+           for(j=0; epl_tab[j].code != 0 && epl_tab[j].code != lbuf[i]; j++);
+           if (epl_tab[j].code == 0)
+                DLOG (compat_log, LLOG_DEBUG, ("unknown facility %d", lbuf[i]));
+           else {
+               switch (epl_tab[j].type) {
+               case EPL_STR:
+                   tptr = epl_prtstr((epl_tab[j].fmt), cptr, cbl);
+                   DLOG (compat_log, LLOG_DEBUG, ("%s", tptr));
+                   break;
+               case EPL_BOOL:
+                   tptr = epl_prtbool((epl_tab[j].fmt), (short *)cptr, cbl);
+                   DLOG (compat_log, LLOG_DEBUG, ("%s", tptr));
+                   break;
+               case EPL_INT:
+                   tptr = epl_prtint((epl_tab[j].fmt), (short *)cptr, cbl);
+                   DLOG (compat_log, LLOG_DEBUG, ("%s", tptr));
+                   break;
+               case EPL_LIST:
+                   tptr = epl_prtlst((epl_tab[j].fmt), (short *)cptr, cbl);
+                   DLOG (compat_log, LLOG_DEBUG, ("%s", tptr));
+                   break;
+               default:
+                    DLOG (compat_log, LLOG_DEBUG, 
+                         ("unknown type of EPL %d", epl_tab[j].code));
+                   break;
+               }
+           }
+        }
+    }
+    return OK;
+}
+#endif
+#else   /* ULTRIX_X25 */
+int     _ultrix25_stub2 () {;}
+#endif  /* ULTRIX_X25 */
+#else  /* X25 */
+int    _ultrix25_stub () {;}
+#endif  /* X25 */
diff --git a/src/isode/compat/version.major b/src/isode/compat/version.major
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/src/isode/compat/version.minor b/src/isode/compat/version.minor
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/src/isode/compat/x25addr.c b/src/isode/compat/x25addr.c
new file mode 100644 (file)
index 0000000..bb10a71
--- /dev/null
@@ -0,0 +1,1476 @@
+/* x25addr.c - X.25 level generic <-> interface address munging */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by George Michaelson, Julian Onions, and John Pavel
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:53  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:16  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:35:13  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:18:24  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                                NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 */
+
+/*
+ * for *really* generic address translation
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+
+#ifdef X25
+#include "tailor.h"
+#include "tpkt.h"
+#include "sys.file.h"
+#include "x25.h"
+
+#ifndef        DEBUG
+#define        DEBUG
+#endif
+
+/* \f */
+
+static int  char2bcd ();
+static int  bcd2char ();
+
+/*
+ * convert from the generic X25 structure to interface specific
+ */
+/* ARGSUSED */
+CONN_DB *gen2if (generic, specific, context)
+struct NSAPaddr *generic;
+CONN_DB         *specific;
+int             context;
+{
+    int     dtelen;
+    char    dte[NSAP_DTELEN + 1];
+#ifdef CAMTEC_CCL
+    struct iovec *iov;
+#endif
+
+    if (generic == NULLNA
+           || specific == (CONN_DB *) 0)
+       return (CONN_DB *)0;
+    if (generic -> na_stack != NA_X25) {
+#ifdef SUN_X25                 /* really NSAP specific */
+#ifdef AEF_NSAP
+       /* for suns, with sunnet 7.0 or >,
+        * if this a real NSAP, we have a NULL X121
+        * and let the routing tables do the business
+        */
+
+       if (generic -> na_stack == NA_NSAP) {
+           bzero ((char *)specific, sizeof *specific);
+           return specific;
+       }
+#endif
+#endif
+       return (CONN_DB *)0;
+    }
+
+    if (x25_dnic_prefix && *x25_dnic_prefix) {
+               /* need DNIC on local calls? */
+       register int    i;
+
+       if ( strncmp(generic -> na_dte, x25_dnic_prefix,
+           i = strlen(x25_dnic_prefix)) == 0 )
+           {
+           if (x25_strip_dnic) bcopy(generic -> na_dte + i, dte, dtelen =
+               generic -> na_dtelen - i);
+           else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen);
+           }
+       else
+           if (x25_intl_zero)
+               {
+               bcopy(generic -> na_dte, dte + 1, dtelen = generic-> na_dtelen);
+               *dte = '0', dtelen++;
+               }
+           else bcopy(generic -> na_dte, dte, dtelen = generic -> na_dtelen);
+
+    }
+    else bcopy (generic -> na_dte, dte, dtelen = generic -> na_dtelen);
+    dte[dtelen] = NULL;
+
+#ifdef SUN_X25_HACK
+       /*      
+        * If your X.25 provider expects to receive the subaddress alone
+        * on listen requests, and you are using SunLink X.25, you may need
+        * to enable SUN_X25_HACK in your config file. This will allow you
+        * to use x25_local_dte in isotailor to specify a dte mask to be
+        * stripped when listening, and thus use full DTE strings in
+        * isoentities and QUIPU EDB files. You will also have to use the 
+        * tsapd -a <dte> option to specify the listen address in
+        * /etc/rc.local and other tsapd startups since by default this equals
+        * x25_local_dte and thus will be masked to <null> unless overridden
+        * with full DTE + subaddress. 
+        */
+
+       /* 
+        * in ADDR_LISTEN context, it may be neccessary to only listen
+        * on the sub-address, because certain PTT-provided networks
+        * remove the local DTE from incoming CR packets. 
+        *
+        * SunLink X.25 listen asserts whatever DTE it is given as a simple
+        * string-compare, and will never receive inbound calls that bear
+        * only the sub-address if you assert the full DTE.
+        *
+        * this behaviour is orthogonal to any requirements to remove DNIC
+        * or add a leading 0 on outbound calls, and so needs a separate
+        * test. It uses tailor variable x25_local_dte to assert the local 
+        * DTE *without* subaddress which should be tested for and stripped 
+        * when detected. 
+        */
+
+    if ((context == ADDR_LISTEN) && x25_local_dte && *x25_local_dte) 
+       {
+       register int    i;
+
+       if ( strncmp(generic -> na_dte, x25_local_dte,
+           i = strlen(x25_local_dte)) == 0 ) 
+           {
+           bcopy(generic -> na_dte + i, dte, dtelen =
+               generic -> na_dtelen - i);
+           dte[dtelen] = NULL;
+           }
+       }
+#endif
+
+    DLOG (x25_log, LLOG_DEBUG,
+          ("gen2if %s -> %s, %d octets; PID %s",
+           generic -> na_dte, dte, dtelen,
+           sel2str (generic -> na_pid, (int) generic -> na_pidlen,1)));
+
+
+#if !defined(CAMTEC_CCL) && !defined(HPUX_X25)
+    bzero ((char *)specific, sizeof *specific);
+#endif
+
+#ifdef UBC_X25
+    if ((specific -> xaddr_len = dtelen) != 0)  {
+       bcopy (dte, specific -> xaddr_addr,
+              dtelen);
+       specific -> xaddr_len = dtelen;
+       specific -> xaddr_facilities = 0;
+       bcopy (generic -> na_pid, specific -> xaddr_proto,
+              generic -> na_pidlen);
+       bcopy (generic -> na_cudf, specific -> xaddr_userdata,
+              generic -> na_cudflen);
+    }
+#endif
+
+#ifdef HPUX_X25
+    if ((dtelen != 1) || (dte [0] != '0'))
+       bcopy (dte, specific -> addr.x25_host,
+              specific -> addr.x25hostlen = dtelen);
+
+    /* Zero PID */
+    if (generic -> na_pidlen) { /* non-null PID */
+       if (generic -> na_pidlen > NPSIZE) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("PID too long (%d > %d)", generic -> na_pidlen, NPSIZE));
+           return (CONN_DB *)0;
+       } else {
+           bzero((char *)specific -> addr.x25pid, NPSIZE);
+           bcopy (generic -> na_pid, (char *)specific -> addr.x25pid,
+                  specific -> addr.x25pidlen = generic -> na_pidlen);
+           bcopy (generic -> na_pid, (char *)specific -> cudf.x25_cu_data,
+                  specific -> cudf.x25_cud_len = generic -> na_pidlen);
+       }
+       /* copy in CUDF */
+       if (generic -> na_cudflen) {
+           if (generic -> na_cudflen + specific -> cudf.x25_cud_len > X25_MAX_C
+               U_LEN) {
+               SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("CALL-USERDATA too long (%d > %d)",
+                      generic -> na_cudflen + specific -> cudf.x25_cud_len,
+                      X25_MAX_CU_LEN));
+               return (CONN_DB *)0;
+           } else {
+               bcopy (generic -> na_cudf,
+                      &specific -> cudf.x25_cu_data [specific -> cudf.x25_cud_len]
+                      ,
+                      generic -> na_cudflen);
+               specific -> cudf.x25_cud_len += generic -> na_cudflen;
+           }
+       }
+    } else {
+       /* PID ws empty, use first four Byte of cudf */
+       /* CUDF has PID - I hope so */
+       bcopy (generic -> na_cudf, specific -> addr.x25pid,
+              specific -> addr.x25pidlen =
+              (generic -> na_cudflen <= NPSIZE) ?
+              generic -> na_cudflen : NPSIZE);
+       if (generic -> na_cudflen > X25_MAX_CU_LEN) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("CALL-USERDATA too long (%d > %d)",
+                  generic -> na_cudflen - NPSIZE, X25_MAX_CU_LEN));
+           return (CONN_DB *)0;
+       } else
+           bcopy (generic -> na_cudf, specific -> cudf.x25_cu_data,
+                  specific -> cudf.x25_cud_len = generic -> na_cudflen);
+    }
+
+#endif
+
+#ifdef SUN_X25
+    specific -> hostlen = char2bcd (dte, dtelen, specific -> host);
+
+    /* Zero PID */
+    if (generic -> na_pidlen) { /* non-null PID */
+       if (generic -> na_pidlen > NPSIZE) {
+           SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("PID too long (%d > %d)", generic -> na_pidlen, NPSIZE));
+           return (CONN_DB *)0;
+       } else {
+           bzero((char *)specific -> data, NPSIZE);
+           bcopy (generic -> na_pid, (char *)specific -> data,
+                  generic -> na_pidlen);
+           bcopy (generic -> na_cudf, (char *) specific -> data + NPSIZE,
+                  generic -> na_cudflen);
+           specific -> datalen = generic -> na_pidlen + generic -> na_cudflen;
+       }
+    } else { /* Null PID (just copy in CUDF, the first four octets of which
+               will be the PID in any case) */
+        bcopy (generic -> na_cudf, (char *)specific -> data,
+               generic -> na_cudflen);
+        specific -> datalen = generic -> na_cudflen;
+    }
+#endif
+
+#ifdef CAMTEC_CCL
+    switch (context) {
+       case ADDR_REMOTE:
+           iov = &(specific -> ccl_iovec[0]);
+           if (x25_outgoing_port == '#') {
+               char *a, *b;
+               int i;
+
+               iov -> iov_len = dtelen + 4;
+               bzero(iov -> iov_base, iov -> iov_len + 1);
+               a = iov -> iov_base;
+               b = dte;
+               *a++ = '#';
+               *a++ = '[';
+               for (i = 0; i < dtelen; i++) {
+                       if (i == 2) *a++ = ':';
+                       else if (i == 14) *a++ = ']';
+                       *a++ = *b++;
+               }
+           }
+           else {
+               iov -> iov_len = dtelen+1;
+               bcopy(dte, (iov -> iov_base)+1, dtelen);
+               *(iov -> iov_base) = x25_outgoing_port;
+           }
+           break;
+
+       case ADDR_LOCAL:
+           iov = &(specific -> ccl_iovec[0]);
+           strncpy(iov -> iov_base, generic -> na_dte, generic -> na_dtelen);
+           iov -> iov_base[generic -> na_dtelen] = '\0';
+           return (specific);
+
+       case ADDR_LISTEN:
+           iov = &(specific -> ccl_iovec[0]);
+           if (generic -> na_pidlen)
+               {                       /* listen on a PID */
+               register int i;
+               iov -> iov_base[0] = 'C';
+               bcopy(generic -> na_pid, iov -> iov_base + 1,
+                   i = generic -> na_pidlen);
+               iov -> iov_len = i + 1;
+               }
+           else
+           if (generic -> na_dtelen < 6)
+               {           /* listen on a subaddress */
+               register int i;
+               iov -> iov_base[0] = 'S';
+               bcopy(generic -> na_dte, iov -> iov_base + 1,
+                   i = generic -> na_dtelen);
+               iov -> iov_len = i + 1;
+               }
+           else    /* full DTE */
+               bcopy(dte, iov -> iov_base,
+                   iov -> iov_len = dtelen);
+           return (specific);
+    }
+    /*
+     * CUDF & PID must be merged. malloc initailly PIDsize space
+     * and bzero it. this may be UK net specific action which
+     * ensures we do NOT fall foul of listeners which use pid
+     * to match as well as "true" cudf & DTE.
+     */
+
+    (iov = &(specific -> ccl_iovec[2])) -> iov_len = 0;
+    if (generic -> na_faclen != 0)
+       bcopy (generic -> na_fac, iov -> iov_base,
+           iov -> iov_len = min( generic -> na_faclen, FACSIZE) );
+    iov++;
+    if ( (iov -> iov_len = generic -> na_pidlen) != 0)
+       bcopy (generic -> na_pid, iov -> iov_base, generic -> na_pidlen);
+
+    /*
+     * if there is any other user data add that in now...
+     * actually cudf is a variable length field so this is
+     * all very suspect.
+     */
+
+    if (generic -> na_cudflen != 0)
+       bcopy(generic -> na_cudf, iov -> iov_base + iov -> iov_len,
+           generic -> na_cudflen), iov -> iov_len += generic -> na_cudflen;
+#endif
+
+#ifdef ULTRIX_X25
+    if (generic -> na_dtelen  != 0) {
+        specific -> na_dtelen = specific -> na_pidlen 
+               = specific -> na_cudflen = 0;
+       bcopy (generic -> na_dte, 
+              specific -> na_dte, 
+              specific -> na_dtelen = generic -> na_dtelen);
+        /*
+         * concatenate PID and CUDF into CUDF buffer.
+         */
+        if (generic -> na_pidlen > 0) {
+           bcopy (generic -> na_pid, 
+                  specific -> na_cudf, 
+                  specific -> na_cudflen = generic -> na_pidlen);
+        }
+        if (generic -> na_cudflen > 0) {
+           bcopy (generic -> na_cudf, 
+                  specific -> na_cudf + specific -> na_pidlen, 
+                  generic -> na_cudflen);
+           specific -> na_cudflen += generic -> na_cudflen;
+        }
+    }
+#endif /* ULTRIX_X25 */
+    return(specific);
+}
+
+/* \f */
+
+/*
+ * convert from interface specific format to generic X.25 structure
+ */
+/* ARGSUSED */
+struct NSAPaddr *if2gen (generic, specific, context)
+struct NSAPaddr *generic;
+CONN_DB         *specific;
+int             context;
+{
+    int     dtelen;
+    char    dte[NSAP_DTELEN + 1];
+#ifdef CAMTEC_CCL
+    struct iovec *iov;
+#endif
+
+    if (generic == NULLNA || specific == (CONN_DB *) 0)
+       return NULLNA;
+    bzero ((char *)generic, sizeof *generic);
+    bzero (dte, sizeof dte);
+    dtelen = 0;
+
+    generic -> na_stack = NA_X25;
+    generic -> na_community = ts_comm_x25_default;
+
+#ifdef UBC_X25
+    if (specific -> xaddr_len  != 0) {
+       bcopy (specific -> xaddr_addr, dte, specific -> xaddr_len);
+       dtelen = specific -> xaddr_len;
+       bcopy (specific -> xaddr_proto, generic -> na_pid,
+                               sizeof(specific -> xaddr_proto));
+       generic -> na_pidlen = sizeof specific -> xaddr_proto;
+       bcopy (specific -> xaddr_userdata, generic -> na_cudf,
+                               sizeof(specific -> xaddr_userdata));
+       generic -> na_cudflen = sizeof specific -> xaddr_userdata;
+    }
+#endif
+
+#ifdef SUN_X25
+    dtelen = bcd2char (specific -> host, dte, (int) specific -> hostlen);
+
+    if (specific -> datalen > NPSIZE) { /* have some real user data after the PID */
+       bcopy((char *)specific -> data, generic -> na_pid,
+             generic -> na_pidlen = NPSIZE);
+       bcopy((char *) specific -> data + generic -> na_pidlen,
+             generic -> na_cudf,
+             generic -> na_cudflen = specific -> datalen - generic -> na_pidlen);
+    }
+    else { /* PID only */
+       bcopy((char *)specific -> data, generic -> na_pid,
+             generic -> na_pidlen = specific -> datalen);
+       generic -> na_cudflen = 0;
+    }
+
+#endif
+
+#ifdef HPUX_X25
+    if (specific -> addr.x25hostlen)
+       bcopy (specific -> addr.x25_host, dte,
+              dtelen = specific -> addr.x25hostlen);
+    else {
+       dte [0] = '0';
+       dte [1] = NULL;
+       dtelen = 1;
+    }
+
+    if (specific -> addr.x25pidlen > NPSIZE) {
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+             ("PID too long (%d > %d)", specific -> addr.x25pidlen, NPSIZE));
+       specific -> addr.x25pidlen = NPSIZE;
+    }
+    bcopy((char *)specific -> addr.x25pid, generic -> na_pid,
+         generic -> na_pidlen = specific -> addr.x25pidlen);
+
+    if (specific -> cudf.x25_cud_len) {
+       bcopy (specific -> cudf.x25_cu_data, generic -> na_cudf,
+              generic -> na_cudflen = specific -> cudf.x25_cud_len);
+    }
+#endif
+
+
+#ifdef CAMTEC_CCL
+    switch (context) {
+    case ADDR_REMOTE:
+
+       iov = &(specific -> ccl_iovec[1]);
+       if (iov -> iov_len) {
+               if (*(iov->iov_base) == '#') {
+                       char *a;
+
+                       a = iov -> iov_base;
+                       while (*a && iov -> iov_len) {
+                               if (*a == ']') {
+                                       iov -> iov_len--;
+                                       a++;
+                                       break;
+                               }
+                               iov -> iov_len--;
+                               a++;
+                       }
+                       if (*a == 0 || iov -> iov_len == 0)
+                               dtelen = 0;
+                       else {
+                               dtelen = iov -> iov_len;
+                               bcopy (a, dte, dtelen);
+                       }
+               }
+               else {
+                       dtelen = iov -> iov_len - 1;
+                       bcopy ((iov -> iov_base)+1, dte,
+                               dtelen);
+               }
+       }
+       else dtelen = 0;
+       break;
+
+    case ADDR_LOCAL:
+       iov = &(specific -> ccl_iovec[0]);
+       if (iov -> iov_len) {
+               dtelen = iov -> iov_len -1;
+               bcopy ((iov -> iov_base)+1, dte,
+                       dtelen);
+       }
+       else dtelen = 0;
+       break;
+
+    case ADDR_LISTEN:
+       return NULLNA;
+    }
+
+    if ( (iov = &(specific -> ccl_iovec[2])) -> iov_len )
+       bcopy( iov -> iov_base, generic -> na_fac,
+           generic -> na_faclen = min( iov -> iov_len, FACSIZE));
+
+    if ( ++iov -> iov_len)
+       {
+       bcopy( iov -> iov_base, generic -> na_pid,
+           generic -> na_pidlen = min( iov -> iov_len, NPSIZE));
+       if ( iov -> iov_len > NPSIZE)
+           bcopy( iov -> iov_base + NPSIZE, generic -> na_cudf,
+               generic -> na_cudflen = min(iov -> iov_len - NPSIZE, CUDFSIZE));
+       }
+#endif
+
+#ifdef ULTRIX_X25
+    if (specific -> na_dtelen  > 0) {
+       bcopy (specific -> na_dte, dte, specific -> na_dtelen);
+       dtelen = specific -> na_dtelen;
+
+       /*
+        * if CUDF non-zero, copy up to first NPSIZE (or cufdlen if less) 
+        * bytes into pid field and shift remainder down.
+        */
+       if (specific -> na_cudflen > 0) {
+           bcopy(specific -> na_cudf, 
+                 generic -> na_pid, 
+                 generic -> na_pidlen = (specific -> na_cudflen <= NPSIZE ? 
+                                         specific -> na_cudflen : NPSIZE));
+           if (specific -> na_cudflen > NPSIZE) {
+               bcopy(specific -> na_cudf + NPSIZE, 
+                     generic -> na_cudf, 
+                     generic -> na_cudflen = specific -> na_cudflen - NPSIZE);
+           }
+       } else {
+           generic -> na_pidlen = 0;
+           generic -> na_pid[0] = 0;
+           generic -> na_cudflen = 0;
+           generic -> na_cudf[0] = 0;
+       }
+    }
+#endif /* ULTRIX_X25 */
+
+    if (x25_dnic_prefix && *x25_dnic_prefix) {
+       register int    i;
+
+       i = 0;
+       if (x25_intl_zero && dte[0] == '0' && dte[1] != '0')
+           i = 1;
+       else
+           if (x25_dnic_prefix
+                   && *x25_dnic_prefix
+                   && x25_strip_dnic
+                   && dtelen < 12)   /* local call... */
+               bcopy (x25_dnic_prefix, generic -> na_dte,
+                      generic -> na_dtelen = strlen (x25_dnic_prefix));
+
+       bcopy (dte + i, generic -> na_dte + generic -> na_dtelen, dtelen - i);
+       generic -> na_dtelen += dtelen - i;
+    }
+    else
+       bcopy (dte, generic -> na_dte, generic -> na_dtelen = dtelen);
+
+    DLOG (x25_log, LLOG_DEBUG,
+          ("if2gen %s -> %s, %d octets; PID %s",
+           dte, generic -> na_dte, generic -> na_dtelen,
+           sel2str (generic -> na_pid, (int) generic -> na_pidlen,1)));
+
+    return(generic);
+}
+
+/* \f */
+
+elucidate_x25_err (flags, pkt)
+int flags;
+unsigned char * pkt;
+{
+    char * cp;
+
+    if (flags & (1 << RECV_DIAG)) {
+#ifdef HPUX_X25
+       if (flags & (1 << DIAG_TYPE)) /* cleared */
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("cleared 0x%02x", pkt[0] ));
+       else if (flags & (1 << REST_TYPE))
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("restart 0x%02x", pkt[0] ));
+       else
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("reset 0x%02x", pkt[0] ));
+
+#else
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+             (( flags & (1 << DIAG_TYPE) ) ?
+              "cleared 0x%02x" : "reset 0x%02x",
+              pkt[0] ));
+#endif
+
+       if ((flags) & (1 << DIAG_TYPE)) /* cleared */
+           switch(pkt[0]) {
+               case 0x00:
+                   cp = "DTE Clearing";
+                   break;
+
+               case 0x01:
+                   cp = "Number Busy";
+                   break;
+
+               case 0x09:
+                   cp = "Out of Order";
+                   break;
+
+               case 0x11:
+                   cp = "Remote Procedure Error";
+                   break;
+
+               case 0x19:
+                   cp = "Reverse Charging not subscribed";
+                   break;
+
+               case 0x03:
+                   cp = "Invalid Facility Request";
+                   break;
+
+               case 0x0B:
+                   cp = "Access Barred";
+                   break;
+
+               case 0x13:
+                   cp = "Local Procedure Error";
+                   break;
+
+               case 0x05:
+                   cp = "Network Congestion";
+                   break;
+
+               case 0x0D:
+                   cp = "Not Obtainable";
+                   break;
+
+               case 0x21:
+                   cp = "DTE Incompatible Call";
+                   break;
+
+               case 0x29:
+                   cp = "Fast Select Acceptance not Subscribed";
+                   break;
+
+               default:
+                   SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("clearing cause 0x2%x", pkt[0]));
+                   goto next;
+           }
+#ifdef HPUX_X25
+      else if ((flags) & (1 << REST_TYPE))
+          switch((unsigned char)(pkt[0] & 0x7f)) {
+         case 0x01:
+             cp = "Local Procedure Error";
+             break;
+
+         case 0x03:
+             cp = "Network Congestion";
+             break;
+
+         case 0x07:
+             cp = "Network Operational";
+             break;
+
+         case 0x7f:
+             cp = "Registration/Cancellation Confirmed";
+             break;
+
+         default:
+             SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                   ("restarting cause 0x2%x", pkt[0]));
+             goto next;
+          }
+#endif
+       else /* reset */
+           switch(pkt[0]) {
+               case 0x00:
+                   cp = "DTE Reset";
+                   break;
+
+               case 0x01:
+                   cp = "Out of Order (PVC Only)";
+                   break;
+
+               case 0x03:
+                   cp = "Remote Procedure Error";
+                   break;
+
+               case 0x05:
+                   cp = "Local Procedure Error";
+                   break;
+
+               case 0x07:
+                   cp = "Network Congestion";
+                   break;
+
+               case 0x09:
+                   cp = "Remote DTE Operational (PVC Only)";
+                   break;
+
+               case 0x0F:
+                   cp = "Network Operational (PVC Only";
+                   break;
+
+               default:
+                   SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                         ("resetting cause 0x%2x", pkt[0]));
+                   goto next;
+
+           }
+#ifdef HPUX_X25
+       if (flags & (1 << DIAG_TYPE)) /* cleared */
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("%sclearing cause: %s (%d)",
+                  (pkt[0] & 0x80) ? "Remote DTE " : "", cp, pkt [0]));
+       else if (flags & (1 << REST_TYPE))
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("%srestarting cause: %s (%d)",
+                  (pkt[0] & 0x80) ? "Remote DTE " : "", cp, pkt [0]));
+       else
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("%sresetting cause: %s (%d)",
+                  (pkt[0] & 0x80) ? "Remote DTE " : "", cp, pkt [0]));
+#else
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("%s%s",
+           ( flags & (1 << DIAG_TYPE) ) ? "clearing cause " :
+           "resetting cause ", cp));
+
+#endif
+
+next: ;
+       /* The following may only be applicable to PSS in the UK */
+       /* In any case, if someone is keen, they can stuff it all
+          into a text file and read it out */
+
+       switch (pkt[1]) {
+           case 0x00:
+               cp = "NO ADDITIONAL INFORMATION";
+               break;
+
+           case 0x01:
+               cp = "INVALID P(S)\tRESET";
+               break;
+
+           case 0x02:
+               cp = "INVALID P(R)\tRESET";
+               break;
+
+           case 0x11:
+               cp = "PACKET TYPE INVALID FOR STATE r1\tRESTART";
+               break;
+
+           case 0x12:
+               cp = "PACKET TYPE INVALID FOR STATE r2\tRESTART";
+               break;
+
+           case 0x13:
+               cp = "PACKET TYPE INVALID FOR STATE r3\tRESTART";
+               break;
+
+           case 0x14:
+               cp = "PACKET TYPE INVALID FOR STATE p1\tCLEAR";
+               break;
+
+           case 0x15:
+               cp = "PACKET TYPE INVALID FOR STATE p2\tCLEAR";
+               break;
+
+           case 0x16:
+               cp = "PACKET TYPE INVALID FOR STATE p3\tCLEAR";
+               break;
+
+           case 0x17:
+               cp = "PACKET TYPE INVALID FOR STATE p4\tCLEAR";
+               break;
+
+           case 0x18:
+               cp = "PACKET TYPE INVALID FOR STATE p5\tRESET";
+               break;
+
+           case 0x19:
+               cp = "PACKET TYPE INVALID FOR STATE p6\tCLEAR";
+               break;
+
+           case 0x1A:
+               cp = "PACKET TYPE INVALID FOR STATE p7\tCLEAR";
+               break;
+
+           case 0x1B:
+               cp = "PACKET TYPE INVALID FOR STATE d1\tRESET";
+               break;
+
+           case 0x1C:
+               cp = "PACKET TYPE INVALID FOR STATE d2\tRESET";
+               break;
+
+           case 0x1D:
+               cp = "PACKET TYPE INVALID FOR STATE d3\tRESET";
+               break;
+
+           case 0x20:
+               cp = "PACKET NOT ALLOWED";
+               break;
+
+           case 0x21:
+               cp = "UNIDENTIFIABLE PACKET";
+               break;
+
+           case 0x22:
+               cp = "CALL ON ONE-WAY LOGICAL CHANNEL\tCLEAR";
+               break;
+
+           case 0x23:
+               cp = "INVALID PACKET TYPE ON PVC\tRESET";
+               break;
+
+           case 0x24:
+               cp = "PACKET ON UNASSIGNED LCN\tCLEAR";
+               break;
+
+           case 0x25:
+               cp = "REJECT NOT SUBSCRIBED TO\tRESET";
+               break;
+
+           case 0x26:
+               cp = "PACKET TOO SHORT\tRESET";
+               break;
+
+           case 0x27:
+               cp = "PACKET TOO LONG\tRESET";
+               break;
+
+           case 0x28:
+               cp = "INVALID GFI\tCLEAR";
+               break;
+
+           case 0x29:
+               cp = "RESTART WITH NON-ZERO BITS 5-16";
+               break;
+
+           case 0x2A:
+               cp = "PACKET TYPE NOT COMPATIBLE WITH FACILITY\tCLEAR";
+               break;
+
+           case 0x2B:
+               cp = "UNAUTHORISED INTERRUPT CONF\tRESET";
+               break;
+
+           case 0x2C:
+               cp = "UNAUTHORISED INTERRUPT\tRESET";
+               break;
+
+           case 0x31:
+               cp = "TIMER EXPIRED;  INCOMING CALL";
+               break;
+
+           case 0x32:
+               cp = "TIMER EXPIRED;\tCLEAR INDICATION";
+               break;
+
+           case 0x33:
+               cp = "TIMER EXPIRED;\tRESET INDICATION";
+               break;
+
+           case 0x34:
+               cp = "TIMER EXPIRED;\tRESTART IND";
+               break;
+
+           case 0x40:
+               cp = "UNSPECIFIED CALL SET-UP PROBLEM CLEAR";
+               break;
+
+           case 0x41:
+               cp = "FACILITY CODE NOT ALLOWED\tCLEAR";
+               break;
+
+           case 0x42:
+               cp = "FACILITY PARAMETER NOT ALLOWED\tCLEAR";
+               break;
+
+           case 0x43:
+               cp = "INVALID CALLED ADDRESS\tCLEAR";
+               break;
+
+           case 0x44:
+               cp = "INVALID CALLING ADDRESS\tCLEAR";
+               break;
+
+           case 0x90:
+               cp = "DTE/DCE CONGESTION\tRESET";
+               break;
+
+           case 0x91:
+               cp = "RECEIVED FAST SELECT CLEAR REQUEST";
+               break;
+
+           case 0x92:
+               cp = "LINE RESTARTING BY INMC COMMAND\tRESTART";
+               break;
+
+           case 0xA0:
+#ifdef HPUX_X25
+               cp = "REVERSE CHARGE REQUESTED WHEN NOT ALLOWED - RESET";
+ #else
+               cp = "NON-ZERO RESET CAUSE FROM DTE\tRESET";
+#endif
+               break;
+
+           case 0xA1:
+#ifdef HPUX_X25
+               cp = "LEVEL 2 IS COMING UP - RESET";
+#else
+               cp = "DATA PACKET TOO LONG\tRESET";
+#endif
+               break;
+
+           case 0xA2:
+#ifdef HPUX_X25
+               cp = "LEVEL 2 OR 3 IS DOWN - RESET";
+#else
+               cp = "INTERRUPT PACKET TOO LONG\tRESET";
+#endif
+               break;
+
+           case 0xA3:
+#ifdef HPUX_X25
+               cp = "LACK OF MEMORY - RESET";
+#else
+               cp = "INT PACKET TOO SHORT; NO USER DATA\tRESET";
+#endif
+               break;
+
+           case 0xA4:
+#ifdef HPUX_X25
+               cp = "FAST SELECT NOT SUBSCRIBED - CLEAR";
+#else
+               cp = "INT CONFIRMATION PACKET TOO LONG\tRESET";
+#endif
+               break;
+
+           case 0xA5:
+               cp = "RR PACKET TOO LONG\tRESET";
+               break;
+
+           case 0xA6:
+               cp = "RNR PACKET TOO LONG\tRESET";
+               break;
+
+           case 0xA7:
+               cp = "RESET PACKET TOO LONG\tRESET";
+               break;
+
+           case 0xA8:
+               cp = "RESET CONF PACKET TOO LONG\tRESET";
+               break;
+
+           case 0xA9:
+               cp = "INVALID `Q' BIT IN DATA PACKET\tRESET";
+               break;
+
+           case 0xAA:
+               cp = "PACKET WINDOW RANGE EXCEEDED\tRESET";
+               break;
+
+           case 0xAB:
+               cp = "UNABLE TO TRANSMIT PACKET\tRESET";
+               break;
+
+           case 0xAC:
+               cp = "diagnostic `Q' BIT SET IN NON-DATA PACKET\tRESET";
+               break;
+
+           case 0xAD:
+               cp = "OUTSTANDING PACKET COUNT LESS THAN ZERO\tRESET";
+               break;
+
+           case 0xAE:
+               cp = "RETRANSMISSION ERROR\tRESET";
+               break;
+
+           case 0xAF:
+               cp = "RESET PACKET TOO SHORT (NO CAUSE)\tRESET";
+               break;
+
+           case 0xB0:
+               cp = "REJECT PACKET TOO LONG\tRESET";
+               break;
+
+           case 0xB1:
+               cp = "INVALID 1D PACKET\tRESET";
+               break;
+
+           case 0xB2:
+               cp = "UNSUCCESSFUL RECONNECTION RESNC\tCLEAR";
+               break;
+
+           case 0xB3:
+               cp = "NON-RECONNECT CALL IN STATE C1\tCLEAR";
+               break;
+
+           case 0xB4:
+               cp = "SECOND 1D PACKET FROM DTE\tCLEAR";
+               break;
+
+           case 0xB5:
+               cp = "BAD DATA TRANSFER STATE IN RECONNECT\tCLEAR";
+               break;
+
+           case 0xB6:
+               cp = "PACKET FORMAT INVALID\tCLEAR";
+               break;
+
+           case 0xB7:
+               cp = "FACILITY BYTE COUNT TOO LARGE\tCLEAR";
+               break;
+
+           case 0xB8:
+               cp = "INVALID PACKET DETECTED\tCLEAR";
+               break;
+
+           case 0xB9:
+               cp = "FACILITY/UTILITY FIELD BYTE COUNT > 63\tCLEAR";
+               break;
+
+           case 0xBA:
+               cp = "OUTGOING CALLS BARRED\tCLEAR";
+               break;
+
+           case 0xBB:
+               cp = "INCOMING CALLS BARRED\tCLEAR";
+               break;
+
+           case 0xBC:
+               cp = "CLEARING OF PVC\tCLEAR";
+               break;
+
+           case 0xBD:
+               cp = "CALLED ADDRESS TOO LONG\tCLEAR";
+               break;
+
+           case 0xBE:
+               cp = "CALLED ADDRESS TOO SHORT\tCLEAR";
+               break;
+
+           case 0xBF:
+               cp = "CALLING ADDRESS TOO LONG\tCLEAR";
+               break;
+
+           case 0xC0:
+               cp = "CALLING ADDRESS TOO SHORT\tCLEAR";
+               break;
+
+           case 0xC1:
+               cp = "BCD ERROR IN CALL ADDRESS\tCLEAR";
+               break;
+
+           case 0xC2:
+               cp = "BCD ERROR IN CALLING ADDRESS\tCLEAR";
+               break;
+
+           case 0xC3:
+               cp = "USER DATA FIELD TOO LONG\tCLEAR";
+               break;
+
+           case 0xC4:
+               cp = "NO BUFFER AVAILABLE\tCLEAR";
+               break;
+
+           case 0xC5:
+               cp = "LOCAL DTE IS NOT ENHANCED\tCLEAR";
+               break;
+
+           case 0xC6:
+               cp = "FACILITY NEGOTIATION INVALID\tCLEAR";
+               break;
+
+           case 0xC7:
+               cp = "MANDATORY UTILITY NOT INPUT\tCLEAR";
+               break;
+
+           case 0xC8:
+               cp = "BUFFER NO AVAILABLE FOR TNIC\tCLEAR";
+               break;
+
+           case 0xC9:
+               cp = "OVERFLOW OF TNIC IN BUFFER\tCLEAR";
+               break;
+
+           case 0xCA:
+               cp = "DTE LINE CONGESTED\tCLEAR";
+               break;
+
+           case 0xCB:
+               cp = "TABLE ERROR IN PACKET PROCEDURES";
+               break;
+
+           case 0xCC:
+               cp = "INSERT TABLE OVERFLOW";
+               break;
+
+           case 0xCD:
+               cp = "DELETE TABLE OVERFLOW";
+               break;
+
+           case 0xD0:
+               cp = "TRUNK LINE RESTART\tRESTART";
+               break;
+
+           case 0xD1:
+               cp = "INVALID EVENT IN STATE p2";
+               break;
+
+           case 0xD2:
+               cp = "INVALID EVENT IN STATE p3";
+               break;
+
+           case 0xD3:
+               cp = "INVALID 1D EVENT IN STATE d1";
+               break;
+
+           case 0xD4:
+               cp = "CALL COLLISION ON TRUNK LINE";
+               break;
+
+           case 0xD5:
+               cp = "NO BUFFER AVAILABLE";
+               break;
+
+           case 0xD6:
+
+               cp = "CALL COLLISION ON DTE LINE";
+               break;
+
+           case 0xD7:
+               cp = "DTE RESTART";
+               break;
+
+           case 0xD8:
+               cp = "CALL REQUEST TO TRUNK LINE TIMEOUT";
+               break;
+
+           case 0xD9:
+               cp = "RECONNECT SET-UP TIMED OUT";
+               break;
+
+           case 0xDA:
+               cp = "INVALID OUTPUT SIDE STATE";
+               break;
+
+           case 0xDB:
+               cp = "ERROR DETECTED IN BLINK PACKET QUEUE PROCEDURE";
+               break;
+
+           case 0xDC:
+               cp = "RESET INDICATION RETRANSMISSION COUNT EXPIRED";
+               break;
+
+           case 0xDD:
+               cp = "INVALID OUTPUT SIDE STATE";
+               break;
+
+           case 0xDE:
+               cp = "BLIND BUFFER QUEUE OVERFLOW IN STATE d4";
+               break;
+
+           case 0xDF:
+               cp = "BLIND BUFFER QUEUE OVERFLOW IN STATE c1";
+               break;
+
+           case 0xE0:
+               cp = "BLIND BUFFER QUEUE OVERFLOW IN STATE c2";
+               break;
+
+           case 0xE1:
+#ifdef HPUX_X25
+               cp = "DISCONNECTION (TRANSIENT CONDITION) - CLEAR";
+#else
+               cp = "CLEAR PACKET BYTE COUNT TOO LARGE OR TOO SMALL";
+#endif
+               break;
+
+           case 0xE2:
+#ifdef HPUX_X25
+               cp = "CONNECTION REJECTION (TRANSIENT CONDITION) - CLEAR";
+#else
+               cp = "NON-ZERO\tCLEAR CAUSE";
+#endif
+               break;
+
+           case 0xE3:
+               cp = "CLEAR CONF PACKET BYTE COUNT TOO SMALL OR TOO LARGE";
+               break;
+
+           case 0xE4:
+#ifdef HPUX_X25
+               cp = "CONNECTION REJECTION (REASON UNSPECIFIED) - CLEAR";
+#else
+               cp = "CALL COLLISION";
+#endif
+               break;
+
+           case 0xE5:
+               cp = "INVALID TP LOAD REQUEST CALL PKT";
+               break;
+
+           case 0xE6:
+               cp = "MAXIMUM HOPCOUNT EXCEEDED";
+               break;
+
+           case 0xE7:
+#ifdef HPUX_X25
+               cp = "NSAP UNREACHABLE (TRANSIENT CONDITION) - CLEAR";
+#else
+               cp = "ROUTING LOOP DETECTED";
+#endif
+               break;
+
+           case 0xE8:
+#ifdef HPUX_X25
+               cp = "NSAP UNREACHABLE (PERMANENT CONDITION) - CLEAR";
+#else
+               cp = "PVC CALL REQUEST FAILURE";
+#endif
+               break;
+
+           case 0xE9:
+#ifdef HPUX_X25
+               cp = "RESET CAUSE UNSPECIFIED - RESET";
+#else
+               cp = "RECONNECT CALL REQUEST FAILED";
+#endif
+               break;
+
+           case 0xEA:
+               cp = "NO LC AVAILABLE ON OUTPUT SIDE";
+               break;
+
+           case 0xEB:
+               cp = "NO BUFFER AVAILABLE";
+               break;
+
+           case 0xEC:
+               cp = "CALL REDIRECTION CLEAR";
+               break;
+
+           case 0xED:
+               cp = "NO PATH ROUTE CALL";
+               break;
+
+           case 0xEE:
+               cp = "CALL ROUTED TO DTE LINE";
+               break;
+
+           case 0xEF:
+               cp = "CALL CANNOT BE REROUTED";
+               break;
+
+           case 0xF0:
+               cp = "ADDRESS NOT IN ROUTING TABLES";
+               break;
+
+           case 0xF1:
+#ifdef HPUX_X25
+               cp = "NORMAL DISCONNECTION - CLEAR";
+#else
+               cp = "ROUTING TABLE CHANGE DURING CALL ROUTING";
+#endif
+               break;
+
+           case 0xF2:
+#ifdef HPUX_X25
+               cp = "ABNORMAL DISCONNECTION - CLEAR";
+#else
+               cp = "NO LC AVAILABLE ON FAKE TRUNK";
+#endif
+               break;
+
+           case 0xF3:
+               cp = "REMOTE DTE DOWN ON A PVC";
+               break;
+
+           case 0xF4:
+               cp = "INVALID EVENT DETECTED";
+               break;
+
+           case 0xF5:
+               cp = "INVALID PACKET RECEIVED; STATE d4";
+               break;
+
+           case 0xF6:
+               cp = "INVALID PACKET RECEIVED; STATE d5";
+               break;
+
+           case 0xF7:
+               cp = "INVALID PACKET RECEIVED; STATE p8";
+               break;
+
+           case 0xF8:
+               cp = "INTERNAL PROCESSING FAILURE";
+               break;
+
+           case 0xF9:
+               cp = "INVALID RESTART INDICATION";
+               break;
+
+           case 0xFA:
+#ifdef HPUX_X25
+               cp = "USER SYNCHRONISATION - RESET";
+#else
+               cp = "LINE STATUS CHANGE IN STATE r4";
+#endif
+               break;
+
+           case 0xFB:
+               cp = "INVALID PACKET RECEIVED; STATE r4";
+               break;
+
+           case 0xFC:
+               cp = "INVALID PACKET RECEIVED; STATE r3";
+               break;
+
+           case 0xFD:
+               cp = "LINE STATUS CHANGE IN STATE r2";
+               break;
+
+           case 0xFE:
+               cp = "LINE STATUS CHANGE IN STATE r1";
+               break;
+
+           case 0xFF:
+               cp = "LINE STATUS CHANGE IN STATE r0";
+               break;
+
+           default:
+               SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+                     ("diagnostic: 0x%2x", pkt[1]));
+               goto done;
+       }
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP, ("diagnostic %s", cp));
+#ifdef HPUX_X25
+       if (flags & (1 << DIAG_TYPE)) /* cleared */
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("clearing source: %s (%d)",
+                  pkt [2] ? "X25-Level 2" : "network prov./firmware",
+                  pkt [2] ));
+       else if (flags & (1 << REST_TYPE))
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("restart source unknown (%d)", pkt [2] ));
+       else
+           SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("resetting source: %s (%d)",
+                  pkt [2] ? "network provider" : "undefined", pkt [2] ));
+#endif
+    }
+    else        /* Not RECV_DIAG */
+#ifdef HPUX_X25
+       SLOG (x25_log, LLOG_EXCEPTIONS, NULLCP,
+             ("cause: 0x%02x - diag code: 0x%02x", pkt [0], pkt [1]));
+#else
+    if (flags)
+       SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+             ("diag flags: 0x%02x", flags));
+#endif
+
+done: ;
+    return OK;
+};
+
+/* \f */
+
+#ifdef  SUN_X25
+#ifdef AEF_NSAP
+int nsap2if (nsap, aef)
+struct NSAPaddr *nsap;
+AEF *aef;
+{
+    char buf[NASIZE*2+1];
+    int len;
+
+    if (nsap -> na_stack != NA_NSAP)
+       return NOTOK;
+    aef -> aef_type = AEF_NSAP;
+    len = explode (buf, (u_char *) nsap -> na_address, nsap -> na_addrlen);
+    aef -> aef_len = char2bcd (buf, len, aef -> aef);
+    return OK;
+}
+#endif
+
+static int  char2bcd (s, n, d)
+register char   *s;
+int n;
+register u_char *d;
+{
+    register int    c,
+                   i;
+
+    for (i = 0; *s && n-- > 0; i++) {
+       if ((c = *s++) >= 'a' && c <= 'f')
+           c -= 'a' + 0x0a;
+       else
+           if (c >= 'A' && c <= 'F')
+               c -= 'A' + 0x0a;
+           else
+               if (c >= '0' && c <= '9')
+                   c -= '0';
+               else
+                   c = 0;
+
+       if (i & 1)
+           *d++ |= c & 0xf;
+       else
+           *d = (c & 0xf) << 4;
+    }
+
+    return i;
+}
+
+/* \f */
+#ifdef AEF_NSAP
+int if2nsap (aef, nsap)
+AEF    *aef;
+struct NSAPaddr *nsap;
+{
+    char buf[NASIZE*2+1];
+    int len;
+
+    if (aef -> aef_type != AEF_NSAP)
+       return NOTOK;
+
+    nsap -> na_stack = NA_NSAP;
+    len = bcd2char (aef -> aef, buf, (int)aef -> aef_len);
+    nsap -> na_addrlen = implode ((u_char *) nsap -> na_address, buf, len);
+    return OK;
+}
+#endif
+
+static int     bcd2char (s, d, len)
+register    u_char *s;
+register char  *d;
+int     len;
+{
+    register int    i,
+                   g;
+
+    for (i = 0; i < len; i++) {
+       g = s[i >> 1];
+       if ((i & 1) == 0)
+           g >>= 4;
+       g &= 0xf;
+
+       if (g < 0x0a)
+           *d++ = g + '0';
+       else
+           *d++ = g + 'a' - 0x0a;
+    }
+
+    *d = NULL;
+
+    return len;
+}
+#endif
+#else
+int    _x25addr_stub () {}
+#endif
diff --git a/src/isode/configure.in b/src/isode/configure.in
new file mode 100644 (file)
index 0000000..2ef53dd
--- /dev/null
@@ -0,0 +1,6 @@
+AC_INIT(configure.in)
+CONFIG_DIRS(h compat psap pepsy support)
+MAKE_SUBDIRS("making",all)
+MAKE_SUBDIRS("cleaning",clean)
+CONFIG_RULES
+AC_OUTPUT(Makefile,[EXTRA_RULES])
diff --git a/src/isode/h/Makefile.in b/src/isode/h/Makefile.in
new file mode 100644 (file)
index 0000000..610ce8e
--- /dev/null
@@ -0,0 +1,92 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE header files
+###############################################################################
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+BUILDTOP = ../../
+TOPDIR = $(BUILDTOP)
+
+OPTIONS        =       -I. -I$(HDIR) $(PEPYPATH) $(KRBOPT)
+CFLAGS  =       $(OPTIONS) $(LOPTIONS) 
+
+HDIR   =       $(TOPDIR)isode/h/
+UTILDIR        =       $(TOPDIR)isode/util/
+INCDIRM        =       $(HDIR)
+INCDIR =       $(INCDIRM)/
+PEPSYDIRM=     $(INCDIR)pepsy
+PEPSYDIR=      $(PEPSYDIRM)/
+LIBISODE=      $(TOPDIR)libisode.a
+LIBDSAP        =       $(TOPDIR)libdsap.a
+
+KRBINC =       $(TOPDIR)include/
+ISODEINCM=     $(KRBINC)isode
+ISODEINC=      $(ISODEINCM)/
+
+LIBES  =       libcompat.a
+LLIBS   =
+HFILES =       $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+LN     =       ln
+
+
+###############################################################################
+#
+#                               NOTICE
+#
+#    Acquisition, use, and distribution of this module and related
+#    materials are subject to the restrictions of a license agreement.
+#    Consult the Preface in the User's Manual for the full terms of
+#    this agreement.
+#
+###############################################################################
+
+
+HEADERS        =       config.h \
+               sys.dirent.h usr.dirent.h \
+               general.h manifest.h isoaddrs.h sys.file.h \
+               internet.h x25.h tp4.h dgram.h \
+               cmd_srch.h isoservent.h logger.h tailor.h \
+               mpkt.h \
+               tpkt.h tsap.h \
+               spkt.h ssap.h \
+               pepsy.h \
+               ppkt.h psap2.h psap.h \
+               acpkt.h acsap.h \
+               rtpkt.h rtsap.h \
+               ropkt.h rosap.h \
+               ronot.h \
+               rosy.h
+
+FHEADERS=      fpkt.h ftam.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:;  -mkdir $(ISODEINCM)
+       @for h in $(HEADERS); do cp $$h $(ISODEINC)/$$h; done
+       -@echo copied $(HEADERS)
+
+inst-all:;     -mkdir $(INCDIRM)
+               @for h in $(HEADERS); do $(MAKE) TARGET=$$h inst-target; done
+
+inst-ftam:;    @for h in $(FHEADERS); do $(MAKE) TARGET=$$h inst-target; done
+
+inst-target:   $(INCDIR)$(TARGET)
+
+$(INCDIR)$(TARGET):    $(TARGET)
+               -cp $@ z$(TARGET)
+               sed -e 's%#include "\([^/]*\)"%#include "$(INCDIR)\1"%' \
+                       < $(TARGET) | \
+                       sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+               -@ls -gls $@
+               -@echo ""
+
+install:       inst-all clean
+
+lint:;
+
+clean:;                rm -f z* _*
+
+grind:;                tgrind -lc $(HEADERS)
diff --git a/src/isode/h/acpkt.h b/src/isode/h/acpkt.h
new file mode 100644 (file)
index 0000000..35ff43b
--- /dev/null
@@ -0,0 +1,327 @@
+/* acpkt.h - include file for association control providers (AcS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:28:59  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:23  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:41  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:41  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _AcSAP_
+#include "acsap.h"             /* definitions for AcS-USERs */
+#endif
+
+#ifndef        _PSAP2_
+#include "psap2.h"             /* definitions for PS-USERs */
+#endif
+
+/* \f */
+
+#ifdef ACSE
+
+#define        AC_ASN          "acse pci version 1"
+
+#if    USE_BUILTIN_OIDS
+#define AC_ASN_OID     str2oid ("2.2.1.0.1")
+#else
+#define AC_ASN_OID     ode2oid (AC_ASN)
+#endif
+
+#define        acsapPsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_OPERATION, NULLCP, \
+                           "assocation descriptor not connected"); \
+    } \
+    if (acb -> acb_flags & ACB_FINN) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_OPERATION, NULLCP, \
+                           "association descriptor finishing"); \
+    } \
+    if (acb -> acb_flags & ACB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+}
+
+#define        acsapFsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) {\
+       (void) sigiomask (smask);\
+       return acsaplose (aci, ACS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_OPERATION, NULLCP, \
+                           "assocation descriptor not connected"); \
+    } \
+    if (!(acb -> acb_flags & ACB_FINN)) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_OPERATION, NULLCP, \
+                           "association descriptor not finishing"); \
+    } \
+    if (acb -> acb_flags & ACB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return acsaplose (aci, ACS_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+}
+
+#define        toomuchP(b,n,m,p) \
+{ \
+    if (b == NULL) \
+       n = 0; \
+    else \
+       if (n > m) \
+           return acsaplose (aci, ACS_PARAMETER, NULLCP, \
+                               "too many %s user data elements", p); \
+}
+
+#ifdef __STDC__
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return acsaplose (aci, ACS_PARAMETER, NULLCP, \
+                            "mandatory parameter \"%s\" missing", #p); \
+}
+#else
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return acsaplose (aci, ACS_PARAMETER, NULLCP, \
+                           "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyAcSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyAcSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyAcSAPdata(base,len,d)       bcopy (base, (char *) d, len)
+#endif
+
+
+#define        ACS_USER_BASE   ACS_USER_NULL
+#define        ACS_PROV_BASE   ACS_PROV_NULL
+
+
+int    acpktlose (), acsaplose ();
+
+/* \f */
+
+int    ps2acslose ();
+
+struct type_ACS_Association__information *info2apdu ();
+int    apdu2info ();
+#endif
+
+/* \f */
+
+struct assocblk {
+    struct assocblk *acb_forw; /* doubly-linked list */
+    struct assocblk *acb_back; /*   .. */
+
+    int            acb_fd;             /* session/presentation descriptor */
+
+    short   acb_flags;         /* our state */
+#define        ACB_NULL        0x0000
+#define        ACB_CONN        0x0001  /* connected */
+#define        ACB_FINN        0x0002  /* other side wants to finish */
+#define        ACB_INIT        0x0004  /* this side initiated the association */
+#define        ACB_ASYN        0x0008  /* asynchronous */
+#define        ACB_TURN        0x0010  /* we have the turn */
+#define        ACB_TWA         0x0020  /* two-way alternate */
+#define        ACB_ACT         0x0040  /* activity in progress */
+#define        ACB_PLEASE      0x0080  /* RTS: RT-TURN-PLEASE received
+                                  ROS on Session: sent S-PLEASE-TOKENS */
+#define        ACB_TIMER       0x0100  /* ACTIVITY discarded due to timing
+                                  constraint */
+#define        ACB_ROS         0x0200  /* ROS started association */
+#define        ACB_RTS         0x0400  /* RTS   .. */
+#define        ACB_ACS         0x0800  /* ACS   .. */
+#define        ACB_CLOSING     0x1000  /* waiting to close */
+#define        ACB_FINISH      0x2000  /*   .. */
+#define        ACB_STICKY      0x4000  /* ROS using RTS (ugh!) */
+#define        ACB_RELEASE     0x8000  /* release in progress */
+
+    struct SSAPref acb_connect;        /* session connection reference */
+
+    int            acb_requirements;   /* session requirements */
+    int            acb_owned;          /* session tokens we own */
+    int            acb_avail;          /* session tokens available */
+    int            acb_settings;       /* initial settings */
+    int            acb_ssdusize;       /* largest atomic SSDU */
+
+    IFP            acb_uabort;         /* disconnect underlying service */
+
+/* ACSE */
+    int            acb_sversion;       /* session service version number */
+    int            acb_id;             /* ACSE context id */
+    OID            acb_context;        /* application context name */
+    int            acb_offset;         /* offset to ACSE PCI */
+                               /* negative means at END */
+    PE     acb_retry;          /* final acpkt */
+    
+/* RTSE */
+    int            acb_rtsid;          /* RTSE context id */
+    int            acb_ckpoint;        /* checkpoint size */
+    int            acb_window;         /* window size */
+    int            acb_actno;          /* sending activity serial number */
+    long    acb_ssn;           /* highest serial number sent */
+    int            acb_ack;            /* highest serial number acknowledged */
+
+    IFP            acb_pturnrequest;   /* RT-TURN-PLEASE.REQUEST */
+    IFP            acb_gturnrequest;   /* RT-TURN-GIVE.REQUEST */
+    IFP            acb_transferequest; /* RT-TRANSER.REQUEST */
+    IFP            acb_rtwaitrequest;  /* RT-WAIT.REQUEST */
+    IFP            acb_rtsetindications;/* define vectors for INDICATION events */
+    IFP            acb_rtselectmask;   /* map association descriptors for select () */
+    IFP            acb_rtpktlose;      /* protocol-level abort */
+
+    int            acb_priority;       /* priority of please turn */
+    struct AcSAPfinish acb_finish;
+
+    char   *acb_realbase;      /* APDU in transit */
+    char   *acb_base;          /*   .. */
+    int            acb_len;            /*   .. */
+    
+    IFP            acb_uptrans;        /* upcall for up-transfer */
+    IFP            acb_downtrans;      /* upcall for down-transfer */
+
+    IFP            acb_rtsindication;  /* rts event handler */
+
+/* ROSE */
+    int            acb_rosid;          /* ROSE (SASE) context id */
+    IFP            acb_putosdu;        /* osdu2acb */
+    IFP            acb_rowaitrequest;  /* RO-WAIT.REQUEST */
+    IFP            acb_ready;          /* get HDX permission */
+    IFP            acb_rosetindications;/* define vectors for INDICATION events */
+    IFP            acb_roselectmask;   /* map association descriptors for select () */
+    IFP            acb_ropktlose;      /* protocol-level abort */
+    PE     (*acb_getosdu) ();  /* for users of THORN... */
+
+    PE     acb_apdu;           /* APDU buffered */
+    
+    IFP            acb_rosindication;  /* ros event handler */
+};
+#define        NULLACB         ((struct assocblk *) 0)
+
+#define        FREEACB(acb) \
+{ \
+    if ((acb) -> acb_realbase) \
+       free ((acb) -> acb_realbase); \
+    else \
+       if ((acb) -> acb_base) \
+           free ((acb) -> acb_base); \
+    (acb) -> acb_realbase = (acb) -> acb_base = NULL, (acb) -> acb_len = 0; \
+}
+
+
+int    freeacblk ();
+struct assocblk *newacblk (), *findacblk ();
+
+/* \f */
+
+#ifndef        ACSE
+
+                               /* PConnect Types */
+#define        PCONN_DTS       0       /* Data Transfer Syntax */
+#define        PCONN_DATA      1       /* User Data */
+#define          PCONN_DATA_CK 0       /*   Checkpoint Size */
+#define            PCONN_CK_DFLT 0
+#define          PCONN_DATA_WD 1       /*   Window Size */
+#define            PCONN_WD_DFLT 3
+#define          PCONN_DATA_DM 2       /*   Dialogue-mode */
+#define            PCONN_DM_MONO 0     /*     monologue */
+#define            PCONN_DM_TWA  1     /*     two-way alternate */
+#define            PCONN_DM_DFLT PCONN_DM_MONO
+#define          PCONN_DATA_CN 3       /*   Connection Data */
+#define          PCONN_DATA_AP 4       /*   Application Protocol */
+#define            PCONN_AP_DFLT 1
+
+
+                               /* PAccept Types */
+#define        PACC_DTS        0       /* Data Transfer Syntax */
+#define        PACC_DATA       1       /* User Data */
+#define   PACC_DATA_CK  0      /*   Checkpoint Size */
+#define            PACC_CK_DFLT 0
+#define   PACC_DATA_WD  1      /*   Window Size */
+#define            PACC_WD_DFLT 3
+#define   PACC_DATA_CN  2      /*   Connection Data */
+
+
+                               /* PRefuse Types */
+#define        PREF_REASON     0       /* Refuse Reason */
+
+
+                               /* Data Transfer Syntax Types */
+#define        DTS_SYNTAX      0       /* IMPLICIT INTEGER */
+#define SYN_X409       0       /* x.409 */
+
+
+                               /* Connection Data Types */
+#define CN_OPEN                0       /* Open */
+#define        CN_RECOVER      1       /* Recover */
+
+
+                               /* Refuse codes */
+#define        REFUSE_BUSY     0       /* Busy */
+#define        REFUSE_RECOVER  1       /* Cannot recover */
+#define        REFUSE_VALIDATE 2       /* Validation failure */
+#define        REFUSE_MODE     3       /* Unacceptable dialogue mode */
+
+
+                               /* Abort codes */
+#define        ABORT_LSP       0       /* Local system problem */
+#define        ABORT_INV       1       /* Invalid parameter */
+#define        ABORT_ACT       2       /* Unrecognized activity */
+#define        ABORT_TMP       3       /* Temporary problem */
+#define        ABORT_PROTO     4       /* Protocol error */
+#define        ABORT_PERM      5       /* Permanent problem */
+#define        ABORT_USER      6       /* User abort */
+#define        ABORT_TRANS     7       /* Transfer completed */
+#endif
diff --git a/src/isode/h/acsap.h b/src/isode/h/acsap.h
new file mode 100644 (file)
index 0000000..7581af6
--- /dev/null
@@ -0,0 +1,273 @@
+/* acsap.h - include file for association control users (AcS-USER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:02  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:25  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:44  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:41  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _AcSAP_
+#define        _AcSAP_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+
+#ifndef        _PSAP2_
+#include "psap2.h"             /* definitions for PS-USERs */
+#endif
+
+/* \f */
+
+#define        NACDATA         3       /* arbitrary */
+
+struct AcSAPstart {            /* A-CONNECT.INDICATION */
+    int            acs_sd;             /* association descriptor */
+    
+    OID            acs_context;        /* application context name */
+
+    AEInfo acs_callingtitle;   /* info on calling application-entity */
+    AEInfo acs_calledtitle;    /* info on called application-entity */
+
+    struct PSAPstart acs_start;        /* info from P-CONNECT.INDICATION */
+
+                               /* initial information from peer */
+    int            acs_ninfo;          /*   number of elements */
+    PE     acs_info[NACDATA];  /*   data */
+};
+#define        ACSFREE(acs) { \
+    register int ACSI; \
+ \
+    if ((acs) -> acs_context) \
+       oid_free ((acs) -> acs_context), (acs) -> acs_context = NULLOID; \
+ \
+    AEIFREE (&(acs) -> acs_callingtitle); \
+    AEIFREE (&(acs) -> acs_calledtitle); \
+ \
+    PSFREE (&(acs) -> acs_start); \
+ \
+    for (ACSI = (acs) -> acs_ninfo - 1; ACSI >= 0; ACSI--) \
+       if ((acs) -> acs_info[ACSI]) \
+           pe_free ((acs) -> acs_info[ACSI]), \
+               (acs) -> acs_info[ACSI] = NULLPE; \
+    (acs) -> acs_ninfo = 0; \
+}
+
+
+struct AcSAPconnect {
+    int            acc_sd;             /* association descriptor */
+    
+    int            acc_result;         /* result */
+#define        ACS_ACCEPT      0       /*   Accepted */
+#define        ACS_REJECT      (-1)    /*   Release rejected */
+                               /*   Rejected by responder: */
+#define        ACS_PERMANENT   1       /*     Permanent */
+#define        ACS_TRANSIENT   2       /*     Transient */
+
+    int            acc_diagnostic;     /* source-diagnostic */
+                               /* service-user */
+#define        ACS_USER_NULL   3       /*   null */
+#define        ACS_USER_NOREASON 4     /*   no reason given */
+#define        ACS_CONTEXT     5       /*   application context name not supported*/
+#define        ACS_CALLING_AP_TITLE 6  /*   calling AP title not recognized */
+#define        ACS_CALLING_AP_ID 7     /*   calling AP invocation-ID not recognized */
+#define        ACS_CALLING_AE_QUAL 8   /*   calling AE qualifier not recognized */
+#define        ACS_CALLING_AE_ID 9     /*   calling AE invocation-ID not recognized */
+#define        ACS_CALLED_AP_TITLE 10  /*   called AP title not recognized */
+#define        ACS_CALLED_AP_ID 11     /*   called AP invocation-ID not recognized */
+#define        ACS_CALLED_AE_QUAL 12   /*   called AE qualifier not recognized */
+#define        ACS_CALLED_AE_ID 13     /*   called AE invocation-ID not recognized */
+                               /* service-provider */
+#define        ACS_PROV_NULL   14      /*   null */
+#define        ACS_PROV_NOREASON 15    /*   no reason given */
+#define        ACS_VERSION     16      /*   no common acse version */
+
+                               /* begin UNOFFICIAL */
+#define        ACS_ADDRESS     17      /* Address unknown */
+#define        ACS_REFUSED     18      /* Connect request refused on this network
+                                  connection */
+#define        ACS_CONGEST     19      /* Local limit exceeded */
+#define        ACS_PRESENTATION 20     /* Presentation disconnect */
+#define        ACS_PROTOCOL    21      /* Protocol error */
+#define        ACS_ABORTED     22      /* Peer aborted association */
+#define        ACS_PARAMETER   23      /* Invalid parameter */
+#define        ACS_OPERATION   24      /* Invalid operation */
+#define        ACS_TIMER       25      /* Timer expired */
+                               /* end UNOFFICIAL */
+
+#define        ACS_FATAL(r)    ((r) < ACS_PARAMETER)
+#define        ACS_OFFICIAL(r) ((r) < ACS_ADDRESS)
+
+    OID            acc_context;        /* application context name */
+
+    AEInfo  acc_respondtitle;  /* info on responding application-entity */
+
+    struct PSAPconnect acc_connect;/* info from P-CONNECT.CONFIRMATION */
+
+                               /* initial information from peer */
+    int            acc_ninfo;          /*   number of elements */
+    PE     acc_info[NACDATA];  /*   data */
+};
+#define        ACCFREE(acc) { \
+    register int ACCI; \
+ \
+    if ((acc) -> acc_context) \
+       oid_free ((acc) -> acc_context), (acc) -> acc_context = NULLOID; \
+ \
+    AEIFREE (&(acc) -> acc_respondtitle); \
+ \
+    PCFREE (&(acc) -> acc_connect); \
+ \
+    for (ACCI = (acc) -> acc_ninfo - 1; ACCI >= 0; ACCI--) \
+       if ((acc) -> acc_info[ACCI]) \
+           pe_free ((acc) -> acc_info[ACCI]), \
+               (acc) -> acc_info[ACCI] = NULLPE; \
+    (acc) -> acc_ninfo = 0; \
+}
+           
+
+
+struct AcSAPfinish {           /* A-RELEASE.INDICATION */
+    int            acf_reason;         /* reason for release */
+#define        ACF_NORMAL      0       /*   normal */
+#define        ACF_URGENT      1       /*   urgent */
+#define        ACF_USERDEFINED 30      /*   user-defined */
+
+                               /* release information from peer */
+    int            acf_ninfo;          /*   number of elements */
+    PE     acf_info[NACDATA];  /*   data */
+};
+#define        ACFFREE(acf) \
+{ \
+    register int ACFI; \
+ \
+    for (ACFI = (acf) -> acf_ninfo - 1; ACFI >= 0; ACFI--) \
+       if ((acf) -> acf_info[ACFI]) \
+           pe_free ((acf) -> acf_info[ACFI]), \
+               (acf) -> acf_info[ACFI] = NULLPE; \
+    (acf) -> acf_ninfo = 0; \
+}
+
+
+struct AcSAPrelease {          /* A-RELEASE.CONFIRMATION */
+    int            acr_affirmative;    /* T   = connection released
+                                  NIL = request refused */
+    
+    int            acr_reason;         /* reason for result */
+#define        ACR_NORMAL      0       /*   normal */
+#define        ACR_NOTFINISHED 1       /*   not finished */
+#define        ACR_USERDEFINED 30      /*   user-defined */
+
+                               /* release information from peer */
+    int            acr_ninfo;          /*   number of elements */
+    PE     acr_info[NACDATA];  /*   data */
+};
+#define        ACRFREE(acr) \
+{ \
+    register int ACRI; \
+ \
+    for (ACRI = (acr) -> acr_ninfo - 1; ACRI >= 0; ACRI--) \
+       if ((acr) -> acr_info[ACRI]) \
+           pe_free ((acr) -> acr_info[ACRI]), \
+               (acr) -> acr_info[ACRI] = NULLPE; \
+    (acr) -> acr_ninfo = 0; \
+}
+
+
+struct AcSAPabort {            /* A-{U,P}-ABORT.INDICATION */
+    int            aca_source;         /* abort source */
+#define        ACA_USER        0       /*   service-user */
+#define        ACA_PROVIDER    1       /*   service-provider */
+#define        ACA_LOCAL       2       /*   local ACPM (UNOFFICIAL) */
+
+    int            aca_reason;         /* same codes as acc_result */
+    
+                               /* abort information from peer */
+    int            aca_ninfo;          /*   number of elements */
+    PE     aca_info[NACDATA];  /*   data */
+
+                               /* diagnostics from provider */
+#define        ACA_SIZE        512
+    int            aca_cc;             /*   length */
+    char    aca_data[ACA_SIZE];        /*   data */
+};
+#define        ACAFREE(aca) \
+{ \
+    register int ACAI; \
+ \
+    for (ACAI = (aca) -> aca_ninfo - 1; ACAI >= 0; ACAI--) \
+       if ((aca) -> aca_info[ACAI]) \
+           pe_free ((aca) -> aca_info[ACAI]), \
+               (aca) -> aca_info[ACAI] = NULLPE; \
+    (aca) -> aca_ninfo = 0; \
+}
+
+
+struct AcSAPindication {
+    int            aci_type;           /* the union element present */
+#define        ACI_FINISH      0x00
+#define        ACI_ABORT       0x01
+
+    union {
+       struct AcSAPfinish aci_un_finish;
+       struct AcSAPabort aci_un_abort;
+    }  aci_un;
+#define        aci_finish      aci_un.aci_un_finish
+#define        aci_abort       aci_un.aci_un_abort
+};
+
+/* \f */
+
+extern char *acsapversion;
+
+
+int    AcInit ();              /* A-ASSOCIATE.INDICATION */
+
+int    AcAssocResponse ();     /* A-ASSOCIATE.RESPONSE */
+                               /* A-ASSOCIATE.REQUEST
+                                  (backwards-compatible) */
+#define        AcAssocRequest(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17) \
+       AcAsynAssocRequest (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,0)
+int    AcAsynAssocRequest ();  /* A-(ASYN-)ASSOCIATE.REQUEST */
+int    AcAsynRetryRequest ();  /* A-ASYN-RETRY.REQUEST (pseudo) */
+int    AcRelRequest ();        /* A-RELEASE.REQUEST */
+int    AcRelRetryRequest ();   /* A-RELEASE-RETRY.REQUEST (pseudo) */
+int    AcRelResponse ();       /* A-RELEASE.RESPONSE */
+int    AcUAbortRequest ();     /* A-ABORT.REQUEST */
+
+int    AcFINISHser ();         /* handle P-RELEASE.INDICATION */
+int    AcABORTser ();          /* handle P-{U,P}-ABORT.INDICATION */
+
+int    AcFindPCI ();           /* return PCI used by ACSE */
+
+char   *AcErrString ();                /* return AcSAP error code in string form */
+
+#endif
diff --git a/src/isode/h/cmd_srch.h b/src/isode/h/cmd_srch.h
new file mode 100644 (file)
index 0000000..f028ed0
--- /dev/null
@@ -0,0 +1,51 @@
+/* cmd_srch.h - command search structure */
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:04  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:27  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:46  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:42  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef _CMD_SRCH_
+#define _CMD_SRCH_
+
+typedef struct  cmd_table {
+       char    *cmd_key;
+       int     cmd_value;
+} CMD_TABLE;
+
+
+struct  cm_args {
+       char    *cm_key;
+       char    *cm_value;
+};
+
+int     cmd_srch ();
+char   *rcmd_srch ();
+
+#endif
diff --git a/src/isode/h/config.h b/src/isode/h/config.h
new file mode 100644 (file)
index 0000000..5c554a9
--- /dev/null
@@ -0,0 +1,36 @@
+/* this should be enough for everything... */
+
+#define        VSPRINTF                /* has vprintf(3s) routines */
+#define        TCP                     /* has TCP/IP (of course) */
+#define        SOCKETS                 /*   provided by sockets */
+#define        GETDENTS                /* has <dirent.h> */
+
+#ifdef __svr4__
+/* SYS5 is for termio instead of sgttyb */
+#define SYS5
+/* SVR4 turns off strdup */
+#define SVR4
+#endif
+
+#ifdef mips
+/* not sys5 */
+#define BSD42
+#endif
+
+#ifdef _AIX
+/* SYS5 is also for fcntl.h instead of sys/fcntl.h */
+#define SYS5
+/* AIX lets manifest.h fix up SYS5NLY */
+#define AIX
+#endif
+
+#ifdef __linux__
+/* SYS5 is for termio instead of sgttyb */
+#define SYS5
+#endif
+
+#ifdef sun
+#ifndef __svr4__
+#define SUNOS4
+#endif
+#endif
diff --git a/src/isode/h/configure.in b/src/isode/h/configure.in
new file mode 100644 (file)
index 0000000..cdff2db
--- /dev/null
@@ -0,0 +1,2 @@
+AC_INIT(configure.in)
+AC_OUTPUT(Makefile)
diff --git a/src/isode/h/dgram.h b/src/isode/h/dgram.h
new file mode 100644 (file)
index 0000000..21842f6
--- /dev/null
@@ -0,0 +1,47 @@
+/* dgram.h - datagram (CL-mode TS) abstractions */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:11  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:32  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:49  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:42  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _DGRAM_
+#define        _DGRAM_
+
+#define        MAXDGRAM        8192
+
+
+int    join_dgram_aux ();
+int    read_dgram_socket ();
+int    write_dgram_socket ();
+int    close_dgram_socket ();
+int    select_dgram_socket ();
+int    check_dgram_socket ();
+
+#endif
diff --git a/src/isode/h/fpkt.h b/src/isode/h/fpkt.h
new file mode 100644 (file)
index 0000000..1e04209
--- /dev/null
@@ -0,0 +1,280 @@
+/* fpkt.h - include file for FTAM provider (FS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:13  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:34  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:51  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:43  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "FTAM-types.h"
+
+#ifndef        _FTAM_
+#include "ftam.h"              /* definitions for FS-USERs */
+#endif
+#ifndef        _AcSAP_
+#include "acsap.h"             /* definitions for AcS-USERs */
+#endif
+
+/* \f */
+
+#define        FS_GEN(fsb) \
+       ((fsb -> fsb_flags & FSB_INIT) ? FS_GEN_INITIATOR : FS_GEN_RESPONDER)
+
+#define        ftamPsig(fsb, sd) \
+{ \
+    if ((fsb = findfsblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, \
+                           "invalid ftam descriptor"); \
+    } \
+    if (!(fsb -> fsb_flags & FSB_CONN)) { \
+       (void) sigiomask (smask); \
+       return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, \
+                           "ftam descriptor not connected"); \
+    } \
+    if (fsb -> fsb_flags & FSB_FINN) { \
+       (void) sigiomask (smask); \
+       return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, \
+                           "ftam descriptor finishing"); \
+    } \
+}
+
+#define        ftamFsig(fsb, sd) \
+{ \
+    if ((fsb = findfsblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, \
+                           "invalid ftam descriptor"); \
+    } \
+    if (!(fsb -> fsb_flags & FSB_CONN)) { \
+       (void) sigiomask (smask); \
+       return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, \
+                           "ftam descriptor not connected"); \
+    } \
+    if (!(fsb -> fsb_flags & FSB_FINN)) { \
+       (void) sigiomask (smask); \
+       return ftamlose (fti, FS_GEN (fsb), 0, NULLCP, \
+                           "ftam descriptor not finishing"); \
+    } \
+}
+
+#define toomuchP(b,n,m,p) \
+{ \
+    if (b == NULL) \
+       n = 0; \
+    else \
+       if (n > m) \
+           return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, \
+                           "too many %ss", p); \
+}
+
+#ifdef __STDC__
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, \
+                            "mandatory parameter \"%s\" missing", #p); \
+}
+#else
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return ftamlose (fti, FS_GEN_NOREASON, 0, NULLCP, \
+                           "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyFTAMdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyFTAMdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyFTAMdata(base,len,d)        bcopy (base, (char *) d, len)
+#endif
+
+
+int    ftamlose (), fpktlose (), ftamoops ();
+
+/* \f */
+
+struct ftamblk {
+    struct ftamblk *fsb_forw;  /* doubly-linked list */
+    struct ftamblk *fsb_back;  /*   .. */
+
+    int            fsb_fd;             /* association descriptor */
+
+    short   fsb_flags;         /* our state */
+#define        FSB_NULL        0x0000
+#define        FSB_CONN        0x0001  /* connected */
+#define        FSB_FINN        0x0002  /* other side wants to finish */
+#define        FSB_INIT        0x0004  /* this side initiated the association */
+#define        FSB_ASYN        0x0008  /* asynchronous */
+#define        FSB_DECHARGE    0x0010  /* responder can using charging on deselect */
+#define        FSB_CANCEL      0x0020  /* this side started F-CANCEL */
+#define        FSB_COLLIDE     0x0040  /* collision */
+
+    short   fsb_state;         /* more state */
+#define        FSB_INITIALIZED 0       /*   initialized */
+#define        FSB_MANAGEMENT  1       /*   management */
+#define        FSB_BULKBEGIN   2       /*   bulk data begin */
+#define        FSB_BULKEND     3       /*   bulk data end */
+#define        FSB_DATAIDLE    4       /*   data transfer idle */
+#define        FSB_LOCATE      5       /*   locate in progress */
+#define        FSB_ERASE       6       /*   erase in progress */
+#define        FSB_DATAREAD    7       /*   data transfer read */
+#define        FSB_DATAWRITE   8       /*   data transfer write */
+#define        FSB_DATAFIN1    9       /*   data transfer done */
+#define        FSB_DATAFIN2    10      /*     .. */
+#define        FSB_DATACANCEL  11      /*   cancel in progress */
+    
+    int            fsb_group;          /* group flags */
+
+    int            fsb_srequirements;  /* session requirements */
+    int            fsb_owned;          /* session tokens we own */
+    int            fsb_avail;          /* session tokens available */
+    int            fsb_settings;       /* initial and resync settings */
+    long    fsb_ssn;           /* serial number */
+    struct SSAPref fsb_connect;        /* session connection reference */
+    int            fsb_ssdusize;       /* largest atomic SSDU */
+
+    int            fsb_id;             /* FTAM context id */
+    int            fsb_prequirements;  /* presentation requirements */
+    struct PSAPctxlist fsb_contexts;/* presentation contexts */
+    struct FTAMcontentlist fsb_contents; /* FTAM document types */
+
+    OID            fsb_context;        /* application context */
+
+    int            fsb_fqos;           /* ftam-QoS */
+    int            fsb_class;          /* service-class */
+    int            fsb_units;          /* functional-units */
+                               /* mandatory functional-units */
+#define        FUNITS_TRANSFER (FUNIT_GROUPING)
+#define        FUNITS_ACCESS   (FUNIT_READ | FUNIT_WRITE | FUNIT_ACCESS)
+#define        FUNITS_MANAGE   (FUNIT_LIMITED | FUNIT_GROUPING)
+#define        FUNITS_TM       (FUNIT_LIMITED | FUNIT_GROUPING)
+#define        FUNITS_UNCONS   (0)
+
+    int            fsb_attrs;          /* attribute-groups */
+
+    IFP            fsb_indication;     /* event handler */
+    
+    struct PSAPdata fsb_data;  /* for screwy BDT stuff */
+
+    int            fsb_cancelaction;   /* handle CANCEL collisions */
+    PE     fsb_cancelshared;
+    struct FTAMdiagnostic *fsb_canceldiags;
+    int            fsb_cancelndiag;
+    
+    IFP            fsb_trace;          /* user-defined tracing function */
+};
+#define        NULLFSB         ((struct ftamblk *) 0)
+
+int    freefsblk ();
+struct ftamblk *newfsblk (), *findfsblk ();
+
+#ifndef        lint
+#define        fsbtrace(fsb,a) if ((fsb) -> fsb_trace) (*((fsb) -> fsb_trace)) a
+#else
+#define        fsbtrace(fsb,a) FTraceHook a
+#endif
+
+/* \f */
+
+struct pair {
+    int            p_mask;
+    int            p_bitno;
+};
+
+extern struct pair fclass_pairs[],
+                  funit_pairs[],
+                  fattr_pairs[],
+                  fname_pairs[],
+                  fmode_pairs[],
+                  frequested_pairs[],
+                  fpermitted_pairs[];
+/* \f */
+
+struct type_FTAM_Access__Control__List *acl2fpm ();
+int    fpm2acl ();
+
+struct type_FTAM_Read__Attributes *attr2fpm ();
+int    fpm2attr ();
+
+PE     bits2fpm ();
+int    fpm2bits ();
+
+struct type_FTAM_Charging *chrg2fpm ();
+int    fpm2chrg ();
+
+struct type_FTAM_Concurrency__Access *conacc2fpm ();
+int    fpm2conacc ();
+
+struct type_FTAM_Concurrency__Control *conctl2fpm ();
+int    fpm2conctl ();
+#define        conctl_present(fc) \
+    ((fc) -> fc_readlock != FLOCK_NOTREQD \
+       || (fc) -> fc_insertlock != FLOCK_NOTREQD \
+       || (fc) -> fc_replacelock != FLOCK_NOTREQD \
+       || (fc) -> fc_extendlock != FLOCK_NOTREQD \
+       || (fc) -> fc_eraselock != FLOCK_NOTREQD \
+       || (fc) -> fc_readattrlock != FLOCK_NOTREQD \
+       || (fc) -> fc_chngattrlock != FLOCK_NOTREQD \
+       || (fc) -> fc_deletelock != FLOCK_NOTREQD) \
+
+
+struct type_FTAM_Diagnostic *diag2fpm ();
+int    fpm2diag ();
+
+struct type_FTAM_FADU__Identity *faduid2fpm ();
+int    fpm2faduid ();
+
+struct type_FTAM_Access__Passwords *pass2fpm ();
+int    fpm2pass ();
+#define        passes_present(fp) \
+    ((fp) -> fp_read || (fp) -> fp_insert || (fp) -> fp_replace \
+       || (fp) -> fp_extend || (fp) -> fp_erase || (fp) -> fp_readattr \
+       || (fp) -> fp_chngattr || (fp) -> fp_delete) \
+
+struct type_FTAM_Shared__ASE__Information *shared2fpm ();
+int    fpm2shared ();
+
+/* \f */
+
+int    acs2ftamlose (), acs2ftamabort ();
+int    ps2ftamlose ();
diff --git a/src/isode/h/ftam.h b/src/isode/h/ftam.h
new file mode 100644 (file)
index 0000000..009002c
--- /dev/null
@@ -0,0 +1,1255 @@
+/* ftam.h - include file for FTAM users (FS-USER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:15  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:36  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:53  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:43  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _FTAM_
+#define        _FTAM_
+
+#ifndef        _PSAP2_
+#include "psap2.h"             /* definitions for PS-USERs */
+#endif
+#include "logger.h"
+
+/* \f */
+
+                               /* FTAM-QoS */
+#define        FQOS_NORECOVERY 0       /*   no-recovery */
+#define        FQOS_CLASS1     1       /*   class-1-recovery */
+#define        FQOS_CLASS2     2       /*   class-2-recovery */
+#define        FQOS_CLASS3     3       /*   class-3-recovery */
+#define        MY_FQOS         FQOS_NORECOVERY
+
+
+                               /* Service-Class */
+#define        FCLASS_UNCONS   0x01    /*   unconstrained-class */
+#define        FCLASS_MANAGE   0x02    /*   management-class */
+#define        FCLASS_TRANSFER 0x04    /*   transfer-class */
+#define        FCLASS_TM       0x08    /*   transfer-and-management-class */
+#define        FCLASS_ACCESS   0x10    /*   access-class */
+
+                               /* Functional-Units */
+#define        FUNIT_READ      0x001   /*   read */
+#define        FUNIT_WRITE     0x002   /*   write */
+#define        FUNIT_ACCESS    0x004   /*   file-access */
+#define        FUNIT_LIMITED   0x008   /*   limited-file-managment */
+#define        FUNIT_ENHANCED  0x010   /*   enhanced-file-management */
+#define        FUNIT_GROUPING  0x020   /*   grouping */
+#define        FUNIT_FADULOCK  0x040   /*   fadu-locking */
+#define        FUNIT_RECOVERY  0x080   /*   recovery */
+#define        FUNIT_RESTART   0x100   /*   restart-data-transfer */
+#define        MY_FUNIT        (FUNIT_READ | FUNIT_WRITE | FUNIT_ACCESS \
+                               | FUNIT_LIMITED | FUNIT_ENHANCED \
+                               | FUNIT_GROUPING | FUNIT_FADULOCK)
+
+                               /* Attribute-Groups */
+#define        FATTR_STORAGE   0x01    /*   storage */
+#define        FATTR_SECURITY  0x02    /*   security */
+#define        FATTR_PRIVATE   0x04    /*   private */
+#define        MY_FATTR        (FATTR_STORAGE | FATTR_SECURITY)
+
+
+                               /* State-Result */
+#define        FSTATE_SUCCESS  0       /*   success */
+#define        FSTATE_FAILURE  1       /*   failure */
+
+                               /* Action-Result */
+#define        FACTION_SUCCESS 0       /*   success */
+#define        FACTION_TRANS   1       /*   transient-error */
+#define        FACTION_PERM    2       /*   permanent-error */
+
+/* \f */
+
+struct FTAMcontent {
+    OID            fc_dtn;             /* Document-Type-Name */
+
+                               /* associated presentation context info */
+    int            fc_id;              /*   identifier */
+    int            fc_result;          /*   status */
+};
+    
+    
+struct FTAMcontentlist {       /* Contents-Type-List */
+    int            fc_ncontent;        /* number of contents */
+
+#define        NFCONT  (NPCTX - 2)     /* not-so-arbitrary */
+    struct FTAMcontent fc_contents[NFCONT];
+};
+
+/* \f */
+
+struct FTAMdiagnostic {                /* Diagnostic */
+    int            ftd_type;           /* diagnostic-type */
+#define        DIAG_INFORM     0       /*   informative */
+#define        DIAG_TRANS      1       /*   transient */
+#define        DIAG_PERM       2       /*   permanent */
+
+    int            ftd_identifier;     /* error-identifier */
+#define        FS_CODE2OFF(c)  ((c) % 1000)
+
+#define        FS_GEN_BASE     0       /* General FTAM diagnostics */
+#define        FS_GEN_NOREASON 0       /* No reason */
+#define        FS_GEN_RESPONDER 1      /* Responder error (unspecific) */
+#define        FS_GEN_SHUTDOWN 2       /* System shutdown */
+#define        FS_GEN_MGMT     3       /* FTAM management problem (unspecific) */
+#define        FS_GEN_MGMTACCT 4       /* FTAM management, bad account */
+#define        FS_GEN_MGMTPASS 5       /* FTAM management, security not passed */
+#define        FS_GEN_DELAY    6       /* Delay may be encountered */
+#define        FS_GEN_INITIATOR 7      /* Initiator error (unspecific) */
+#define        FS_GEN_SUBSEQ   8       /* Subsequent error */
+#define        FS_GEN_TEMPORAL 9       /* Temporal insufficiency of resources */
+#define        FS_GEN_VFSECURE 10      /* Access request violates VFS security */
+#define        FS_GEN_LSECURE  11      /* Access request violates local security */
+#define        FS_GEN_WAITING  12      /* Indications waiting (unofficial) */
+
+#define        FS_PRO_BASE     1000    /* Protocol and supporting service related
+                                  diagnostics */
+#define        FS_PRO_CONFLICT 1000    /* Conflicting parameter values */
+#define        FS_PRO_UNSUPORT 1001    /* Unsupported parameter values */
+#define        FS_PRO_MANDATORY 1002   /* Mandatory parameter not set */
+#define        FS_PRO_UNPARAM  1003    /* Unsupported parameter */
+#define        FS_PRO_DUPARAM  1004    /* Duplicated parameter */
+#define        FS_PRO_ILLEGAL  1005    /* Illegal parameter type */
+#define        FS_PRO_UNTYPE   1006    /* Unsupported parameter type */
+#define        FS_PRO_ERR      1007    /* FTAM protocol error (unspecific) */
+#define        FS_PRO_ERRPROC  1008    /* FTAM protocol error, procedure error */
+#define        FS_PRO_ERRFUNIT 1009    /* FTAM protocol error, functional unit error*/
+#define        FS_PRO_ERRMSG   1010    /* FTAM protocol error, corruption error */
+#define        FS_PRO_LOWFAIL  1011    /* Lower layer failure */
+#define        FS_PRO_LOWADDR  1012    /* Lower layer addressing error */
+#define        FS_PRO_TIMEOUT  1013    /* Timeout */
+#define        FS_PRO_SHUTDOWN 1014    /* System shutdown */
+#define        FS_PRO_GROUPING 1015    /* Illegal grouping sequence */
+#define        FS_PRO_THRESH   1016    /* Grouping threshold violation */
+#define        FS_PRO_PDU      1017    /* Specific PDU request inconsistent with the
+                                  current requested access */
+
+#define        FS_ACS_BASE     2000    /* Association related diagnostics */
+#define        FS_ACS_USER     2000    /* Association with user not allowed */
+#define        FS_ACS_2001     2001    /* not assigned, #2001  */
+#define        FS_ACS_CLASS    2002    /* Unsupported service class */
+#define        FS_ACS_FUNIT    2003    /* Unsupported functional unit */
+#define        FS_ACS_GRP      2004    /* Attribute group error (unspecific) */
+#define        FS_ACS_GRPSUP   2005    /* Attribute group not supported */
+#define        FS_ACS_GRPALL   2006    /* Attribute group not allowed */
+#define        FS_ACS_ACCT     2007    /* Bad account */
+#define        FS_ACS_MGMT     2008    /* Association management (unspecific) */
+#define        FS_ACS_MGMTADDR 2009    /* Association management - bad address */
+#define        FS_ACS_MGMTACCT 2010    /* Association management - bad account */
+#define        FS_ACS_CKPLARGE 2011    /* Checkpoint window error - too large */
+#define        FS_ACS_CKPSMALL 2012    /* Checkpoint window error - too small */
+#define        FS_ACS_CKPERR   2013    /* Checkpoint window error - unsupported */
+#define        FS_ACS_QOS      2014    /* Communications QoS not supported */
+#define        FS_ACS_IDENTITY 2015    /* Initiator identity unacceptable */
+#define        FS_ACS_CONTEXT  2016    /* Context management refused */
+#define        FS_ACS_ROLLBACK 2017    /* Rollback not available */
+#define        FS_ACS_CNTRESP  2018    /* Contents type list cut by responder */
+#define        FS_ACS_CNTPSAP  2019    /* Contents type list cut by Presentation
+                                  service */
+#define        FS_ACS_PASSWORD 2020    /* Invalid filestore password */
+#define        FS_ACS_SERVICES 2021    /* Incompatible service classes */
+
+#define        FS_SEL_BASE     3000    /* Selection related diagnostics */
+#define        FS_SEL_FILENAME 3000    /* Filename not found */
+#define        FS_SEL_MATCHED  3001    /* Selection attributes not matched */
+#define        FS_SEL_INITIAL  3002    /* Initial attributes not possible */
+#define        FS_SEL_ATTRNAME 3003    /* Bad attribute name */
+#define        FS_SEL_NOEXIST  3004    /* Non-existent file */
+#define        FS_SEL_EXISTS   3005    /* File already exists */
+#define        FS_SEL_CREATE   3006    /* File can not be created */
+#define        FS_SEL_DELETE   3007    /* File can not be deleted */
+#define        FS_SEL_CONAVAIL 3008    /* Concurrency control not available */
+#define        FS_SEL_CONSUPRT 3009    /* Concurrency control not supported */
+#define        FS_SEL_CONPOSS  3010    /* Concurrency control not possible */
+#define        FS_SEL_RESTRICT 3011    /* More restrictive lock */
+#define        FS_SEL_BUSY     3012    /* File busy */
+#define        FS_SEL_AVAIL    3013    /* File not available */
+#define        FS_SEL_ACCAVAIL 3014    /* Access control not available */
+#define        FS_SEL_ACCSUPRT 3015    /* Access control not supported */
+#define        FS_SEL_ACCINCON 3016    /* Access control inconsistent */
+#define        FS_SEL_TRUNC    3017    /* Filename truncated */
+#define        FS_SEL_ALTER    3018    /* Initial attributes altered */
+#define        FS_SEL_ACCOUNT  3019    /* Bad account */
+#define        FS_SEL_CREEXIST 3020    /* Override selected existing file */
+#define        FS_SEL_CREOLD   3021    /* Override deleted and recreated file
+                                  with old attributes */
+#define        FS_SEL_CRENEW   3022    /* Create override deleted and recreated file
+                                  with new attributes */
+#define        FS_SEL_CRELOSE  3023    /* Create override - not possible */
+#define        FS_SEL_AMBIG    3024    /* Ambiguous file specification */
+#define        FS_SEL_CREPASS  3025    /* Invalid create password */
+#define        FS_SEL_DELPASS  3026    /* Invalid delete password on override */
+#define        FS_SEL_ATRVALUE 3027    /* Bad attribute value */
+#define        FS_SEL_VIOLATES 3028    /* Requested access violates permitted
+                                  actions */
+#define        FS_SEL_NOTAVAIL 3029    /* Functional unit not available for requested
+                                  access */
+#define        FS_SEL_CRENOSEL 3030    /* File created but not selected */
+
+#define        FS_MGT_BASE     4000    /* File management related diagnostics */
+#define        FS_MGT_EXIST    4000    /* Attribute non-existant */
+#define        FS_MGT_READ     4001    /* Attribute cannot be read */
+#define        FS_MGT_CHANGE   4002    /* Attribute cannot be changed */
+#define        FS_MGT_SUPPORT  4003    /* Attribute not supported */
+#define        FS_MGT_NAME     4004    /* Bad attribute name */
+#define        FS_MGT_VALUE    4005    /* Bad attribute value */
+#define        FS_MGT_PARTIAL  4006    /* Attribute partially supported */
+#define        FS_MGMT_DISTINCT 4007   /* Additional set attribute not distinct */
+
+#define        FS_ACC_BASE     5000    /* Access related diagnostics */
+#define        FS_ACC_FADU     5000    /* Bad FADU (unspecific) */
+#define        FS_ACC_FADUSIZE 5001    /* Bad FADU - size error */
+#define        FS_ACC_FADUTYPE 5002    /* Bad FADU - type error */
+#define        FS_ACC_FADUSPEC 5003    /* Bad FADU - poorly specified */
+#define        FS_ACC_FADULOC  5004    /* Bad FADU - bad location */
+#define        FS_ACC_EXIST    5005    /* FADU does not exist */
+#define        FS_ACC_AVL      5006    /* FADU not available (unspecific) */
+#define        FS_ACC_AVLREAD  5007    /* FADU not available for reading */
+#define        FS_ACC_AVLWRITE 5008    /* FADU not available for writing */
+#define        FS_ACC_AVLLOC   5009    /* FADU not available for location */
+#define        FS_ACC_AVLERASE 5010    /* FADU not available for erasure */
+#define        FS_ACC_INSERT   5011    /* FADU cannot be inserted */
+#define        FS_ACC_REPLACE  5012    /* FADU cannot be replaced */
+#define        FS_ACC_LOCATE   5013    /* FADU cannot be located */
+#define        FS_ACC_ELEMENT  5014    /* Bad data element type */
+#define        FS_ACC_OPAVAIL  5015    /* Operation not available */
+#define        FS_ACC_OPSUPRT  5016    /* Operation not supported */
+#define        FS_ACC_OPCONS   5017    /* Operation inconsistent */
+#define        FS_ACC_CONAVAIL 5018    /* Concurrency control not available */
+#define        FS_ACC_CONSUPRT 5019    /* Concurrency control not supported */
+#define        FS_ACC_CONINCON 5020    /* Concurrency control inconsistent */
+#define        FS_ACC_MODAVAIL 5021    /* Processing mode not available */
+#define        FS_ACC_MODSUPRT 5022    /* Processing mode not supported */
+#define        FS_ACC_MODINCON 5023    /* Processing mode inconsistent */
+#define        FS_ACC_CTXAVAIL 5024    /* Access context not available */
+#define        FS_ACC_CTXSUPRT 5025    /* Access context not supported */
+#define        FS_ACC_WRITE    5026    /* Bad write (unspecific) */
+#define        FS_ACC_READ     5027    /* Bad read (unspecific) */
+#define        FS_ACC_LCL      5028    /* Local failure (unspecific) */
+#define        FS_ACC_LCLSPACE 5029    /* Local failure - file space exhausted */
+#define        FS_ACC_LCLDATA  5030    /* Local failure - data corrupted */
+#define        FS_ACC_LCLDEV   5031    /* Local failure - device failure */
+#define        FS_ACC_FFSEXCEED 5032   /* Future file size exceeded */
+#define        FS_ACC_FFSINCRES 5034   /* Future file size increased */
+#define        FS_ACC_FUNIT    5035    /* Functional unit invalid in processing
+                                  mode */
+#define        FS_ACC_TYPINCON 5036    /* Contents type inconsistent */
+#define        FS_ACC_TYPSIMPL 5037    /* Contents type simplified */
+#define        FS_ACC_DUPLICATE 5038   /* Duplicate FADU name */
+#define        FS_ACC_DAMAGED  5039    /* Damage to select/open regime */
+#define        FS_ACC_NOLOCKS  5040    /* FADU locking not available on file */
+#define        FS_ACC_LOCKED   5041    /* FADU locked by another user */
+
+#define        FS_RVY_BASE     6000    /* Recovery related diagnostics */
+#define        FS_RVY_CKP      6000    /* Bad checkpoint (unspecific) */
+#define        FS_RVY_UNIQUE   6001    /* Activity not unique */
+#define        FS_RVY_WINDOW   6002    /* Checkpoint outside window */
+#define        FS_RVY_EXISTS   6003    /* Activity no longer exists */
+#define        FS_RVY_RECOG    6004    /* Activity not recognized */
+#define        FS_RVY_NODOCKET 6005    /* No docket */
+#define        FS_RVY_CODOCKET 6006    /* Corrupt docket */
+#define        FS_RVY_WAITING  6007    /* File waiting restart */
+#define        FS_RVY_RECOVERY 6008    /* Bad recovery point */
+#define        FS_RVY_NOPOINT  6009    /* Non-existent recovery point */
+#define        FS_RVY_MODAVAIL 6010    /* Recovery mode not available */
+#define        FS_RVY_MODINCON 6011    /* Recovery mode inconsistent */
+#define        FS_RVY_MODREDUCE 6012   /* Recovery mode reduced */
+#define        FS_RVY_ACCAVAIL 6013    /* Access control not available */
+#define        FS_RVY_ACCSUPRT 6014    /* Access control not supported */
+#define        FS_RVY_ACCINCON 6015    /* Access control inconsistent */
+#define        FS_RVY_TYPINCON 6016    /* Contents type inconsistent */
+#define        FS_RVY_TYPSIMPL 6017    /* Contents type simplified */
+
+    int            ftd_observer;       /* error-observer */
+    int            ftd_source;         /* error-source */
+#define        EREF_NONE       0       /*   no-categorizaton-possible */
+#define        EREF_IFSU       1       /*   initiating-file-service-user */
+#define        EREF_IFPM       2       /*   initiating-file-protocol-machine */
+#define        EREF_SERV       3       /*   service-supporting-the-file-protocol-machine */
+#define        EREF_RFPM       4       /*   responding-file-protocol-machine */
+#define        EREF_RFSU       5       /*   responding-file-service-user */
+
+    int            ftd_delay;          /* suggested-delay */
+#define        DIAG_NODELAY    (-1)
+
+                               /* further-details */
+#define        FTD_SIZE        512     /* should be unlimited... */
+    int            ftd_cc;             /*   length */
+    char    ftd_data[FTD_SIZE];        /*   data */
+};
+
+/* \f */
+
+struct FTAMcharging {          /* Charging */
+    int            fc_ncharge;         /* number of charges */
+
+#define        NFCHRG  5               /* arbitrary */
+    struct fc_charge {
+       char   *fc_resource;    /* resource-identifier */
+       char   *fc_unit;        /* charging-unit */
+       int     fc_value;       /* charging-value */
+    }      fc_charges[NFCHRG];
+};
+
+/* \f */
+
+struct FTAMpasswords {         /* Access-Passwords */
+    char   *fp_read;           /* read-password */
+    int            fp_readlen;
+
+    char   *fp_insert;         /* insert-password */
+    int            fp_insertlen;
+
+    char   *fp_replace;                /* replace-password */
+    int            fp_replacelen;
+
+    char   *fp_extend;         /* extend-password */
+    int            fp_extendlen;
+
+    char   *fp_erase;          /* erase-password */
+    int            fp_eraselen;
+
+    char   *fp_readattr;       /* read-attribute-password */
+    int            fp_readattrlen;
+
+    char   *fp_chngattr;       /* change-attribute-password */
+    int            fp_chngattrlen;
+
+    char   *fp_delete;         /* delete-password */
+    int            fp_deletelen;
+};
+#define        FPFREE(fp) \
+{ \
+    register struct FTAMpasswords *FP = (fp); \
+ \
+    if (FP -> fp_read) \
+       free (FP -> fp_read), FP -> fp_read = NULL; \
+    if (FP -> fp_insert) \
+       free (FP -> fp_insert), FP -> fp_insert = NULL; \
+    if (FP -> fp_replace) \
+       free (FP -> fp_replace), FP -> fp_replace = NULL; \
+    if (FP -> fp_extend) \
+       free (FP -> fp_extend), FP -> fp_extend = NULL; \
+    if (FP -> fp_erase) \
+       free (FP -> fp_erase), FP -> fp_erase = NULL; \
+    if (FP -> fp_readattr) \
+       free (FP -> fp_readattr), FP -> fp_readattr = NULL; \
+    if (FP -> fp_chngattr) \
+       free (FP -> fp_chngattr), FP -> fp_chngattr = NULL; \
+    if (FP -> fp_delete) \
+       free (FP -> fp_delete), FP -> fp_delete = NULL; \
+}
+
+/* \f */
+
+struct FTAMconcurrency {       /* Concurrency-Control/Concurrency-Access */
+#define        FLOCK_SHARED    00      /* shared */
+#define        FLOCK_EXCLUSIVE 01      /* exclusive */
+#define        FLOCK_NOTREQD   02      /* not-required */
+#define        FLOCK_NOACCESS  03      /* no-access */
+#define        FLOCK_MASK      03
+#define        FLOCK_PRESENT   FLOCK_EXCLUSIVE
+#define        FLOCK_RESTRICT  01
+
+    char    fc_readlock;
+    char    fc_insertlock;
+    char    fc_replacelock;
+    char    fc_extendlock;
+    char    fc_eraselock;
+    char    fc_readattrlock;
+    char    fc_chngattrlock;
+    char    fc_deletelock;
+};
+#define        FCINIT(fc) \
+{ \
+    (fc) -> fc_readlock = FLOCK_NOTREQD; \
+    (fc) -> fc_insertlock = FLOCK_NOTREQD; \
+    (fc) -> fc_replacelock = FLOCK_NOTREQD; \
+    (fc) -> fc_eraselock = FLOCK_NOTREQD; \
+    (fc) -> fc_extendlock = FLOCK_NOTREQD; \
+    (fc) -> fc_readattrlock = FLOCK_NOTREQD; \
+    (fc) -> fc_chngattrlock = FLOCK_NOTREQD; \
+    (fc) -> fc_deletelock = FLOCK_NOTREQD; \
+}
+
+/* \f */
+
+struct FTAMacelement {         /* SET OF Access-Control-Element */
+    int            fe_actions;         /* action-list */
+#define        FA_PERM_READ            0x0001  /* read */
+#define        FA_PERM_INSERT          0x0002  /* insert */
+#define        FA_PERM_REPLACE         0x0004  /* replace */
+#define        FA_PERM_EXTEND          0x0008  /* extend */
+#define        FA_PERM_ERASE           0x0010  /* erase */
+#define        FA_PERM_READATTR        0x0020  /* read-attribute */
+#define        FA_PERM_CHNGATTR        0x0040  /* change-attribute */
+#define        FA_PERM_DELETE          0x0080  /* delete-file */
+
+    struct FTAMconcurrency fe_concurrency; /* concurrency-access */
+
+    char   *fe_identity;       /* user-identity */
+
+    struct FTAMpasswords fe_passwords;
+
+    AEI     fe_aet;            /* application-entity-title */
+
+    struct FTAMacelement *fe_next;
+};
+#define        FEFREE(fe) \
+{ \
+    register struct FTAMacelement  *FE, \
+                                  *FN; \
+ \
+    for (FE = (fe); FE; FE = FN) { \
+       FN = FE -> fe_next; \
+ \
+       if (FE -> fe_identity) \
+           free (FE -> fe_identity), FE -> fe_identity = NULL; \
+ \
+       FPFREE (&FE -> fe_passwords); \
+ \
+       if (FE -> fe_aet) { \
+           AEIFREE (FE -> fe_aet); \
+           free ((char *) FE -> fe_aet), FE -> fe_aet = NULL; \
+       } \
+ \
+       FE -> fe_next = NULL; \
+ \
+       free ((char *) FE); \
+    } \
+}
+
+/* \f */
+
+struct FTAMattributes {                /* {Change,Create,Read,Select}-Attributes */
+    long    fa_present;                /* values present */
+    long    fa_novalue;                /* no value available */
+#define        FA_NULL         0x00000
+#define        FA_FILENAME     0x00001 /* filename */
+#define        FA_ACTIONS      0x00002 /* permitted-actions */
+#define        FA_CONTENTS     0x00004 /* contents-type */
+#define        FA_ACCOUNT      0x00008 /* account */
+#define        FA_DATE_CREATE  0x00010 /* date-and-time-of-creation */
+#define        FA_DATE_MODIFY  0x00020 /* date-and-time-of-last-modification */
+#define        FA_DATE_READ    0x00040 /* date-and-time-of-last-read-access */
+#define        FA_DATE_ATTR    0x00080 /* date-and-time-of-last-attribute-modification */
+#define        FA_ID_CREATE    0x00100 /* identity-of-creator */
+#define        FA_ID_MODIFY    0x00200 /* identity-of-last-modifier */
+#define        FA_ID_READ      0x00400 /* identity-of-last-reader */
+#define        FA_ID_ATTR      0x00800 /* identity-of-last-attribute-modifier */
+#define        FA_AVAILABILITY 0x01000 /* file-availability */
+#define        FA_FILESIZE     0x02000 /* filesize */
+#define        FA_FUTURESIZE   0x04000 /* future-filesize */
+#define        FA_CONTROL      0x08000 /* access-control */
+#define        FA_LEGAL        0x10000 /* legal-qualifications */
+#define        FA_PRIVATE      0x20000 /* private-use */
+
+#define        FA_KERNEL       (FA_FILENAME | FA_ACTIONS | FA_CONTENTS)
+#define        FA_STORAGE      (FA_ACCOUNT | FA_DATE_CREATE | FA_DATE_MODIFY \
+                           | FA_DATE_READ | FA_DATE_ATTR | FA_ID_CREATE \
+                           | FA_ID_MODIFY | FA_ID_READ | FA_ID_ATTR \
+                           | FA_AVAILABILITY | FA_FILESIZE | FA_FUTURESIZE)
+#define        FA_SECURITY     (FA_CONTROL | FA_LEGAL)
+
+#define        NFFILE  5               /* arbitrary */
+    int            fa_nfile;           /* filename */
+    char   *fa_files[NFFILE];  /*   .. */
+    
+    int            fa_permitted;       /* permitted-actions,
+                                  same as fe_actions, plus: */
+#define        FA_PERM_TRAV            0x0100  /* traversal */
+#define        FA_PERM_RVTRAV          0x0200  /* reverse-traversal */
+#define        FA_PERM_RANDOM          0x0400  /* random-order */
+#define        FA_PERM_TRAVERSAL       (FA_PERM_TRAV | FA_PERM_RVTRAV \
+                                       | FA_PERM_RANDOM)
+
+    OID            fa_contents;        /* contents-type */
+    PE     fa_parameter;       /*   .. parameter */
+
+    char   *fa_account;                /* account */
+
+                               /* date-and-time-of- ... */
+    struct UTCtime fa_date_create;
+    struct UTCtime fa_date_modify;
+    struct UTCtime fa_date_read;
+    struct UTCtime fa_date_attribute;
+
+                               /* identity-of- ... */
+    char   *fa_id_create;
+    char   *fa_id_modify;
+    char   *fa_id_read;
+    char   *fa_id_attribute;
+
+    int            fa_availability;    /* file-availability */
+#define        FA_AVAIL_IMMED  0       /*   immediate */
+#define        FA_AVAIL_DEFER  1       /*   deferred */
+
+    int            fa_filesize;        /* filesize */
+    int            fa_futuresize;      /* future-filesize */
+
+    struct FTAMacelement *fa_control;/* access-control */
+    char   *fa_legal;          /* legal-qualification */
+
+    char   *fa_private;                /* XXX */
+};
+
+void   FAFREE ();
+
+/* \f */
+
+struct FADUidentity {          /* FADU-Identity */
+    int            fa_type;
+#define        FA_FIRSTLAST    0       /* first-last */
+#define        FA_RELATIVE     1       /* relative */
+#define        FA_BEGINEND     2       /* begin-end */
+#define        FA_SINGLE       3       /* single-name */
+#define        FA_NAMELIST     4       /* name-list */
+#define        FA_FADUNUMBER   5       /* fadu-number */
+
+    union {
+       int     fa_un_firstlast;
+#define        FA_FIRST        0
+#define        FA_LAST         1
+
+       int     fa_un_relative;
+#define        FA_PREVIOUS     0
+#define        FA_CURRENT      1
+#define        FA_NEXT         2
+
+       int     fa_un_beginend;
+#define        FA_BEGIN        0
+#define        FA_END          1
+
+       char   *fa_un_singlename;
+
+#define        NANAME  5               /* arbitrary */
+       struct {
+           char   *fa_un_names[NANAME];
+           int     fa_un_nname;
+       }       fa_un_list;
+
+       int     fa_un_fadunumber;
+    }  fa_un;
+#define        fa_firstlast    fa_un.fa_un_firstlast
+#define        fa_relative     fa_un.fa_un_relative
+#define        fa_beginend     fa_un.fa_un_beginend
+#define        fa_singlename   fa_un.fa_un_singlename
+#define        fa_names        fa_un.fa_un_list.fa_un_names
+#define        fa_nname        fa_un.fa_un_list.fa_un_nname
+#define        fa_fadunumber   fa_un.fa_un_fadunumber
+};
+#define        FUFREE(fu) \
+{ \
+    register int    FUI; \
+ \
+    if ((fu) -> fa_singlename) \
+       free ((fu) -> fa_singlename), (fu) -> fa_singlename = NULL; \
+ \
+    for (FUI = (fu) -> fa_nname - 1; FUI >= 0; FUI--) \
+       if ((fu) -> fa_names[FUI]) \
+           free ((fu) -> fa_names[FUI]), (fu) -> fa_names[FUI] = NULL; \
+}
+
+/* \f */
+
+struct FTAMstart {             /* F-INITIALIZE.INDICATION */
+    int            fts_sd;             /* FTAM descriptor */
+
+    AEInfo fts_callingtitle;   /* info on calling application-entity */
+    AEInfo fts_calledtitle;    /* info called application-entity */
+
+    struct PSAPaddr fts_calledaddr;/* called presentation address */
+    struct PSAPaddr fts_callingaddr;/* calling presentation address */
+
+    OID            fts_context;        /* application context name */
+
+    int            fts_manage;         /* presentation-context-management */
+
+    int            fts_class;          /* service-class */
+
+    int            fts_units;          /* functional-units */
+    int            fts_attrs;          /* attribute-groups */
+
+    PE     fts_sharedASE;      /* shared-ASE-information */
+
+    int            fts_fqos;           /* ftam-QoS */
+
+    struct FTAMcontentlist fts_contents;/* contents-type-list */
+
+    char   *fts_initiator;     /* initiator-identity */
+    char   *fts_account;       /* account */
+    char   *fts_password;      /* filestore-password */
+    int            fts_passlen;        /*   .. */
+
+    int            fts_ssdusize;       /* largest atomic SSDU */
+
+    struct QOStype fts_qos;    /* Communications QoS */
+};
+#define        FTSFREE(fts) \
+{ \
+    register int FSI; \
+ \
+    AEIFREE (&(fts) -> fts_callingtitle); \
+    AEIFREE (&(fts) -> fts_calledtitle); \
+    if ((fts) -> fts_context) \
+       oid_free ((fts) -> fts_context), (fts) -> fts_context = NULLOID; \
+ \
+    if ((fts) -> fts_sharedASE) \
+       pe_free ((fts) -> fts_sharedASE), (fts) -> fts_sharedASE = NULLPE; \
+ \
+    for (FSI = (fts) -> fts_contents.fc_ncontent - 1; FSI >= 0; FSI--) \
+       oid_free ((fts) -> fts_contents.fc_contents[FSI].fc_dtn), \
+               (fts) -> fts_contents.fc_contents[FSI].fc_dtn = NULLOID; \
+    (fts) -> fts_contents.fc_ncontent = 0; \
+ \
+    if ((fts) -> fts_initiator) \
+       free ((fts) -> fts_initiator), (fts) -> fts_initiator = NULL; \
+    if ((fts) -> fts_account) \
+       free ((fts) -> fts_account), (fts) -> fts_account = NULL; \
+    if ((fts) -> fts_password) \
+       free ((fts) -> fts_password), (fts) -> fts_password = NULL; \
+}
+
+
+struct FTAMconnect {           /* F-INITIALIZE.CONFIRMATION */
+    int            ftc_sd;             /* FTAM descriptor */
+
+    AEInfo ftc_respondtitle;   /* responding application-entity title */
+
+    struct PSAPaddr ftc_respondaddr;/* responding presentation address */
+
+    OID            ftc_context;        /* application context name */
+
+    int            ftc_state;          /* state-result */
+    int            ftc_action;         /* action-result */
+
+    int            ftc_manage;         /* presentation-context-management */
+
+    int            ftc_class;          /* service-class */
+
+    int            ftc_units;          /* functional-units */
+    int            ftc_attrs;          /* attribute-groups */
+
+    PE     ftc_sharedASE;      /* shared-ASE-information */
+
+    int            ftc_fqos;           /* ftam-QoS */
+
+    struct FTAMcontentlist ftc_contents;/* contents-type-list */
+
+#define        NFDIAG  5               /* diagnostic */
+    int            ftc_ndiag;
+    struct FTAMdiagnostic  ftc_diags[NFDIAG];
+
+    int            ftc_ssdusize;       /* largest atomic SSDU */
+
+    struct QOStype ftc_qos;    /* communications QoS */
+};
+#define        FTCFREE(ftc) \
+{ \
+    register int FCI; \
+ \
+    AEIFREE (&(ftc) -> ftc_respondtitle); \
+    if ((ftc) -> ftc_context) \
+       oid_free ((ftc) -> ftc_context), (ftc) -> ftc_context = NULLOID; \
+ \
+    if ((ftc) -> ftc_sharedASE) \
+       pe_free ((ftc) -> ftc_sharedASE), (ftc) -> ftc_sharedASE = NULLPE; \
+ \
+    for (FCI = (ftc) -> ftc_contents.fc_ncontent - 1; FCI >= 0; FCI--) \
+       oid_free ((ftc) -> ftc_contents.fc_contents[FCI].fc_dtn), \
+               (ftc) -> ftc_contents.fc_contents[FCI].fc_dtn = NULLOID; \
+    (ftc) -> ftc_contents.fc_ncontent = 0; \
+}
+
+
+struct FTAMfinish {            /* F-TERMINATE.INDICATION */
+    PE     ftf_sharedASE;      /* shared-ASE-information */
+};
+#define        FTFFREE(ftf) \
+{ \
+      if ((ftf) -> ftf_sharedASE) \
+         pe_free ((ftf) -> ftf_sharedASE), (ftf) -> ftf_sharedASE = NULLPE; \
+}
+
+struct FTAMrelease {           /* F-TERMINATE.CONFIRMATION */
+    PE     ftr_sharedASE;      /* shared-ASE-information */
+                               /* charging */
+    struct FTAMcharging ftr_charges;
+};
+#define        FTRFREE(ftr) \
+{ \
+    register int    FRI; \
+    register struct fc_charge  *FC; \
+ \
+    if ((ftr) -> ftr_sharedASE) \
+       pe_free ((ftr) -> ftr_sharedASE), (ftr) -> ftr_sharedASE = NULLPE; \
+ \
+    for (FC = (ftr) -> ftr_charges.fc_charges, FRI = (ftr) -> ftr_charges.fc_ncharge - 1; \
+           FRI >= 0; \
+           FC++, FRI--) { \
+       if (FC -> fc_resource) \
+           free (FC -> fc_resource), FC -> fc_resource = NULL; \
+       if (FC -> fc_unit) \
+           free (FC -> fc_unit), FC -> fc_unit = NULL; \
+    } \
+    (ftr) -> ftr_charges.fc_ncharge = 0; \
+}
+
+
+struct FTAMabort {             /* F-{U,P}-ABORT.INDICATION */
+    int            fta_peer;           /* T   = F-U-ABORT.INDICATION
+                                  NIL = F-P-ABORT.INDICATION */
+
+    int            fta_action;         /* action-result */
+    
+    int            fta_ndiag;          /* diagnostic */
+    struct FTAMdiagnostic fta_diags[NFDIAG];
+};
+
+
+struct FTAMselect {            /* F-SELECT.* */
+                               /* RESPONSE only */
+    int     ftse_state;                /* state-result */
+    int     ftse_action;       /* action-result */
+
+                               /* attributes (FILENAME only) */
+    struct FTAMattributes ftse_attrs;
+#define        FA_SEL_ATTRS    FA_FILENAME
+
+                               /* REQUEST only */
+    int            ftse_access;        /* requested-access */
+#define        FA_REQ_MASK     (FA_PERM_READ | FA_PERM_INSERT | FA_PERM_REPLACE \
+                               | FA_PERM_EXTEND | FA_PERM_ERASE \
+                               | FA_PERM_READATTR | FA_PERM_CHNGATTR \
+                               | FA_PERM_DELETE)
+                               /* access-passwords */
+    struct FTAMpasswords ftse_pwds;
+                               /* concurrency-control */
+    struct FTAMconcurrency ftse_conctl;
+    PE     ftse_sharedASE;     /* shared-ASE-information */
+    char   *ftse_account;      /* account */
+
+                               /* RESPONSE only */
+    int            ftse_ndiag;         /* diagnostic */
+    struct FTAMdiagnostic ftse_diags[NFDIAG];
+};
+#define        FTSEFREE(ftse) \
+{ \
+    FAFREE (&((ftse) -> ftse_attrs)); \
+    FPFREE (&((ftse) -> ftse_pwds)); \
+    if ((ftse) -> ftse_sharedASE) \
+       pe_free ((ftse) -> ftse_sharedASE), (ftse) -> ftse_sharedASE = NULLPE; \
+    if ((ftse) -> ftse_account) \
+       free ((ftse) -> ftse_account), (ftse) -> ftse_account = NULLCP; \
+}
+
+
+struct FTAMdeselect {          /* F-DESELECT.* */
+                               /* RESPONSE only */
+    int     ftde_action;       /* action-result */
+
+    PE     ftde_sharedASE;     /* shared-ASE-information */
+
+                               /* RESPONSE only */
+                               /* charging */
+    struct FTAMcharging ftde_charges;
+    int     ftde_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftde_diags[NFDIAG];
+};
+#define        FTDEFREE(ftde) \
+{ \
+    register int    FDEI; \
+    register struct fc_charge  *FC; \
+ \
+    for (FC = (ftde) -> ftde_charges.fc_charges, FDEI = (ftde) -> ftde_charges.fc_ncharge - 1; \
+           FDEI >= 0; \
+           FC++, FDEI--) { \
+       if (FC -> fc_resource) \
+           free (FC -> fc_resource), FC -> fc_resource = NULL; \
+       if (FC -> fc_unit) \
+           free (FC -> fc_unit), FC -> fc_unit = NULL; \
+    } \
+    (ftde) -> ftde_charges.fc_ncharge = 0; \
+    if ((ftde) -> ftde_sharedASE) \
+       pe_free ((ftde) -> ftde_sharedASE), (ftde) -> ftde_sharedASE = NULLPE; \
+}
+
+
+struct FTAMcreate {            /* F-CREATE.* */
+                               /* RESPONSE only */
+    int     ftce_state;                /* state-result */
+    int     ftce_action;       /* action-result */
+
+                               /* REQUEST only */
+    int            ftce_override;      /* override */
+#define        FOVER_FAIL      0       /* fail, if already exists */
+#define        FOVER_SELECT    1       /* select, if it already exists */
+#define        FOVER_WRITE     2       /* zero-truncate, if it already exists */
+#define        FOVER_DELETE    3       /* delete, if it already exists */
+
+                               /* initial-attributes */
+    struct FTAMattributes ftce_attrs;
+#define        FA_CRE_ATTRS    (FA_FILENAME | FA_ACTIONS | FA_CONTENTS | FA_ACCOUNT \
+                           | FA_AVAILABILITY | FA_FUTURESIZE | FA_CONTROL \
+                           | FA_LEGAL | FA_PRIVATE)
+
+                               /* REQUEST only */
+    char   *ftce_create;       /* create-password */
+    int            ftce_crelen;        /*   .. */
+    int            ftce_access;        /* requested-access */
+                               /* access-passwords */
+    struct FTAMpasswords ftce_pwds;
+                               /* concurrency-control */
+    struct FTAMconcurrency ftce_conctl;
+
+    PE     ftce_sharedASE;     /* shared-ASE-information */
+
+                               /* REQUEST only */
+    char   *ftce_account;      /* account */
+
+                               /* RESPONSE only */
+    int            ftce_ndiag;         /* diagnostic */
+    struct FTAMdiagnostic ftce_diags[NFDIAG];
+};
+#define        FTCEFREE(ftce) \
+{ \
+    FAFREE (&((ftce) -> ftce_attrs)); \
+    if ((ftce) -> ftce_create) \
+       free ((ftce) -> ftce_create), (ftce) -> ftce_create = NULLCP; \
+    FPFREE (&((ftce) -> ftce_pwds)); \
+    if ((ftce) -> ftce_sharedASE) \
+       pe_free ((ftce) -> ftce_sharedASE), (ftce) -> ftce_sharedASE = NULLPE; \
+    if ((ftce) -> ftce_account) \
+       free ((ftce) -> ftce_account), (ftce) -> ftce_account = NULLCP; \
+}
+
+
+struct FTAMdelete {            /* F-DELETE.* */
+                               /* RESPONSE only */
+    int            ftxe_action;        /* action-result */
+    
+    PE     ftxe_sharedASE;     /* shared-ASE-information */
+
+                               /* RESPONSE only */
+                               /* charging */
+    struct FTAMcharging ftxe_charges;
+    int     ftxe_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftxe_diags[NFDIAG];
+};
+#define        FTXEFREE(ftxe) \
+{ \
+    register int    FXEI; \
+    register struct fc_charge  *FC; \
+ \
+    if ((ftxe) -> ftxe_sharedASE) \
+       pe_free ((ftxe) -> ftxe_sharedASE), (ftxe) -> ftxe_sharedASE = NULLPE; \
+ \
+    for (FC = (ftxe) -> ftxe_charges.fc_charges, FXEI = (ftxe) -> ftxe_charges.fc_ncharge - 1; \
+           FXEI >= 0; \
+           FC++, FXEI--) { \
+       if (FC -> fc_resource) \
+           free (FC -> fc_resource), FC -> fc_resource = NULL; \
+       if (FC -> fc_unit) \
+           free (FC -> fc_unit), FC -> fc_unit = NULL; \
+    } \
+    (ftxe) -> ftxe_charges.fc_ncharge = 0; \
+}
+
+
+struct FTAMreadattr {          /* F-READ-ATTRIB.* */
+                               /* RESPONSE only */
+    int            ftra_action;        /* action-result */
+
+                               /* REQUEST only */
+    int            ftra_attrnames;     /* attribute names (from fa_present) */
+
+                               /* RESPONSE only */
+    struct FTAMattributes ftra_attrs;
+    int            ftra_ndiag;         /* diagnostic */
+    struct FTAMdiagnostic ftra_diags[NFDIAG];
+};
+#define        FTRAFREE(ftra) \
+{ \
+    FAFREE (&((ftra) -> ftra_attrs)); \
+}
+
+
+struct FTAMchngattr {          /* F-CHANGE-ATTRIB.* */
+                               /* RESPONSE only */
+    int ftca_action;           /* action-result */
+
+    struct FTAMattributes ftca_attrs;
+#define        FA_CHG_ATTRS    (FA_FILENAME | FA_ACCOUNT | FA_AVAILABILITY \
+                           | FA_FUTURESIZE | FA_CONTROL | FA_LEGAL \
+                           | FA_PRIVATE)
+
+                               /* RESPONSE only */
+    int            ftca_ndiag;         /* diagnostic */
+    struct FTAMdiagnostic ftca_diags[NFDIAG];
+};
+#define        FTCAFREE(ftca) \
+{ \
+    FAFREE (&((ftca) -> ftca_attrs)); \
+}
+
+
+struct FTAMopen {              /* F-OPEN.* */
+                               /* RESPONSE only */
+    int            ftop_state;         /* state-result */
+    int            ftop_action;        /* action-result */
+
+                               /* REQUEST only */
+    int            ftop_mode;          /* processing-mode (read..erase) */
+#define        FA_MODE_MASK    (FA_PERM_READ | FA_PERM_INSERT | FA_PERM_REPLACE \
+                               | FA_PERM_EXTEND | FA_PERM_ERASE)
+
+    OID            ftop_contents;      /* contents-type */
+    PE     ftop_parameter;     /*   .. */
+                               /* concurrency-control */
+    struct FTAMconcurrency ftop_conctl;
+    PE     ftop_sharedASE;     /* shared-ASE-information */
+
+                               /* REQUEST only */
+    int            ftop_locking;       /* enable-fadu-locking */
+
+                               /* RESPONSE only */
+    int            ftop_ndiag;         /* diagnostic */
+    struct FTAMdiagnostic ftop_diags[NFDIAG];
+};
+#define        FTOPFREE(ftop) \
+{ \
+    if ((ftop) -> ftop_contents) \
+       oid_free ((ftop) -> ftop_contents), \
+           (ftop) -> ftop_contents = NULLOID; \
+    if ((ftop) -> ftop_parameter) \
+       pe_free ((ftop) -> ftop_parameter), \
+           (ftop) -> ftop_parameter = NULLPE; \
+    if ((ftop) -> ftop_sharedASE) \
+       pe_free ((ftop) -> ftop_sharedASE), (ftop) -> ftop_sharedASE = NULLPE; \
+}
+
+
+struct FTAMclose {             /* F-CLOSE.* */
+    int            ftcl_action;        /* action-result */
+
+    PE     ftcl_sharedASE;     /* shared-ASE-information */
+
+    int     ftcl_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftcl_diags[NFDIAG];
+};
+#define        FTCLFREE(ftcl) \
+{ \
+    if ((ftcl) -> ftcl_sharedASE) \
+       pe_free ((ftcl) -> ftcl_sharedASE), (ftcl) -> ftcl_sharedASE = NULLPE; \
+}
+
+
+struct FTAMgroup {
+    int     ftg_threshold;     /* threshold */
+
+    int     ftg_flags;
+#define        FTG_NULL        0x0000
+#define        FTG_BEGIN       0x0001  /* have begin */
+#define        FTG_SELECT      0x0002  /*   .. select */
+#define        FTG_CREATE      0x0004  /*   .. create */
+#define        FTG_RDATTR      0x0008  /*   .. read attribute */
+#define        FTG_CHATTR      0x0010  /*   .. change attribute */
+#define        FTG_OPEN        0x0020  /*   .. open */
+#define        FTG_CLOSE       0x0040  /*   .. close */
+#define        FTG_DESELECT    0x0080  /*   .. deselect */
+#define        FTG_DELETE      0x0100  /*   .. delete */
+#define        FTG_END         0x0200  /*   .. end */
+
+    union {
+       struct FTAMselect   ftg_un1_select;
+       struct FTAMcreate   ftg_un1_create;
+       struct FTAMclose    ftg_un1_close;
+    }                   ftg_un1;
+#define        ftg_select      ftg_un1.ftg_un1_select
+#define        ftg_create      ftg_un1.ftg_un1_create
+#define        ftg_close       ftg_un1.ftg_un1_close
+
+    struct FTAMreadattr ftg_readattr;
+
+    struct FTAMchngattr ftg_chngattr;
+
+    union {
+       struct FTAMdeselect ftg_un2_deselect;
+       struct FTAMdelete   ftg_un2_delete;
+       struct FTAMopen     ftg_un2_open;
+    } ftg_un2;
+#define        ftg_deselect    ftg_un2.ftg_un2_deselect
+#define        ftg_delete      ftg_un2.ftg_un2_delete
+#define        ftg_open        ftg_un2.ftg_un2_open
+};
+#define        FTGFREE(ftg) \
+{ \
+    if ((ftg) -> ftg_flags & FTG_SELECT) { \
+       FTSEFREE (&((ftg) -> ftg_select)); \
+    } \
+    else \
+       if ((ftg) -> ftg_flags & FTG_CREATE) { \
+           FTCEFREE (&((ftg) -> ftg_create)); \
+       } \
+       else \
+           if ((ftg) -> ftg_flags & FTG_CLOSE) \
+               FTCLFREE (&((ftg) -> ftg_close)); \
+ \
+    if ((ftg) ->ftg_flags & FTG_RDATTR) \
+       FTRAFREE (&((ftg) -> ftg_readattr)); \
+ \
+    if ((ftg) ->ftg_flags & FTG_CHATTR) \
+       FTCAFREE (&((ftg) -> ftg_chngattr)); \
+ \
+    if ((ftg) -> ftg_flags & FTG_DESELECT) { \
+       FTDEFREE (&((ftg) -> ftg_deselect)); \
+    } \
+    else \
+       if ((ftg) -> ftg_flags & FTG_DELETE) { \
+           FTXEFREE (&((ftg) -> ftg_delete)); \
+       } \
+       else \
+           if ((ftg) -> ftg_flags & FTG_OPEN) \
+               FTOPFREE (&((ftg) -> ftg_open)); \
+}
+
+
+struct FTAMaccess {            /* F-{LOCATE,ERASE}.{INDICATION,CONFIRMATION} */
+    int            ftac_operation;
+#define        FA_OPS_LOCATE   0       /* locate */
+#define        FA_OPS_ERASE    1       /* erase */
+
+                               /* CONFIRMATION only */
+    int            ftac_action;        /* action-result */
+
+                               /* *.INDICATION OR F-LOCATE.CONFIRMATION */
+                               /* fadu-identity */
+    struct FADUidentity ftac_identity;
+
+                               /* F-LOCATE.INDICATION only */
+    int            ftac_locking;       /* fadu-lock (on, off) */
+
+                               /* CONFIRMATION only */
+    int     ftac_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftac_diags[NFDIAG];
+};
+#define        FTACFREE(ftac) \
+{ \
+    FUFREE (&((ftac) -> ftac_identity)); \
+}
+
+
+struct FTAMreadwrite {         /* F-{READ,WRITE}.INDICATION */
+    int            ftrw_operation;     /* fadu-operation */
+#define        FA_OPS_READ     (-1)    /*   read (pseudo) */
+#define        FA_OPS_INSERT   0       /*   insert */
+#define        FA_OPS_REPLACE  1       /*   replace */
+#define        FA_OPS_EXTEND   2       /*   extend */
+
+                               /* fadu-identity */
+    struct FADUidentity        ftrw_identity;
+
+                               /* F-READ.INDICATION only */
+    int            ftrw_context;       /* access-context */
+#define        FA_ACC_HA       0       /*   hierarchical-all-data-units */
+#define        FA_ACC_HN       1       /*   hierarchical-no-data-units */
+#define        FA_ACC_FA       2       /*   flat-all-data-units */
+#define        FA_ACC_FL       3       /*   flat-one-level-data-units */
+#define        FA_ACC_FS       4       /*   flat-single-data-unit */
+#define        FA_ACC_UA       5       /*   unstructured-all-data-units */
+#define        FA_ACC_US       6       /*   unstructured-single-data-unit */
+    int            ftrw_level;         /* level for FL */
+
+    int            ftrw_locking;       /* fadu-lock */
+};
+#define        FTRWFREE(ftrw) \
+{ \
+    FUFREE (&((ftrw) -> ftrw_identity)); \
+}
+
+
+struct FTAMdataend {           /* F-DATA-END.INDICATION */
+    int            ftda_action;        /* action-result */
+
+    int     ftda_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftda_diags[NFDIAG];
+};
+
+
+struct FTAMtransend {          /* F-TRANSFER-END.{INDICATION,CONFIRMATION} */
+                               /* RESPONSE only */
+    int            ftre_action;        /* action-result */
+
+    PE     ftre_sharedASE;     /* shared-ASE-information */
+
+                               /* RESPONSE only */
+    int     ftre_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftre_diags[NFDIAG];
+};
+#define        FTREFREE(ftre) \
+{ \
+    if ((ftre) -> ftre_sharedASE) \
+       pe_free ((ftre) -> ftre_sharedASE), (ftre) -> ftre_sharedASE = NULLPE; \
+}
+
+
+struct FTAMcancel {            /* F-CANCEL.{INDICATION,CONFIRMATION} */
+    int            ftcn_action;        /* action-result */
+
+    PE     ftcn_sharedASE;     /* shared-ASE-information */
+
+    int     ftcn_ndiag;                /* diagnostic */
+    struct FTAMdiagnostic   ftcn_diags[NFDIAG];
+};
+#define        FTCNFREE(ftcn) \
+{ \
+    if ((ftcn) -> ftcn_sharedASE) \
+       pe_free ((ftcn) -> ftcn_sharedASE), (ftcn) -> ftcn_sharedASE = NULLPE; \
+}
+
+
+struct FTAMindication {
+    int     fti_type;          /* the union element present */
+#define        FTI_FINISH      0x00
+#define        FTI_ABORT       0x01
+#define        FTI_MANAGEMENT  0x02
+#define        FTI_BULKBEGIN   0x03
+#define        FTI_BULKEND     0x04
+#define        FTI_ACCESS      0x05
+#define        FTI_READWRITE   0x06
+#define        FTI_DATA        0x07
+#define        FTI_DATAEND     0x08
+#define        FTI_CANCEL      0x09
+#define        FTI_TRANSEND    0x10
+
+    union {
+       struct FTAMfinish   fti_un_finish;
+       struct FTAMabort    fti_un_abort;
+       struct FTAMgroup    fti_un_group;
+       struct FTAMaccess   fti_un_access;
+       struct FTAMreadwrite fti_un_readwrite;
+       struct PSAPdata     fti_un_data;
+       struct FTAMdataend  fti_un_dataend;
+       struct FTAMcancel   fti_un_cancel;
+       struct FTAMtransend fti_un_transend;
+    }  fti_un;
+#define        fti_finish      fti_un.fti_un_finish
+#define        fti_abort       fti_un.fti_un_abort
+#define        fti_group       fti_un.fti_un_group
+#define        fti_access      fti_un.fti_un_access
+#define        fti_readwrite   fti_un.fti_un_readwrite
+#define        fti_data        fti_un.fti_un_data
+#define        fti_dataend     fti_un.fti_un_dataend
+#define        fti_cancel      fti_un.fti_un_cancel
+#define        fti_transend    fti_un.fti_un_transend
+};
+    
+/* when FTAMindication has PSAPdata, the pe_context indicates whether
+   each data is from the FTAM PCI or is a data element.
+
+       FTAM PCI        - PE_DFLT_CTX
+
+       data element    - anything else
+
+   three different types of data in the FTAM PCI are handled by the user:
+
+       Node-Descriptor-Data-Element ::=        [APPLICATION 0] ...
+       Enter-Subtree-Data-Element ::=          [APPLICATION 1] ...
+       Exit-Subtree-Data-Element ::=           [APPLICATION 2] ...
+ */
+
+#define        FADU_NODESCR    0       /* Node-Descriptor-Data-Element */
+#define        FADU_ENTERTREE  1       /* Enter-Subtree-Data-Element */
+#define        FADU_EXITREE    2       /* Exit-Subtree-Data-Element */
+
+/* \f */
+
+extern char *ftamversion;
+
+extern LLog _ftam_log, *ftam_log;
+
+
+int    FInit ();               /* F-INITIALIZE.INDICATION */
+int    FInitializeResponse (); /* F-INITIALIZE.RESPONSE */
+int    FInitializeRequest ();  /* F-INITIALIZE.REQUEST */
+int    FTerminateRequest ();   /* F-TERMINATE.REQUEST */
+int    FTerminateResponse ();  /* F-TERMINATE.RESPONSE */
+int    FUAbortRequest ();      /* F-U-ABORT.REQUEST */
+
+int    FWaitRequest ();        /* F-WAIT.REQUEST (pseudo) */
+
+int    FManageRequest ();      /* F-MANAGE.REQUEST (group) */
+int    FManageResponse ();     /* F-MANAGE.RESPONSE (group) */
+int    FBulkBeginRequest ();   /* F-BULK-BEGIN.REQUEST (group) */
+int    FBulkBeginResponse ();  /* F-BULK-BEGIN.RESPONSE (group) */
+int    FBulkEndRequest ();     /* F-BULK-END.REQUEST (group) */
+int    FBulkEndResponse ();    /* F-BULK-END.RESPONSE (group) */
+
+int    FAccessRequest ();      /* F-{LOCATE,ERASE}.REQUEST */
+int    FAccessResponse ();     /* F-{LOCATE,ERASE}.RESPONSE */
+
+int    FReadWriteRequest ();   /* F-{READ,WRITE}.REQUEST */
+int    FDataRequest ();        /* F-DATA.REQUEST */
+int    FDataEndRequest ();     /* F-DATA-END.REQUEST */
+int    FCancelRequest ();      /* F-CANCEL.REQUEST */
+int    FCancelResponse ();     /* F-CANCEL.RESPONSE */
+int    FTransEndRequest ();    /* F-TRANSFER-END.REQUEST */
+int    FTransEndResponse ();   /* F-TRANSFER-END.RESPONSE */
+
+int    FSetIndications ();     /* define vector for INDICATION events */
+int    FSelectMask ();         /* map ftam descriptors for select() */
+
+int    FHookRequest ();        /* set tracing */
+int    FTraceHook ();          /* user-defined tracing */
+
+char   *FErrString ();         /* return FTAM error code in string form */
+
+/* \f */
+
+struct isodocument {
+    char   *id_entry;
+
+    OID            id_type;
+
+    OID            id_abstract;
+    OID            id_transfer;
+    OID            id_model;
+    OID            id_constraint;
+};
+
+int    setisodocument (), endisodocument ();
+
+struct isodocument *getisodocument ();
+
+struct isodocument *getisodocumentbyentry ();
+struct isodocument *getisodocumentbytype ();
+
+#endif
diff --git a/src/isode/h/general.h b/src/isode/h/general.h
new file mode 100644 (file)
index 0000000..feaa247
--- /dev/null
@@ -0,0 +1,293 @@
+/* general.h - general compatibility */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:17  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:42  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.3  1994/06/07 23:08:23  eichin
+ * hide calloc/malloc/realloc from ultrix too
+ *
+ * Revision 1.1  1994/05/31 20:37:55  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:44  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _GENERAL_
+#define        _GENERAL_
+
+#ifndef        _CONFIG_
+#include "config.h"            /* system-specific configuration */
+#endif
+
+
+/* target-dependent defines:
+
+       BSDFORK -       target has BSD vfork
+       BSDLIBC -       target has real BSD libc
+       BSDSTRS -       target has BSD strings
+       SWABLIB -       target has byteorder(3n) routines
+ */
+
+#ifdef SOCKETS
+#define        SWABLIB
+#endif
+
+#ifdef WINTLI
+#define        SWABLIB
+#endif
+
+#ifdef EXOS
+#define        SWABLIB
+#endif
+
+
+#ifdef BSD42
+#define        BSDFORK
+#define        BSDLIBC
+#define        BSDSTRS
+#endif
+
+#ifdef  SVR4_UCB
+#ifndef SVR4
+#define SVR4
+#endif
+#endif
+
+#ifdef  SVR4
+#ifndef SVR3
+#define SVR3
+#endif
+#endif
+
+#ifdef ROS
+#undef BSDFORK
+#undef BSDLIBC
+#define        BSDSTRS
+#ifndef        BSD42
+#define        BSD42
+#endif
+#undef SWABLIB
+#endif
+
+#ifdef SYS5
+#undef BSDFORK
+#undef BSDLIBC
+#undef BSDSTRS
+#endif
+
+#ifdef sgi
+#undef BSDFORK
+#undef BSDLIBC
+#undef BSDSTRS
+#endif
+
+#ifdef HPUX
+#define        BSDFORK
+#undef BSDLIBC
+#undef BSDSTRS
+#undef SWABLIB
+#endif
+
+#ifdef pyr
+#undef SWABLIB
+#endif
+
+#ifdef XOS
+#undef SWABLIB
+#endif
+
+#ifdef XOS_2
+#undef SWABLIB
+#endif
+
+#ifdef  apollo
+#undef  SWABLIB
+#endif
+
+#ifdef AUX
+#undef BSDFORK
+#define BSDSTRS
+#undef SWABLIB
+#define BSDLIBC
+#endif 
+
+#ifndef        BSDFORK
+#define        vfork   fork
+#endif
+
+/* \f   STRINGS */
+
+#ifdef SVR4
+#include <stdio.h>
+#include <stdlib.h>
+
+#else /* SVR4 */
+
+/* sprintf already defined in stdio.h on SunOS 4.1.1 -- SJL
+#if    defined(BSDSTRS) && !defined(BSD44) && (!defined(BSD43) || defined(SUNOS4) || defined(vax) || defined(RT) || (defined(mips) && defined(ultrix))) && !defined(XOS_2)
+#if !(defined(__STDC__) && defined(__GNUC__) && defined(mips) && defined(ultrix))
+char   *sprintf ();
+#endif
+#else
+int     sprintf ();
+#endif
+ */
+
+char   *getenv ();
+char   *mktemp ();
+
+#endif /* SVR4 */
+
+#ifdef __STDC__
+#include <malloc.h>
+#else
+#ifndef _AIX
+#ifndef mips
+char   *calloc (), *malloc (), *realloc ();
+#endif
+#endif
+#endif
+
+
+#ifndef        BSDSTRS
+#ifndef AIX
+#define        index   strchr
+#define        rindex  strrchr
+#endif
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+#if    defined(SYS5) && !defined(AIX) && !defined(XOS) && !defined(XOS_2)
+#include <memory.h>
+
+#define        bcopy(b1,b2,length)     (void) memcpy ((b2), (b1), (length))
+#define        bcmp(b1,b2,length)      memcmp ((b1), (b2), (length))
+#define        bzero(b,length)         (void) memset ((b), 0, (length))
+#endif
+/* \f   HEXIFY */
+
+int    explode (), implode ();
+
+/* \f   SPRINTB */
+
+char   *sprintb ();
+
+/* \f   STR2VEC */
+
+#define        NVEC    100
+#define        NSLACK  10
+
+
+#define        str2vec(s,v)    str2vecX ((s), (v), 0, NULLIP, NULL, 1)
+
+int    str2vecX ();
+
+/* \f   STR2ELEM */
+
+#define        NELEM   20
+
+int    str2elem ();
+
+/* \f   STR2SEL */
+
+int    str2sel ();
+char   *sel2str ();
+
+/* \f   GETPASS */
+
+char   *getpassword ();
+
+/* \f   BADUSER */
+
+int    baduser ();
+
+/* \f  UTILITIES */
+
+extern char chrcnv[], nochrcnv[];
+
+
+int    lexequ (), lexnequ ();
+
+int    log_tai ();
+
+int    sstr2arg ();
+
+char    *smalloc (), *strdup ();
+
+/* \f   MISC */
+
+char   *sys_errname ();
+
+#ifdef lint
+#define        insque(e,p)     INSQUE ((char *) (e), (char *) (p))
+#define        remque(e)       REMQUE ((char *) (e))
+#endif
+
+
+void   asprintf (), _asprintf ();
+
+void   isodetailor ();         /* also in tailor.h */
+
+
+/* \f time */
+
+#ifndef makedev
+#include <sys/types.h>
+#endif
+#ifndef        OSX
+#ifndef        BSD42
+#include <time.h>
+#else
+#ifndef        timerisset
+#include <sys/time.h>
+#endif
+#endif
+#endif
+
+#ifndef __STDC__
+extern time_t time ();
+#endif
+
+
+/* \f ntohs etc */
+
+#ifndef linux
+#ifndef        ntohs
+unsigned short ntohs ();
+#endif
+#ifndef        htons
+unsigned short htons ();
+#endif
+#ifndef        ntohl
+unsigned long  ntohl ();
+#endif
+#ifndef        htonl
+unsigned long  htonl ();
+#endif
+#endif
+
+#endif
diff --git a/src/isode/h/internet.h b/src/isode/h/internet.h
new file mode 100644 (file)
index 0000000..6d9947b
--- /dev/null
@@ -0,0 +1,186 @@
+/* internet.h - TCP/IP abstractions */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:19  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:43  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:56  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:45  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _INTERNET_
+#define        _INTERNET_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+
+/* \f   SOCKETS */
+
+#include "sys/socket.h"
+
+#ifndef        SOMAXCONN
+#define        SOMAXCONN       5
+#endif
+
+#if    defined(WIN) || defined(WINTLI)
+#include "sys/in.h"
+#else
+
+#ifdef SVR4    /* Has a different defn for NULLVP */
+#ifdef NULLVP 
+#undef NULLVP
+#endif
+#endif /* SVR4 */
+#include "netinet/in.h"
+#ifdef SVR4    /* Put back the ISODE defn */
+#ifdef NULLVP
+#undef NULLVP
+#endif
+#define NULLVP ((char **) 0)
+#endif /* SVR4 */
+
+#endif /* defined(WIN) || defined(WINTLI) */
+
+int    start_tcp_client ();
+int    start_tcp_server ();
+
+#ifdef SOCKETS
+int    join_tcp_client ();
+int    join_tcp_server ();
+
+#define        read_tcp_socket         read
+#define        write_tcp_socket        write
+#define        select_tcp_socket       selsocket
+#endif
+
+#ifdef WINTLI
+int    join_tcp_client ();
+int    join_tcp_server ();
+
+#define        select_tcp_socket       selsocket
+#endif
+
+#ifdef EXOS
+
+#ifdef SYS5
+#define        join_tcp_client(s,f) \
+       (accept ((s), (struct sockaddr *) (f)) != NOTOK ? (s) : NOTOK)
+#define        join_tcp_server(s,t)    connect ((s), (struct sockaddr *) (t))
+
+#define        read_tcp_socket         read
+#define        write_tcp_socket        write
+#define        close_tcp_socket        close
+#define        select_tcp_socket       selsocket
+#endif
+#endif
+
+int    read_tcp_socket ();
+int    write_tcp_socket ();
+int    close_tcp_socket ();
+
+int    select_tcp_socket ();
+
+/* \f   UDP */
+
+#ifdef SOCKETS
+#ifndef        _DGRAM_
+#include "dgram.h"
+#endif
+
+int    start_udp_server ();
+#define        start_udp_client        start_udp_server
+
+#define        join_udp_server(fd,sock) \
+               join_dgram_aux ((fd), (struct sockaddr *) (sock), 0)
+#define        join_udp_client(fd,sock) \
+               join_dgram_aux ((fd), (struct sockaddr *) (sock), 1)
+
+#define        read_udp_socket         read_dgram_socket
+#define        write_udp_socket        write_dgram_socket
+#define        close_udp_socket        close_dgram_socket
+
+#define        select_udp_socket       select_dgram_socket
+#define        check_udp_socket        check_dgram_socket
+#endif
+
+/* \f   NETDB */
+
+#if    defined(SOCKETS) || defined (WINTLI) || defined (WIN)
+#include <netdb.h>
+#endif
+
+
+#if    defined(BIND) && !defined(h_addr)
+#define        h_addr  h_addr_list[0]
+#endif
+
+#define        inaddr_copy(hp,sin) \
+    bcopy ((hp) -> h_addr, (char *) &((sin) -> sin_addr), (hp) -> h_length)
+
+
+#ifdef EXOS
+struct hostent {
+    char   *h_name;            /* official name */
+    char  **h_aliases;         /* alias list */
+    int     h_addrtype;                /* address type: AF_INET */
+    int     h_length;          /* address length: sizeof (u_long) == 4 */
+    char   *h_addr;            /* address value: (struct in_addr *) */
+};
+
+struct servent {
+    char   *s_name;            /* official name */
+    char  **s_aliases;         /* alias list */
+    int     s_port;            /* port number */
+    char   *s_proto;           /* protocol beneath service */
+};
+
+
+struct hostent *gethostbyaddr (), *gethostbyname ();
+struct servent *getservbyname ();
+#endif
+
+
+struct hostent *gethostbystring ();
+
+/* \f   INET */
+
+/* under BSD42, we could simply include <arpa/inet.h> instead.  However,
+   the definition of inet_addr contained therein causes problems with some
+   compilers. */
+
+char   *inet_ntoa ();
+#ifndef        DG
+u_long inet_addr ();
+#ifndef        HPUX
+u_long inet_network ();
+#else
+int    inet_network ();
+#endif
+#else
+struct in_addr inet_addr (), inet_network ();
+#endif
+#endif
diff --git a/src/isode/h/isoaddrs.h b/src/isode/h/isoaddrs.h
new file mode 100644 (file)
index 0000000..baf0315
--- /dev/null
@@ -0,0 +1,287 @@
+/* isoaddrs.h - ISODE addressing */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:21  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:45  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:37:58  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:45  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _ISOADDRS_
+#define        _ISOADDRS_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+
+/* \f */
+
+#ifdef NULLPE
+typedef struct AEInfo {                /* "real" directory services! */
+    PE     aei_ap_title;
+    PE     aei_ae_qualifier;
+
+    int            aei_ap_id;
+    int            aei_ae_id;
+
+    int            aei_flags;
+#define        AEI_NULL        0x00
+#define        AEI_AP_ID       0x01
+#define        AEI_AE_ID       0x02
+}      AEInfo, *AEI;
+#define        NULLAEI         ((AEI) 0)
+#define        AEIFREE(aei) { \
+    if ((aei) -> aei_ap_title) \
+       pe_free ((aei) -> aei_ap_title), \
+           (aei) -> aei_ap_title = NULLPE; \
+    if ((aei) -> aei_ae_qualifier) \
+       pe_free ((aei) -> aei_ae_qualifier), \
+           (aei) -> aei_ae_qualifier = NULLPE; \
+}
+
+#define        str2aei(d,q)    _str2aei ((d), (q), NULLCP, 0, NULLCP, NULLCP)
+#define        str2aeinfo(string,context,interactive,userdn,passwd) \
+       _str2aei ((string), NULLCP, (context), (interactive), (userdn), \
+                 (passwd))
+AEI    _str2aei ();
+
+char   *sprintaei ();
+#endif
+
+/* \f */
+
+struct NSAPaddr {              /* this structure shouldn't have holes in it */
+    long     na_stack;                 /* TS-stack */
+#define        NA_NSAP 0                       /*   native COTS */
+#define        NA_TCP  1                       /*   RFC1006/TCP */
+#define        NA_X25  2                       /*   TP0/X.25 */
+#define        NA_BRG  3                       /*   TP0-bridge */
+
+    long    na_community;              /* internal community # */
+#define        SUBNET_REALNS           (-1)    /* hard-wired */
+#define        SUBNET_INT_X25          1       
+/* (unused)
+#define        SUBNET_JANET            2
+ */
+#define        SUBNET_INTERNET         3
+#define        SUBNET_DYNAMIC          100     /* dynamic start here... */
+
+    union {
+       struct na_nsap {                /* real network service */
+#define        NASIZE  64                      /* 20 ought to do it */
+           char    na_nsap_address[NASIZE];
+           char    na_nsap_addrlen;
+       }               un_na_nsap;
+
+       struct na_tcp {                 /* emulation via RFC1006 */
+#define        NSAP_DOMAINLEN  63
+           char    na_tcp_domain[NSAP_DOMAINLEN + 1];
+
+           u_short na_tcp_port;        /* non-standard TCP port */
+           u_short na_tcp_tset;        /* transport set */
+#define        NA_TSET_TCP     0x0001          /*   .. TCP */
+#define        NA_TSET_UDP     0x0002          /*   .. UDP */
+       }               un_na_tcp;
+
+       struct na_x25 {                 /* X.25 (assume single subnet) */
+#define        NSAP_DTELEN     36
+           char    na_x25_dte[NSAP_DTELEN + 1]; /* Numeric DTE + Link */
+           char    na_x25_dtelen;      /* number of digits used */
+
+/* Conventionally, the PID sits at the first head bytes of user data and so
+ * should probably not be mentioned specially. A macro might do it, if
+ * necessary.
+ */
+
+#define        NPSIZE  4
+           char    na_x25_pid[NPSIZE]; /* X.25 protocol id */
+           char    na_x25_pidlen;      /*   .. */
+
+#define        CUDFSIZE 16
+           char    na_x25_cudf[CUDFSIZE];/* call user data field */
+           char    na_x25_cudflen;     /* .. */
+/*
+ * X25 Facilities field. 
+ */
+#define        FACSIZE 6
+           char    na_x25_fac[FACSIZE];        /* X.25 facilities */
+           char    na_x25_faclen;              /*   .. */
+       }               un_na_x25;
+    }               na_un;
+#define        na_address      na_un.un_na_nsap.na_nsap_address
+#define        na_addrlen      na_un.un_na_nsap.na_nsap_addrlen
+
+#define        na_domain       na_un.un_na_tcp.na_tcp_domain
+#define        na_port         na_un.un_na_tcp.na_tcp_port
+#define        na_tset         na_un.un_na_tcp.na_tcp_tset
+
+#define        na_dte          na_un.un_na_x25.na_x25_dte
+#define        na_dtelen       na_un.un_na_x25.na_x25_dtelen
+#define        na_pid          na_un.un_na_x25.na_x25_pid
+#define        na_pidlen       na_un.un_na_x25.na_x25_pidlen
+#define        na_cudf         na_un.un_na_x25.na_x25_cudf
+#define        na_cudflen      na_un.un_na_x25.na_x25_cudflen
+#define        na_fac          na_un.un_na_x25.na_x25_fac
+#define        na_faclen       na_un.un_na_x25.na_x25_faclen
+
+/* for backwards compatibility... these two will be removed after ISODE 7.0 */
+#define        na_type         na_stack
+#define        na_subnet       na_community
+};
+#define        NULLNA                  ((struct NSAPaddr *) 0)
+
+
+struct TSAPaddr {
+#define        NTADDR  8                       /* according to NIST OIW */
+    struct NSAPaddr ta_addrs[NTADDR];  /* choice of network addresses */
+    int     ta_naddr;
+
+#define        TSSIZE  64
+    int            ta_selectlen;
+
+    union un_ta_type {                         /* TSAP selector */
+       char    ta_un_selector[TSSIZE];
+
+       u_short ta_un_port;
+    }               un_ta;
+#define        ta_selector     un_ta.ta_un_selector
+#define        ta_port         un_ta.ta_un_port
+};
+#define        NULLTA                  ((struct TSAPaddr *) 0)
+
+
+struct SSAPaddr {
+    struct TSAPaddr sa_addr;           /* transport address */
+
+#define        SSSIZE  64
+    int            sa_selectlen;
+
+    union {                            /* SSAP selector */
+       char    sa_un_selector[SSSIZE];
+
+       u_short sa_un_port;
+    }               un_sa;
+#define        sa_selector     un_sa.sa_un_selector
+#define        sa_port         un_sa.sa_un_port
+};
+#define        NULLSA                  ((struct SSAPaddr *) 0)
+
+
+struct PSAPaddr {
+    struct SSAPaddr pa_addr;           /* session address */
+
+#define        PSSIZE  64
+    int            pa_selectlen;
+
+    union {                            /* PSAP selector */
+       char    pa_un_selector[PSSIZE];
+
+       u_short pa_un_port;
+    }               un_pa;
+#define        pa_selector     un_pa.pa_un_selector
+#define        pa_port         un_pa.pa_un_port
+};
+#define        NULLPA                  ((struct PSAPaddr *) 0)
+
+struct PSAPaddr *aei2addr ();  /* application entity title to PSAPaddr */
+
+/* \f */
+
+#ifdef NULLPE
+char   *alias2name ();
+
+extern PE    (*acsap_lookup) ();
+#endif
+
+
+#ifdef NULLOID
+struct isoentity {             /* for stub directory service */
+    OIDentifier ie_identifier;
+    char    *ie_descriptor;
+
+    struct PSAPaddr ie_addr;
+};
+
+int    setisoentity (), endisoentity ();
+
+struct isoentity *getisoentity ();
+
+AEI    oid2aei ();
+#endif
+
+
+                               /* old-style */
+struct PSAPaddr *is2paddr ();  /* service entry to PSAPaddr */
+struct SSAPaddr *is2saddr ();  /* service entry to SSAPaddr */
+struct TSAPaddr *is2taddr ();  /* service entry to TSAPaddr */
+
+/* \f */
+
+struct PSAPaddr *str2paddr ();  /* string encoding to PSAPaddr */
+struct SSAPaddr *str2saddr ();  /* string encoding to SSAPaddr */
+struct TSAPaddr *str2taddr ();  /* string encoding to TSAPaddr */
+
+#define        paddr2str(pa,na)        _paddr2str ((pa), (na), 0)
+
+char   *_paddr2str ();         /* PSAPaddr to string encoding */
+char   *saddr2str ();          /* SSAPaddr to string encoding */
+char   *taddr2str ();          /* TSAPaddr to string encoding */
+
+struct NSAPaddr *na2norm ();   /* normalize NSAPaddr */
+
+char   *na2str ();             /* pretty-print NSAPaddr */
+char   *pa2str ();             /* pretty-print PSAPaddr */
+
+/* \f */
+
+int    isodeserver ();         /* generic server dispatch */
+
+int    iserver_init ();        /* phase 1 */
+int    iserver_wait ();        /* phase 2 */
+fd_set iserver_mask ();        /* linkage */
+
+/* \f */
+
+/* all of this really should be in "isoqos.h" ... */
+   
+struct QOStype {
+                               /* transport QOS */
+    int            qos_reliability;    /* "reliability" element */
+#define        HIGH_QUALITY    0
+#define        LOW_QUALITY     1
+
+                               /* session QOS */
+    int            qos_sversion;       /* session version required */
+    int            qos_extended;       /* extended control */
+    int            qos_maxtime;        /* for SPM response during S-CONNECT */
+};
+#define        NULLQOS ((struct QOStype *) 0)
+
+#endif
diff --git a/src/isode/h/isoservent.h b/src/isode/h/isoservent.h
new file mode 100644 (file)
index 0000000..02c7c8a
--- /dev/null
@@ -0,0 +1,64 @@
+/* isoservent.h - ISODE services database access routines */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:23  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:47  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:00  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:46  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _ISOSERVENT_
+#define        _ISOSERVENT_
+
+
+struct isoservent {
+    char         *is_entity;   /* name of entity */
+    char         *is_provider; /* name of service provider */
+
+#define        ISSIZE  64              /* xSAP selector/ID */
+    int                  is_selectlen;
+    union {
+       char            is_un_selector[ISSIZE];
+       unsigned short  is_un_port;
+    }          un_is;
+#define        is_selector     un_is.is_un_selector
+#define        is_port         un_is.is_un_port
+
+    char        **is_vec;      /* exec vector */
+    char        **is_tail;     /* next free slot in vector */
+};
+
+
+int    setisoservent (), endisoservent ();
+
+struct isoservent *getisoservent ();
+
+struct isoservent *getisoserventbyname ();
+struct isoservent *getisoserventbyselector ();
+struct isoservent *getisoserventbyport ();
+
+#endif
diff --git a/src/isode/h/logger.h b/src/isode/h/logger.h
new file mode 100644 (file)
index 0000000..81e2e3b
--- /dev/null
@@ -0,0 +1,178 @@
+/* logger.h - logging routines */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:24  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:50  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:02  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:46  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _LOGGER_
+#define        _LOGGER_
+
+#include "manifest.h"
+
+/* \f */
+
+typedef struct  ll_struct {
+    char   *ll_file;           /* path name to logging file */
+
+    char   *ll_hdr;            /* text to put in opening line */
+    char   *ll_dhdr;           /* dynamic header - changes */
+
+    int            ll_events;          /* interesting events */
+#define        LLOG_NONE       0
+#define        LLOG_FATAL      0x01    /*   fatal errors */
+#define        LLOG_EXCEPTIONS 0x02    /*   exceptional events */
+#define        LLOG_NOTICE     0x04    /*   informational notices */
+#define        LLOG_PDUS       0x08    /*   PDU printing */
+#define        LLOG_TRACE      0x10    /*   program tracing */
+#define        LLOG_DEBUG      0x20    /*   full debugging */
+#define        LLOG_ALL        0xff
+#define        LLOG_MASK \
+    "\020\01FATAL\02EXCEPTIONS\03NOTICE\04PDUS\05TRACE\06DEBUG"
+
+    int            ll_syslog;          /* interesting events to send to syslog */
+                               /*   takes same values as ll_events */
+
+    int     ll_msize;          /* max size for log, in Kbytes */
+
+    int     ll_stat;           /* assorted switches */
+#define        LLOGNIL         0x00
+#define        LLOGCLS         0x01    /*   keep log closed, except when writing */
+#define        LLOGCRT         0x02    /*   create log if necessary */
+#define        LLOGZER         0x04    /*   truncate log when limits reached */
+#define        LLOGERR         0x08    /*   log closed due to (soft) error */
+#define        LLOGTTY         0x10    /*   also log to stderr */
+#define        LLOGHDR         0x20    /*   static header allocated */
+#define        LLOGDHR         0x40    /*   dynamic header allocated */
+
+    int     ll_fd;             /* file descriptor */
+} LLog;
+
+/* \f */
+
+#define        SLOG(lp,event,what,args) \
+if (lp -> ll_events & (event)) { \
+    (void) ll_log (lp, event, what, "%s", ll_preset args); \
+} \
+else
+
+#ifndef        LLOG
+#define        LLOG(lp,event,args)     SLOG (lp, event, NULLCP, args)
+#endif
+
+#ifdef DEBUG
+#define        DLOG(lp,event,args)     SLOG (lp, event, NULLCP, args)
+#else
+#define        DLOG(lp,event,args)
+#endif
+
+
+#ifdef DEBUG
+
+#ifdef PEPSY_VERSION
+
+#ifdef __STDC__
+
+#define        PLOGP(lp,args,pe,text,rw) \
+    if ((lp) -> ll_events & LLOG_PDUS) { \
+       pvpdu (lp, print_##args##_P, pe, text, rw); \
+    } \
+    else
+
+#define        PLOG(lp,fnx,pe,text,rw) \
+    if ((lp) -> ll_events & LLOG_PDUS) { \
+       pvpdu (lp, fnx##_P, pe, text, rw); \
+    } \
+    else
+
+#else
+
+#define        PLOGP(lp,args,pe,text,rw) \
+    if ((lp) -> ll_events & LLOG_PDUS) { \
+       pvpdu (lp, print_/* */args/* */_P, pe, text, rw); \
+    } \
+    else
+
+#define        PLOG(lp,fnx,pe,text,rw) \
+    if ((lp) -> ll_events & LLOG_PDUS) { \
+       pvpdu (lp, fnx/* */_P, pe, text, rw); \
+    } \
+    else
+
+#endif
+
+#else  /* !PEPSY_VERSION */
+
+#define        PLOG(lp,fnx,pe,text,rw) \
+    if ((lp) -> ll_events & LLOG_PDUS) { \
+       vpdu (lp, fnx, pe, text, rw); \
+    } \
+    else
+
+#endif /* !PEPSY_VERSION */
+
+#ifdef lint
+#undef PLOGP
+#define        pvpdu(lp,cookie,pe,text,rw) \
+       _pvpdu(lp, pe, text, rw)
+#define        PLOGP(lp,args,pe,text,rw) \
+       _pvpdu (lp, pe, text, rw);
+#endif
+
+#ifndef PLOGP
+#define        PLOGP(lp,args,pe,text,rw) \
+    if ((lp) -> ll_events & LLOG_PDUS) { \
+       pvpdu (lp, 0, (struct modtype *) 0, pe, text, rw); \
+    } \
+    else
+#endif
+
+#else  /* !DEBUG */
+#define        PLOG(lp,fnx,pe,text,rw)
+#define        PLOGP(lp,args,pe,text,rw)
+#endif
+
+
+int    ll_open ();
+int    ll_log (), _ll_log ();
+int    ll_close ();
+
+void   ll_hdinit ();
+void   ll_dbinit ();
+
+int    ll_printf ();
+int    ll_sync ();
+
+char   *ll_preset ();
+
+int    ll_check ();
+
+int    ll_defmhdr ();
+IFP    ll_setmhdr ();
+#endif
diff --git a/src/isode/h/manifest.h b/src/isode/h/manifest.h
new file mode 100644 (file)
index 0000000..d727184
--- /dev/null
@@ -0,0 +1,344 @@
+/* manifest.h - manifest constants */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:51  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.4  1994/06/03 06:44:53  eichin
+ * put sys/select.h in correct place
+ *
+ * Revision 1.2  1994/06/03 00:55:09  eichin
+ * new configury (to copy headers to correct place)
+ * tweak NULLVP to work under svr4
+ *
+ * Revision 1.1  1994/05/31 20:38:06  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:47  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _MANIFEST_
+#define        _MANIFEST_
+
+                       /* current ISODE distribution: major*10+minor */
+#define        ISODE   70
+
+#ifndef        _CONFIG_
+#include "config.h"            /* system-specific configuration */
+#endif
+
+
+/* target-dependent defines:
+
+       SYS5NLY -       target has SYS5 types only, no BSD types
+
+       BSDSIGS -       target supports BSD signals
+
+ */
+
+#ifdef BSD42
+#undef SYS5NLY
+#define        BSDSIGS
+#endif 
+
+
+#ifdef ROS
+#undef SYS5NLY
+#define        BSDSIGS
+
+#ifndef        BSD42
+#define        BSD42
+#endif
+
+#endif
+
+
+#ifdef SYS5
+#define        SYS5NLY
+#undef BSDSIGS
+
+#ifdef mc68000
+#undef SYS5NLY
+#endif
+
+#ifdef OSX
+#undef SYS5NLY
+#endif
+
+#ifdef XOS_2
+#undef SYS5NLY
+#define        SIGEMT  SIGSEGV
+#endif
+
+#if    defined(WIN) || defined (WINTLI)
+#undef SYS5NLY
+#endif
+
+#ifdef sun
+#undef SYS5NLY
+#endif
+
+#ifdef linux
+#undef SYS5NLY
+#endif
+
+#ifdef sgi
+#undef SYS5NLY
+#endif
+
+#ifdef SVR4
+#undef  SYS5NLY
+#endif
+
+#ifdef HPUX
+#undef SYS5NLY
+#define        BSDSIGS
+#undef SIGPOLL
+#endif
+
+#ifdef AIX
+#undef SYS5NLY
+#define        BSDSIGS
+#define        SIGEMT  SIGUSR1
+
+
+int   (*_signal ()) ();
+
+#define        signal  _signal
+#endif
+
+#ifdef AUX
+#undef SYS5NLY
+#define BSDSIGS
+#endif
+#endif
+
+#ifdef  SVR4
+#ifndef SVR3
+#define SVR3
+#endif
+#endif
+
+
+#ifdef NSIG
+
+#ifndef        sigmask
+#define        sigmask(s)      (1 << ((s) - 1))
+#endif
+
+#ifdef XOS_2
+#define _SIGIO SIGEMT
+#else
+#ifdef SIGPOLL
+#define        _SIGIO  SIGPOLL
+#else
+#ifdef SIGUSR1
+#define        _SIGIO  SIGUSR1
+#else
+#define        _SIGIO  SIGEMT
+#endif
+#endif
+#endif
+
+typedef        int     SBV;
+#ifndef        lint
+#define        sigioblock()    (_iosignals_set ? sigblock (sigmask (_SIGIO)) : 0)
+#define        sigiomask(s)    (_iosignals_set ? sigsetmask (s) : 0)
+#else
+#define        sigioblock()    sigblock (sigmask (_SIGIO))
+#define        sigiomask(s)    sigsetmask (s)
+#endif
+extern int _iosignals_set;
+
+#define        siginblock()    sigblock (sigmask (SIGINT))
+#define        siginmask(s)    sigsetmask (s)
+
+#endif
+
+/* \f   TYPES */
+
+#ifndef        NOTOK
+#define        NOTOK           (-1)
+#define        OK              0
+#define        DONE            1
+#define CONNECTING_1   OK
+#define CONNECTING_2   2
+#endif
+
+#ifdef SVR4
+#ifdef NULLVP
+#undef NULLVP
+#endif
+#endif
+
+#ifdef linux
+/*
+ * Unfortunately, ISODE assumes that NULL is 0, instead of ((void *) 0).
+ * This is wrong, but it's simpler to redefine NULL than to try to
+ * make all of the changes necessary to fix ISODE.  Sigh....
+ */
+#undef NULL
+#define NULL 0
+#endif
+
+#ifndef        NULLCP
+typedef char *CP;
+#define        NULLCP          ((char *) 0)
+#ifndef NULLVP
+#define        NULLVP          ((char **) 0)
+#endif
+#endif
+
+#ifndef INTDEF
+#define        INTDEF  long
+#endif
+
+typedef INTDEF integer;
+#define NULLINT                ((integer) 0)
+#define NULLINTP       ((integer *) 0)
+
+#ifndef        makedev
+#include <sys/types.h>
+#if    defined(WIN) || defined(WINTLI)
+#include "sys/inet.h"
+#ifndef        NFDBITS
+typedef struct fd_set { int fds_bits[1]; } fd_set;
+#endif
+#endif
+
+#ifdef SYS5NLY
+typedef unsigned char  u_char;
+typedef unsigned short u_short;
+typedef unsigned int   u_int;
+typedef unsigned long  u_long;
+#endif
+#endif
+
+#ifdef AIX
+/* needed for fd_set under AIX --eichin */
+#include <sys/select.h>
+#endif
+
+#ifndef linux
+#ifndef FD_SET
+#define        FD_SETSIZE          (sizeof (fd_set) * 8)
+
+#define FD_SET(f,s)        ((s)->fds_bits[0] |= (1 << (f)))
+#define FD_CLR(f,s)        ((s)->fds_bits[0] &= ~(1 << (f)))
+#define FD_ISSET(f,s)      ((s)->fds_bits[0] & (1 << (f)))
+#define FD_ZERO(s)         ((s)->fds_bits[0] = 0)
+#endif
+#endif
+
+#define        NULLFD          ((fd_set *) 0)
+
+
+#undef IP
+typedef int    *IP;
+#define        NULLIP          ((IP) 0)
+
+
+typedef        int     (*IFP) ();
+#define        NULLIFP         ((IFP) 0)
+
+
+typedef void   (*VFP) ();
+#define        NULLVFP         ((VFP) 0)
+
+
+#ifndef        SFD
+#if !defined(SVR3) && !defined(SUNOS4) && !defined(BSD44) && !defined(ultrix) && !(defined linux)
+#define        SFD     int
+#define        SFP     IFP
+#else
+#define        SFD     void
+#define        SFP     VFP
+#endif
+#endif
+
+
+struct udvec {                 /* looks like a BSD iovec... */
+    caddr_t uv_base;
+    int            uv_len;
+
+    int            uv_inline;
+};
+
+
+struct qbuf {
+    struct qbuf *qb_forw;      /* doubly-linked list */
+    struct qbuf *qb_back;      /*   .. */
+
+    int            qb_len;             /* length of data */
+    char   *qb_data;           /* current pointer into data */
+    char    qb_base[1];                /* extensible... */
+};
+
+#define        QBFREE(qb) \
+{ \
+    register struct qbuf *QB, \
+                        *QP; \
+ \
+    for (QB = (qb) -> qb_forw; QB != (qb); QB = QP) { \
+       QP = QB -> qb_forw; \
+       remque (QB); \
+       free ((char *) QB); \
+    } \
+}
+
+
+#ifndef        min
+#define        min(a, b)       ((a) < (b) ? (a) : (b))
+#define        max(a, b)       ((a) > (b) ? (a) : (b))
+#endif
+
+
+#if (defined(SYS5) && !defined(linux))
+
+#if    !defined(WINTLI) && !defined(WIN)
+#ifndef        sun
+#define        getdtablesize() _NFILE
+#endif
+#else
+#define        getdtablesize() (_NFILE - 1)
+#endif
+
+#endif
+
+#if    defined(RT) || defined (HPUX)
+#define        ntohs(x)        (x)
+#define        htons(x)        (x)
+#define        ntohl(x)        (x)
+#define        htonl(x)        (x)
+#endif
+
+/* \f   POSIX */
+
+#ifndef        SETSID
+#if    defined(SUNOS41) || defined(BSD44)
+#define        SETSID
+#endif
+#endif
+
+#endif
diff --git a/src/isode/h/mpkt.h b/src/isode/h/mpkt.h
new file mode 100644 (file)
index 0000000..f6c20ef
--- /dev/null
@@ -0,0 +1,68 @@
+/* mpkt.h - defines the report format for management */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:28  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:53  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:08  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:49  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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"
+
+
+struct MReport {
+    u_short type;
+#define OPREQIN         1
+#define OPREQOUT        2
+#define USERDT          3
+#define USERDR          4
+#define DISCREQ         5
+#define PROTERR         6
+#define CONGEST         7
+#define CONFIGBAD       8
+#define OPREQINBAD      9
+#define OPREQOUTBAD     10
+#define SOURCEADDR      11
+#define        STARTLISTEN     12
+#define        ENDLISTEN       13
+
+    long    id;                /* process id */
+    u_short cid;        /* connection fd */
+
+    union {
+       struct {
+           int a, b, c, d, e, f;
+       } gp;
+
+       struct {
+           int     tsel_len;
+           char    tsel[TSSIZE];
+           struct NSAPaddr nsap;
+       } taddr;
+    } u;
+};
+
+int    TManGen ();
diff --git a/src/isode/h/pepdefs.h b/src/isode/h/pepdefs.h
new file mode 100644 (file)
index 0000000..9d1d211
--- /dev/null
@@ -0,0 +1,56 @@
+/* pepdefs.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:30  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:55  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:10  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:49  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef PEPDEF_DEFINITIONS
+#define PEPDEF_DEFINITIONS
+/*
+ * Globally known pep definitions
+ */
+
+typedef        struct  {
+       char    *md_name;       /* Name of this module */
+       int     md_nentries;    /* Number of entries */
+       tpe     **md_etab;      /* Pointer to encoding tables */
+       tpe     **md_dtab;      /* Pointer to decoding tables */
+       ptpe **md_ptab; /* Pointer to Printing tables */
+       PE      (*md_eucode)(); /* User code for encoding */
+       PE      (*md_ducode)(); /* User code for decoding */
+       PE      (*md_pucode)(); /* User code for printing */
+
+       }       modtyp;
+
+#ifndef NULL
+#define NULL   (char *)0
+#endif
+
+#endif
diff --git a/src/isode/h/pepsy.h b/src/isode/h/pepsy.h
new file mode 100644 (file)
index 0000000..0ac84b4
--- /dev/null
@@ -0,0 +1,237 @@
+/* pepsy.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:32  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:57  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:12  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:50  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef PEPSY_DEFINITIONS
+#define PEPSY_DEFINITIONS
+
+#ifndef        PEPYPARM
+#define PEPYPARM       char *
+#endif
+
+/*
+ * Definitions for pep tables
+ */
+
+#ifdef notdef
+typedef struct {
+       int     pe_type;        /* Type of entry */
+       integer pe_ucode;       /* index to user's code if any */
+       int     pe_tag;         /* Tag of this entry if any */
+       int     pe_flags;       /* Flags */
+}      tpe;
+#define NULLTPE        ((tpe *)0)
+#endif
+
+typedef struct {
+       int     pe_type;        /* Type of entry */
+       integer pe_ucode;       /* index to user's code if any */
+       int     pe_tag;         /* Tag of this entry if any */
+       int     pe_flags;       /* Flags */
+       char **pe_typename; /* User defined name of variable */
+}      ptpe;
+#define tpe ptpe
+#define NULLTPE        ((tpe *)0)
+#define NULLPTPE       ((ptpe *)0)
+
+/* extract a pointer from the pointer table */
+#define GPTR(mod, ind, type)     ((type )(mod)->md_ptrtab[ind])
+/* tricky situation with the "type" - it must not contain the brackets of the
+ * cast because we supply them here 
+ */
+
+/* macros for getting values of default flexibly */
+#define IVAL(mod, x)      ((x)->pe_ucode)         /* Integer value */
+#define PVAL(mod, x)      (GPTR(mod, (x)->pe_tag, char *)) /* (char *) */
+#define TVAL(mod, x)      ((x)->pe_flags)         /* Type - Integer value */
+#define RVAL(mod, x)     (*GPTR(mod, (x)->pe_tag, double *))  /* double */
+
+/* macros for getting the function pointer (for a FN_CALL entry) */
+#define FN_PTR(mod, x)   (*GPTR(mod, (x)->pe_ucode, IFP ))  /* function ptr */
+
+/* macros for getting other more general pointers transparently */
+#define EXT2MOD(mod, x)           (GPTR(mod, (x)->pe_ucode, modtyp *))
+
+/* Types */
+#define PE_START       (-1)
+#define        PE_END          0
+#define XOBJECT                3
+#define        UCODE           6
+#define MEMALLOC       7
+#define        SCTRL           8
+#define        CH_ACT          9
+#define OPTL           10      /* Optionals field offset */
+#define BOPTIONAL      11 /* optional test for next */
+#define FFN_CALL        12 /* call the free function */
+#define FREE_ONLY       13 /* the next item is only for freeing code */
+
+/* types that generate data */
+#define TYPE_DATA      20
+
+#define ANY                    (TYPE_DATA + 0)
+#define INTEGER                (TYPE_DATA + 1)
+#define BOOLEAN                (TYPE_DATA + 2)
+#define OBJECT         (TYPE_DATA + 3)         /* This generates data */
+#define BITSTRING      (TYPE_DATA + 4)
+#define OCTETSTRING    (TYPE_DATA + 5)
+#define SET_START      (TYPE_DATA + 6)
+#define        SEQ_START       (TYPE_DATA + 7)
+#define SEQOF_START    (TYPE_DATA + 8)
+#define SETOF_START    (TYPE_DATA + 9)
+#define CHOICE_START   (TYPE_DATA + 10)
+#define REALTYPE       (TYPE_DATA + 11)        /* ASN.1 Real */
+#define T_NULL         (TYPE_DATA + 12)
+#define T_OID          (TYPE_DATA + 13)
+#define ETAG           (TYPE_DATA + 14) /*so set_find in pr_set is executed*/
+#define IMP_OBJ                (TYPE_DATA + 15) /*so set_find in pr_set is executed*/
+#define EXTOBJ         (TYPE_DATA + 16) /* External reference object */
+#define EXTMOD         (TYPE_DATA + 17) /* External module for above object */
+#define OBJID          (TYPE_DATA + 18) /* Object Identifier */
+#define DFLT_F         (TYPE_DATA + 19)/* Default value for following entry */
+#define DFLT_B         (TYPE_DATA + 20)/* default value for previous entry */
+#define T_STRING       (TYPE_DATA + 21)/* [[ s ptr ]] supporting entry */
+#define OCTET_PTR      (TYPE_DATA + 22)/* [[ o ptr $ len]] str entry */
+#define OCTET_LEN      (TYPE_DATA + 23)/* [[ o ptr $ len]] len entry */
+#define BITSTR_PTR     (TYPE_DATA + 24)/* [[ x ptr $ len]] str entry */
+#define BITSTR_LEN     (TYPE_DATA + 25)/* [[ x ptr $ len]] len entry */
+#define FN_CALL         (TYPE_DATA + 26)/* call a function to do the work */
+
+#if PEPSY_VERSION >= 2
+#define STYPE_DATA     (TYPE_DATA + 50) /* Below here are the S* items */
+#else
+#define STYPE_DATA     (TYPE_DATA + 30) /* Below here are the S* items */
+#endif
+/* Optimised - No indirection to cope with ISODE optimisation */
+#define SBITSTRING     (STYPE_DATA + 0) /* No offset */
+#define SOBJID         (STYPE_DATA + 1) /* Object Identifier - No offset */
+#define SREALTYPE      (STYPE_DATA + 2) /* ASN.1 Real */
+#define SANY           (STYPE_DATA + 3)
+#define SEXTOBJ                (STYPE_DATA + 4) /* External reference object */
+#define SOBJECT                (STYPE_DATA + 5)        /* This generates data */
+#define SOCTETSTRING   (STYPE_DATA + 6) /* No offset */
+#define SEXTERNAL      (STYPE_DATA + 7) /* External to be encoded */
+#define SSEQ_START     (STYPE_DATA + 8) /* SEQUENCE don't indirect */
+#define SSET_START     (STYPE_DATA + 9) /* SET don't do an indirection */
+#define SSEQOF_START   (STYPE_DATA + 10) /* SEQOF - no indirection */
+#define SSETOF_START   (STYPE_DATA + 11) /* SETOF - no indirection */
+#define SCHOICE_START  (STYPE_DATA + 12) /* CHOICE - no indirection */
+
+#define ISDTYPE(p)     (p->pe_type >= TYPE_DATA)
+
+/* User code indexes */
+
+#define NONE           0               /* No User code */
+/* Standard Tags */
+
+#define T_BOOL         1
+#define T_INTEGER      2
+#define T_OCTETSTRING  4
+#define T_OBJIDENT     6
+#define T_EXTERNAL     8
+#define T_REAL         9
+#define T_ENUMERATED   10
+#define T_SEQ          16
+#define T_SET          17
+#define T_IA5          22
+#define T_GRAPHIC      25
+
+/* Flags */
+
+/* Use values 0-3 bottom two bits at the moment */
+/* This has to be changed if the values for the 4 below are changed in ISODE */
+#define FL_CLASS       0xf     
+/* Class specification */
+#define FL_UNIVERSAL   PE_CLASS_UNIV
+#define FL_APPLICATION PE_CLASS_APPL
+#define FL_CONTEXT     PE_CLASS_CONT
+#define FL_PRIVATE     PE_CLASS_PRIV
+
+
+#define FL_IMPLICIT    0100
+#define FL_DEFAULT     0200
+#define FL_OPTIONAL    0400
+
+#define OPTIONAL(p)            ((p)->pe_flags & FL_OPTIONAL)
+#define DEFAULT(p)             ((p)->pe_flags & FL_DEFAULT)
+
+#define FL_PRTAG       01000   /* only for printing - print the tag */
+
+#define PRINT_TAG(p)           ((p)->pe_flags & FL_PRTAG)
+
+#define FL_USELECT     02000   /* user code selects */
+
+#define IF_USELECT(p)          ((p) -> pe_flags & FL_USELECT)
+
+
+#define CLASS(p)       ((PElementClass)((p)->pe_flags & FL_CLASS))
+#define TAG(p)         ((PElementID)((p)->pe_tag))
+
+/* signed version of above - needed for tag == -1 */
+#define STAG(p)                ((p)->pe_tag)
+
+#define TESTBIT(p, bit)        ((p) & (1 << (bit)))
+#define SETBIT(p, bit) ((p) |= (1 << (bit)))
+#define CLRBIT(p, bit) ((p) &= ~(1 << (bit)))
+
+/* To support the OPTIONAL << field $ bitno >> construct */
+#define BITTEST(p, bit)        (((p)[(bit)/8]) & (0x80 >> (bit) % 8))
+#define BITSET(p, bit) (((p)[(bit)/8]) |= (0x80 >> (bit) % 8))
+#define BITCLR(p, bit) (((p)[(bit)/8]) &= ~(0x80 >> (bit) % 8))
+
+/* compute the number of char's required to support x bits */
+#define NBITS2NCHARS(x)                (((x) + 7)/8)
+
+/*
+ * The module table. One per module which gives access to everything one needs
+ * to know about the modules types
+ */
+
+typedef        struct  {
+       char    *md_name;       /* Name of this module */
+       int     md_nentries;    /* Number of entries */
+       tpe     **md_etab;      /* Pointer to encoding tables */
+       tpe     **md_dtab;      /* Pointer to decoding tables */
+       ptpe    **md_ptab;      /* Pointer to printing tables */
+       int     (*md_eucode)(); /* User code for encoding */
+       int     (*md_ducode)(); /* User code for decoding */
+       int     (*md_pucode)(); /* User code for printing */
+       caddr_t *md_ptrtab;     /* pointer table */
+
+       }       modtyp;
+#define NULLMODTYP     ((modtyp *)0)
+
+
+#define        LOTSOFBITS      128
+
+
+int    enc_f (), dec_f (), fre_obj ();
+#endif
diff --git a/src/isode/h/ppkt.h b/src/isode/h/ppkt.h
new file mode 100644 (file)
index 0000000..edd7336
--- /dev/null
@@ -0,0 +1,303 @@
+/* ppkt.h - include file for presentation providers (PS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ * RFC1085 (LPP) support contributed by the Wollongong Group, Inc.
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:33  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:17:59  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:14  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:50  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _PSAP2_
+#include "psap2.h"             /* definitions for PS-USERs */
+#endif
+
+#include "ssap.h"              /* definitinos for SS-USERs */
+
+/* \f */
+
+#define        psapPsig(pb, sd) \
+{ \
+    if ((pb = findpblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_PARAMETER, NULLCP, \
+                           "invalid presentation descriptor"); \
+    } \
+    if (!(pb -> pb_flags & PB_CONN)) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_OPERATION, NULLCP, \
+                           "presentation descriptor not connected"); \
+    } \
+    if (pb -> pb_flags & PB_FINN) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_OPERATION, NULLCP, \
+                           "presentation descriptor finishing"); \
+    } \
+    if (pb -> pb_flags & PB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+}
+
+#define        psapFsig(pb, sd) \
+{ \
+    if ((pb = findpblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_PARAMETER, NULLCP, \
+                           "invalid presentation descriptor"); \
+    } \
+    if (!(pb -> pb_flags & PB_CONN)) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_OPERATION, NULLCP, \
+                           "presentation descriptor not connected"); \
+    } \
+    if (!(pb -> pb_flags & PB_FINN)) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_OPERATION, NULLCP, \
+                           "presentation descriptor not finishing"); \
+    } \
+    if (pb -> pb_flags & PB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return psaplose (pi, PC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+}
+
+#define toomuchP(b,n,m,p) \
+{ \
+    if (b == NULL) \
+       n = 0; \
+    else \
+       if (n > m) \
+           return psaplose (pi, PC_PARAMETER, NULLCP, \
+                           "too many %s user data elements", p); \
+}
+
+#ifdef __STDC__
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return psaplose (pi, PC_PARAMETER, NULLCP, \
+                           "mandatory parameter \"%s\" missing", #p); \
+}
+#else
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return psaplose (pi, PC_PARAMETER, NULLCP, \
+                            "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyPSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyPSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyPSAPdata(base,len,d)        bcopy (base, (char *) d, len)
+#endif
+
+
+#define        pylose(p) \
+       ppktlose (pb, pi, PC_UNRECOGNIZED, (p), NULLCP, "%s", PY_pepy)
+
+
+int    ppktlose (), psaplose ();
+
+/* \f */
+
+#define        DFLT_ASN        "iso asn.1 abstract syntax"
+#define        DFLT_ATN        BER
+
+#if    USE_BUILTIN_OIDS
+#define DFLT_ASN_OID   str2oid ("1.0.8824")
+#define DFLT_ATN_OID   str2oid ("2.1.1")
+#else
+#define DFLT_ASN_OID   ode2oid (DFLT_ASN)
+#define DFLT_ATN_OID   ode2oid (DFLT_ATN)
+#endif
+
+#define        atn_is_ok(pb,atn)       atn_is_ber ((pb), (atn))
+#define        atn_is_ber(pb,atn)      (!oid_cmp (pb -> pb_ber, atn))
+
+
+struct psapblk {
+    struct psapblk *pb_forw;   /* doubly-linked list */
+    struct psapblk *pb_back;   /*   .. */
+
+    int            pb_fd;              /* session descriptor */
+
+    short   pb_flags;          /* our state */
+#define        PB_NULL         0x00
+#define        PB_CONN         0x01    /* connected */
+#define        PB_FINN         0x02    /* other side wants to finish */
+#define        PB_ASYN         0x04    /* asynchronous */
+#define        PB_DFLT         0x10    /* respond with default context result */
+#define        PB_RELEASE      0x20    /* release in progress */
+#define PB_MAGIC       0x40    /* backwards compat hack */
+
+#ifndef        LPP
+    char   *pb_retry;          /* initial/final ppkt */
+    char   *pb_realbase;
+    int            pb_len;
+#else
+    PE      pb_retry;
+    PE     pb_response;
+
+    struct type_PS_SessionConnectionIdentifier *pb_reference;
+
+    PS     pb_stream;
+
+    int            pb_reliability;
+
+    int            pb_maxtries;
+    int            pb_tries;
+#endif
+
+    int            pb_ncontext;        /* presentation context set */
+    struct PSAPcontext pb_contexts[NPCTX];
+
+    OID            pb_asn;             /* default: abstract syntax name */
+    OID            pb_atn;             /*   ..     abstract transfer name */
+    int            pb_dctxid;          /*   ..     id */
+    int            pb_result;          /*          response */
+    
+    OID            pb_ber;             /* BER */
+
+    int            pb_prequirements;   /* presentation requirements */
+
+    int            pb_srequirements;   /* our session requirements */
+    int            pb_urequirements;   /* user's session requirements */
+    int            pb_owned;           /* session tokens we own */
+    int            pb_avail;           /* session tokens available */
+    int            pb_ssdusize;        /* largest atomic SSDU */
+
+#ifdef LPP
+    struct NSAPaddr pb_initiating;     /* initiator */
+#endif
+    struct PSAPaddr pb_responding;     /* responder */
+
+    IFP            pb_DataIndication;          /* INDICATION handlers */
+    IFP            pb_TokenIndication;         /*   .. */
+    IFP            pb_SyncIndication;          /*   .. */
+    IFP            pb_ActivityIndication;      /*   .. */
+    IFP            pb_ReportIndication;        /*   .. */
+    IFP            pb_ReleaseIndication;       /*   .. */
+    IFP            pb_AbortIndication;         /*   .. */
+
+#ifdef LPP
+    IFP            pb_retryfnx;
+    IFP     pb_closefnx;
+    IFP            pb_selectfnx;
+    IFP            pb_checkfnx;
+#endif
+};
+#define        NULLPB          ((struct psapblk *) 0)
+
+int    freepblk ();
+struct psapblk *newpblk (), *findpblk ();
+
+#ifndef        LPP
+#define        PC_PROV_BASE            PC_NOTSPECIFIED
+#define        PC_ABORT_BASE \
+       (PC_UNRECOGNIZED - int_PS_Abort__reason_unrecognized__ppdu)
+#define        PC_REASON_BASE \
+       (PC_ABSTRACT - int_PS_provider__reason_abstract__syntax__not__supported)
+
+
+struct type_PS_User__data *info2ppdu ();
+int    ppdu2info ();
+
+int    info2ssdu (), ssdu2info (), qbuf2info ();
+
+struct qbuf *info2qb ();
+int    qb2info ();
+
+struct type_PS_Identifier__list *silly_list ();
+
+int    ss2pslose (), ss2psabort ();
+
+
+struct pair {
+    int            p_mask;
+    int            p_bitno;
+};
+
+extern struct pair preq_pairs[], sreq_pairs[];
+#endif
+
+/* \f */
+
+#define        REASON_BASE     PC_NOTSPECIFIED
+
+#ifndef        LPP
+#define        PPDU_NONE       (-1)
+#define        PPDU_CP         0
+#define        PPDU_CPA        1
+#define        PPDU_CPR        2
+#define        PPDU_ARU        3
+#define        PPDU_ARP        4
+#define        PPDU_TD         7
+#define        PPDU_RS        12
+#define        PPDU_RSA       13
+#else
+#define        PR_KERNEL       0x0000  /* kernel (yuk) */
+
+#define        NPCTX_PS        2       /* maximum number of contexts */
+#define        NPDATA_PS       1       /* maximum number of PDVs in a request */
+#define        PCI_ROSE        1       /* PCI for SASE using ROSE */
+#define        PCI_ACSE        3       /* PCI for ACSE */
+
+#define        PT_TCP          'T'     /* TCP providing backing */
+#define        PT_UDP          'U'     /* UDP providing backing */
+
+#define        NULLRF  ((struct type_PS_SessionConnectionIdentifier *) 0)
+
+
+#define        pslose(pi,reason) \
+    (reason != PS_ERR_NONE && reason != PS_ERR_IO \
+       ? psaplose ((pi), PC_CONGEST, NULLCP, "%s", ps_error (reason)) \
+       : psaplose ((pi), PC_SESSION, NULLCP, NULLCP))
+
+
+int    pdu2sel (), refcmp ();
+struct SSAPref *pdu2ref ();
+#endif
diff --git a/src/isode/h/psap.h b/src/isode/h/psap.h
new file mode 100644 (file)
index 0000000..2a1ac51
--- /dev/null
@@ -0,0 +1,654 @@
+/* psap.h - include file for presentation users (PS-USER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:00  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:16  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:51  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _PSAP_
+#define        _PSAP_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+#include <math.h>
+
+/* \f */
+
+#ifndef USE_BUILTIN_OIDS
+#define USE_BUILTIN_OIDS       1
+#endif
+
+
+typedef struct OIDentifier {
+    int            oid_nelem;          /* number of sub-identifiers */
+
+    unsigned int *oid_elements;        /* the (ordered) list of sub-identifiers */
+}                      OIDentifier, *OID;
+#define        NULLOID ((OID) 0)
+
+OID    ode2oid ();
+int    oid_cmp (), elem_cmp ();
+OID    oid_cpy ();
+int    oid_free ();
+#define        oid2ode(i)      oid2ode_aux ((i), 1)
+char   *oid2ode_aux ();
+char   *sprintoid ();
+OID    str2oid ();
+
+/* \f */
+
+typedef        u_char     PElementClass;
+
+typedef        u_char     PElementForm;
+
+typedef u_short    PElementID; /* 0..16383 are meaningful (14 bits) */
+#define        PE_ID_BITS      14
+
+#define        PE_ID(class,code) \
+       ((int) ((((code) & 0x3fff) << 2) | ((class) & 0x0003)))
+
+typedef        int        PElementLen;
+
+
+typedef u_char   byte, *PElementData;
+#define        NULLPED ((PElementData) 0)
+
+#define        PEDalloc(s)             ((PElementData) malloc ((unsigned int) (s)))
+
+#define        PEDrealloc(p, s)        ((PElementData) \
+                                   realloc ((char *) (p), (unsigned int) (s)))
+
+#define        PEDfree(p)              free ((char *) (p))
+
+#define        PEDcmp(b1, b2, length)  \
+                       bcmp ((char *) (b1), (char *) (b2), (int) (length))
+
+#define        PEDcpy(b1, b2, length)  \
+                       bcopy ((char *) (b1), (char *) (b2), (int) (length))
+
+/* \f */
+
+typedef struct PElement {
+    int            pe_errno;           /* Error codes */
+#define        PE_ERR_NONE     0       /*   No error */
+#define        PE_ERR_OVER     1       /*   Overflow */
+#define        PE_ERR_NMEM     2       /*   Out of memory */
+#define        PE_ERR_BIT      3       /*   No such bit */
+#define        PE_ERR_UTCT     4       /*   Malformed universal timestring */
+#define        PE_ERR_GENT     5       /*   Malformed generalized timestring */
+#define        PE_ERR_MBER     6       /*   No such member */
+#define        PE_ERR_PRIM     7       /*   Not a primitive form */
+#define        PE_ERR_CONS     8       /*   Not a constructor form */
+#define        PE_ERR_TYPE     9       /*   Class/ID mismatch in constructor */
+#define        PE_ERR_OID      10      /*   Malformed object identifier */
+#define        PE_ERR_BITS     11      /*   Malformed bitstring */
+#define PE_ERR_NOSUPP  12      /*   Type not supported */
+#define        PE_ERR_SIGNED   13      /*   Signed integer not expected */
+
+                               /* for the PSAP */
+    int            pe_context;         /* indirect reference */
+#define        PE_DFLT_CTX     0       /*   the default context */
+
+#define        PE_ID_XTND      0x1f    /* distinguished ID for extension bits */
+#define        PE_ID_MORE      0x80    /* more to come flag */
+#define        PE_ID_MASK      0x7f    /* value in extension byte */
+#define        PE_ID_SHIFT     7
+
+#define        PE_CLASS_MASK   0xc0    /* identifier class bits (8-7) */
+#define        PE_CLASS_SHIFT  6
+#define        PE_FORM_MASK    0x20    /* identifier form bit (6) */
+#define        PE_FORM_SHIFT   5
+#define        PE_CODE_MASK    0x1f    /* identifier code bits (5-1) + ... */
+#define        PE_CODE_SHIFT   0
+
+    PElementClass      pe_class;
+#define        PE_CLASS_UNIV   0x0     /*   Universal */
+#define        PE_CLASS_APPL   0x1     /*   Application-wide */
+#define        PE_CLASS_CONT   0x2     /*   Context-specific */
+#define        PE_CLASS_PRIV   0x3     /*   Private-use */
+
+    PElementForm       pe_form;
+#define        PE_FORM_PRIM    0x0     /*   PRIMitive */
+#define        PE_FORM_CONS    0x1     /*   CONStructor */
+#define        PE_FORM_ICONS   0x2     /*   internal: Inline CONStructor */
+
+    PElementID pe_id;          /* should be extensible, 14 bits for now */
+                               /* Pseudo Types */
+#define        PE_UNIV_EOC     0x000   /*   End-of-contents */
+
+                               /* Built-in Types */
+#define        PE_PRIM_BOOL    0x001   /*   Boolean */
+#define        PE_PRIM_INT     0x002   /*   Integer */
+#define        PE_PRIM_BITS    0x003   /*   Bitstring */
+#define        PE_PRIM_OCTS    0x004   /*   Octetstring */
+#define        PE_PRIM_NULL    0x005   /*   Null */
+#define        PE_PRIM_OID     0x006   /*   Object identifier */
+#define        PE_PRIM_ODE     0x007   /*   Object descriptor */
+#define        PE_CONS_EXTN    0x008   /*   External */
+#define PE_PRIM_REAL   0x009   /*   Real */
+#define PE_PRIM_ENUM   0x00a   /*   Enumerated type */
+#define PE_PRIM_ENCR   0x00b   /*   Encrypted */
+#define        PE_CONS_SEQ     0x010   /*   Sequence */
+#define        PE_CONS_SET     0x011   /*   Set */
+
+                               /* Defined Types */
+#define        PE_DEFN_NUMS    0x012   /*   Numeric String */
+#define        PE_DEFN_PRTS    0x013   /*   Printable String */
+#define        PE_DEFN_T61S    0x014   /*   T.61 String */
+#define        PE_DEFN_VTXS    0x015   /*   Videotex String */
+#define        PE_DEFN_IA5S    0x016   /*   IA5 String */
+#define        PE_DEFN_UTCT    0x017   /*   UTC Time */
+#define        PE_DEFN_GENT    0x018   /*   Generalized Time */
+#define        PE_DEFN_GFXS    0x019   /*   Graphics string (ISO2375) */
+#define        PE_DEFN_VISS    0x01a   /*   Visible string */
+#define        PE_DEFN_GENS    0x01b   /*   General string */
+#define        PE_DEFN_CHRS    0x01c   /*   Character string */
+
+    PElementLen        pe_len;
+#define        PE_LEN_XTND     0x80    /* long or indefinite form */
+#define        PE_LEN_SMAX     127     /* largest short form */
+#define        PE_LEN_MASK     0x7f    /* mask to get number of bytes in length */
+#define        PE_LEN_INDF     (-1)    /* indefinite length */
+
+    PElementLen        pe_ilen;
+
+    union {
+       PElementData     un_pe_prim;    /* PRIMitive value */
+       struct PElement *un_pe_cons;    /* CONStructor head */
+    }                       pe_un1;
+#define        pe_prim pe_un1.un_pe_prim
+#define        pe_cons pe_un1.un_pe_cons
+
+    union {
+       int         un_pe_cardinal;     /* cardinality of list */
+       int         un_pe_nbits;        /* number of bits in string */
+    }                      pe_un2;
+#define        pe_cardinal     pe_un2.un_pe_cardinal
+#define        pe_nbits        pe_un2.un_pe_nbits
+
+    int            pe_inline;          /* for "ultra-efficient" PElements */
+    char   *pe_realbase;       /*   .. */
+
+    int            pe_offset;          /* offset of element in sequence */
+
+    struct PElement *pe_next;
+
+    int            pe_refcnt;          /* hack for ANYs in pepy */
+
+#ifdef DEBUG
+    struct PElement *pe_link;  /* malloc debugging... */
+#endif
+}                      PElement, *PE;
+#define        NULLPE  ((PE) 0)
+#define        NULLPEP ((PE *) 0)
+
+#define        pe_seterr(pe, e, v)     ((pe) -> pe_errno = (e), (v))
+
+
+extern int     pe_allocs;
+extern int     pe_frees;
+extern int     pe_most;
+extern PE      pe_list;
+#ifdef DEBUG
+extern PE      pe_active;
+#endif
+
+PE     pe_alloc ();
+int    pe_free ();
+int    pe_cmp ();
+PE     pe_cpy ();
+int    pe_pullup ();
+PE     pe_expunge ();
+int    pe_extract ();
+
+PE     str2pe ();
+PE     qb2pe ();
+
+extern int    pe_maxclass;
+extern char  *pe_classlist[];
+
+extern int    pe_maxuniv;
+extern char  *pe_univlist[];
+
+extern int    pe_maxappl;
+extern char **pe_applist;
+
+extern int    pe_maxpriv;
+extern char **pe_privlist;
+
+/* \f */
+
+typedef struct UTCtime {
+    int            ut_year;
+    int            ut_mon;
+    int            ut_mday;
+    int            ut_hour;
+    int            ut_min;
+    int            ut_sec;
+
+    int            ut_usec;
+
+    int            ut_zone;
+
+    int            ut_flags;
+#define        UT_NULL         0x00
+#define        UT_ZONE         0x01
+#define        UT_SEC          0x02
+#define        UT_USEC         0x04
+}                      UTCtime, *UTC;
+#define        NULLUTC ((UTC) 0)
+
+
+void   tm2ut ();
+long   gtime ();
+struct tm *ut2tm ();
+
+/* \f */
+
+extern char *psapversion;
+
+
+int    prim2flag ();
+PE     flag2prim ();
+#define        bool2prim(b)            flag2prim ((b), PE_CLASS_UNIV, PE_PRIM_BOOL)
+
+integer        prim2num ();
+PE     num2prim ();
+#define        int2prim(i)             num2prim ((integer) (i), PE_CLASS_UNIV, PE_PRIM_INT)
+
+
+#define        prim2enum(i)            prim2num((i))
+#define enum2prim(a,b,c)       num2prim((a), (b), (c))
+#define enumint2prim(i)                enum2prim ((i), PE_CLASS_UNIV, PE_PRIM_ENUM)
+
+
+/* psap REAL parameters - tons of 'em */
+#define PE_REAL_FLAGS  0300    /* flag bits of real */
+#define        PE_REAL_BINENC  0200    /* binary encoding */
+#define        PE_REAL_DECENC  0000    /* decimal encoding */
+#define        PE_REAL_SPECENC 0100    /* special encoding */
+
+#define PE_REAL_B_S    0100    /* sign bit */
+#define PE_REAL_B_BASE 0060    /* base bits */
+#define        PE_REAL_B_B2    0000
+#define        PE_REAL_B_B8    0020
+#define        PE_REAL_B_B16   0040
+
+#define PE_REAL_B_F    0014    /* factor bits */
+#define PE_REAL_B_EXP  0003    /* exponent type bits */
+#define                PE_REAL_B_EF1   0000
+#define        PE_REAL_B_EF2   0001
+#define                PE_REAL_B_EF3   0002
+#define                PE_REAL_B_EF4   0003
+
+#define        PE_REAL_PLUSINF         0200
+#define PE_REAL_MINUSINF       0201
+
+#ifndef HUGE
+#ifdef MAXFLOAT
+#define PE_REAL_INFINITY       MAXFLOAT
+#else
+#define        PE_REAL_INFINITY        99.e99
+#endif
+#else
+#define PE_REAL_INFINITY       HUGE
+#endif
+
+double prim2real ();
+PE     real2prim ();
+#define double2prim(i)         real2prim ((i), PE_CLASS_UNIV, PE_PRIM_REAL)
+
+
+char   *prim2str ();
+PE     str2prim ();
+struct qbuf *prim2qb ();
+PE     qb2prim_aux ();         /* really should be qb2pe () */
+#define        qb2prim(q,c,i)          qb2prim_aux ((q), (c), (i), 0)
+#define        oct2prim(s,len)         str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_PRIM_OCTS)
+#define        ia5s2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_IA5S)
+#define        nums2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_NUMS)
+#define        prts2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_PRTS)
+#define        t61s2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_T61S)
+#define        vtxs2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_VTXS)
+#define        gfxs2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_GFXS)
+#define        viss2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_VISS)
+#define        gens2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_GENS)
+#define        chrs2prim(s,len)        str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_DEFN_CHRS)
+#define        ode2prim(s,len)         str2prim ((s), (len), \
+                                           PE_CLASS_UNIV, PE_PRIM_ODE)
+
+PE     prim2bit ();
+PE     bit2prim ();
+
+int    bit_on (), bit_off ();
+int    bit_test ();
+
+OID    prim2oid ();
+PE     obj2prim ();
+#define        oid2prim(o)             obj2prim ((o), PE_CLASS_UNIV, PE_PRIM_OID)
+
+UTC    prim2time ();
+#define        prim2utct(pe)           prim2time ((pe), 0)
+#define        prim2gent(pe)           prim2time ((pe), 1)
+PE     time2prim ();
+#define        utct2prim(u)            time2prim ((u), 0, PE_CLASS_UNIV, PE_DEFN_UTCT)
+#define        gent2prim(u)            time2prim ((u), 1, PE_CLASS_UNIV, PE_DEFN_GENT)
+char   *time2str ();
+#define        utct2str(u)             time2str ((u), 0)
+#define        gent2str(u)             time2str ((u), 1)
+UTC    str2utct (), str2gent ();
+
+PE     prim2set ();
+#define        set2prim(pe)            (pe)
+int    set_add (), set_addon (), set_del ();
+PE     set_find ();
+#define        first_member(pe)        ((pe) -> pe_cons)
+#define        next_member(pe,p)       ((p) -> pe_next)
+
+#define        prim2seq(pe)            (prim2set (pe))
+#define        seq2prim(pe)            (pe)
+int    seq_add (), seq_addon (), seq_del ();
+PE     seq_find ();
+
+
+char   *pe_error ();
+
+/* \f */
+
+#ifdef SVR4_UCB
+#ifdef PS      /* ucb define PS in sys/sparc/reg.h for "portability" !?! */
+#undef PS
+#endif
+#endif
+
+typedef struct {
+    int            ps_errno;           /* Error codes */
+#define        PS_ERR_NONE      0      /*   No error */
+#define        PS_ERR_OVERID    1      /*   Overflow in ID */
+#define        PS_ERR_OVERLEN   2      /*   Overflow in length */
+#define        PS_ERR_NMEM      3      /*   Out of memory */
+#define        PS_ERR_EOF       4      /*   End of file */
+#define        PS_ERR_EOFID     5      /*   End of file reading extended ID */
+#define        PS_ERR_EOFLEN    6      /*   End of file reading extended length */
+#define        PS_ERR_LEN       7      /*   Length mismatch */
+#define        PS_ERR_TRNC      8      /*   Truncated */
+#define        PS_ERR_INDF      9      /*   Indefinite length in primitive form */
+#define        PS_ERR_IO       10      /*   I/O error */
+#define        PS_ERR_EXTRA    11      /*   Extraneous octets */
+#define        PS_ERR_XXX      12      /*   XXX */
+
+    union {
+       caddr_t un_ps_addr;
+       struct {
+           char   *st_ps_base;
+           int     st_ps_cnt;
+           char   *st_ps_ptr;
+           int     st_ps_bufsiz;
+       }                       un_ps_st;
+       struct {
+           struct udvec *uv_ps_head;
+           struct udvec *uv_ps_cur;
+           struct udvec *uv_ps_end;
+           int     uv_ps_elems;
+           int     uv_ps_slop;
+           int     uv_ps_cc;
+       }                       un_ps_uv;
+    }                       ps_un;
+#define        ps_addr ps_un.un_ps_addr
+#define        ps_base ps_un.un_ps_st.st_ps_base
+#define        ps_cnt  ps_un.un_ps_st.st_ps_cnt
+#define        ps_ptr  ps_un.un_ps_st.st_ps_ptr
+#define        ps_bufsiz       ps_un.un_ps_st.st_ps_bufsiz
+#define        ps_head ps_un.un_ps_uv.uv_ps_head
+#define        ps_cur  ps_un.un_ps_uv.uv_ps_cur
+#define        ps_end  ps_un.un_ps_uv.uv_ps_end
+#define        ps_elems        ps_un.un_ps_uv.uv_ps_elems
+#define        ps_slop ps_un.un_ps_uv.uv_ps_slop
+#define        ps_cc   ps_un.un_ps_uv.uv_ps_cc
+
+    caddr_t ps_extra;          /* for George's recursive PStreams */
+
+    int            ps_inline;          /* for "ultra-efficient" PStreams */
+
+    int            ps_scratch;         /* XXX */
+
+    int            ps_byteno;          /* byte position */
+
+    IFP            ps_primeP;
+    IFP            ps_readP;
+    IFP            ps_writeP;
+    IFP            ps_flushP;
+    IFP            ps_closeP;
+}                      PStream, *PS;
+#define        NULLPS  ((PS) 0)
+
+#define        ps_seterr(ps, e, v)     ((ps) -> ps_errno = (e), (v))
+
+
+PS     ps_alloc ();
+void   ps_free ();
+
+int    ps_io ();
+#define        ps_read(ps, data, cc)   ps_io ((ps), (ps) -> ps_readP, (data), (cc), 0)
+#define        ps_write(ps, data, cc)  ps_write_aux ((ps), (data), (cc), 0)
+#define        ps_write_aux(ps, data, cc, in_line) \
+       ps_io ((ps), (ps) -> ps_writeP, (data), (cc), (in_line))
+
+int    ps_flush ();
+
+int    std_open ();
+#define        std_setup(ps, fp)       ((ps) -> ps_addr = (caddr_t) (fp), OK)
+
+int    str_open ();
+int    str_setup ();
+
+int    dg_open ();
+int    dg_setup ();
+
+int    fdx_open ();
+int    fdx_setup ();
+
+int    qbuf_open ();
+#define        qbuf_setup(ps, qb)      ((ps) -> ps_addr = (caddr_t) (qb), OK)
+
+#define        ts_open dg_open
+#define        ts_setup(p,f,s)         dg_setup ((p), (f), (s), ts_read, ts_write)
+int    ts_read (), ts_write ();
+
+int    uvec_open ();
+int    uvec_setup ();
+
+
+#define        ps2pe(ps)               ps2pe_aux ((ps), 1, 1)
+PE     ps2pe_aux ();
+#define        pe2ps(ps, pe)           pe2ps_aux ((ps), (pe), 1)
+int    pe2ps_aux ();
+
+
+PE     pl2pe ();
+int    pe2pl ();
+
+
+extern int    ps_len_strategy;
+#define        PS_LEN_SPAG     0
+#define        PS_LEN_INDF     1
+#define        PS_LEN_LONG     2
+
+int    ps_get_abs ();
+
+
+char   *ps_error ();
+
+/* \f */
+
+struct isobject {
+    char   *io_descriptor;
+
+    OIDentifier io_identity;
+};
+
+int    setisobject (), endisobject ();
+
+struct isobject *getisobject ();
+
+struct isobject *getisobjectbyname ();
+struct isobject *getisobjectbyoid ();
+
+/* \f */
+
+extern int     Len;
+extern char   *Qcp;
+extern char   *Ecp;
+
+int    pe2qb_f ();
+
+
+extern int     Byteno;
+extern int     Qbrefs;
+extern struct qbuf *Hqb;
+extern struct qbuf *Fqb;
+extern struct qbuf *Qb;
+
+#define qbuf2pe(qb, len, result) (Byteno = 0, Hqb = qb, \
+                                        Fqb = (Qb = (qb) -> qb_forw), \
+                                        qbuf2pe_f (result))
+PE     qbuf2pe_f ();
+char   *qb2str ();
+struct qbuf *str2qb ();
+int    qb_free ();
+
+int    pe2ssdu ();
+PE     ssdu2pe ();
+
+void   pe2text (), text2pe ();
+
+int    pe2uvec ();
+
+char   *int2strb ();
+int    strb2int ();
+
+PE     strb2bitstr ();
+char   *bitstr2strb ();
+
+/* \f */
+
+extern char PY_pepy[];
+
+void   PY_advise ();
+int    PY_pp ();
+
+int    testdebug ();
+
+int    vpush (), vpop ();
+int    vname (), vtag ();
+int    vprint ();
+int    vstring (), vunknown ();
+
+char   *bit2str ();
+
+int    vpushfp (), vpopfp ();
+
+int    vpushstr (), vpopstr ();
+
+int    vpushpp (), vpopp ();
+
+#ifdef PEPSY_VERSION
+/* handle calls to the vunknown print routine */
+#define vunknown_P     0, ((modtyp *) 0)
+
+/*
+ * vpdu now comes out of the closet as a real pepsy function "pvpdu" we
+ * keep the #define for vpdu for backwards compatiability of other peoples'
+ * code
+ */
+#ifdef __STDC__
+#define        vpdu(lp,fnx,pe,text,rw) \
+{ \
+    pvpdu ((lp), fnx##_P, (pe), (text), (rw)); \
+}
+#else   /* __STDC__ */
+#define        vpdu(lp,fnx,pe,text,rw) \
+{ \
+    pvpdu ((lp), fnx/**/_P, (pe), (text), (rw)); \
+}
+#endif /* __STDC__ */
+
+#else
+       /* Backwards compatibility with posy/pepy */
+#define vpdu(lp,fnx,pe,text,rw) \
+{ \
+    int    fnx (); \
+ \
+    _vpdu ((lp), fnx, (pe), (text), (rw)); \
+}
+
+int     _vpdu ();
+#endif
+
+/* pepy string definitions */
+extern char *pepy_strings[];
+
+#define         PEPY_ERR_BAD                   (pepy_strings[0])
+#define         PEPY_ERR_BAD_BITS              (pepy_strings[1])
+#define         PEPY_ERR_BAD_BOOLEAN           (pepy_strings[2])
+#define         PEPY_ERR_BAD_CLASS             (pepy_strings[3])
+#define         PEPY_ERR_BAD_CLASS_FORM_ID     (pepy_strings[4])
+#define         PEPY_ERR_BAD_FORM              (pepy_strings[5])
+#define         PEPY_ERR_BAD_INTEGER           (pepy_strings[6])
+#define         PEPY_ERR_BAD_OID               (pepy_strings[7])
+#define         PEPY_ERR_BAD_OCTET             (pepy_strings[8])
+#define         PEPY_ERR_BAD_REAL              (pepy_strings[9])
+#define         PEPY_ERR_BAD_SEQ               (pepy_strings[10])
+#define         PEPY_ERR_BAD_SET               (pepy_strings[11])
+#define         PEPY_ERR_TOO_MANY_BITS         (pepy_strings[12])
+#define         PEPY_ERR_TOO_MANY_ELEMENTS     (pepy_strings[13])
+#define         PEPY_ERR_UNKNOWN_CHOICE        (pepy_strings[14])
+#define         PEPY_ERR_UNK_COMP              (pepy_strings[15])
+#define         PEPY_ERR_INIT_FAILED           (pepy_strings[16])
+#define         PEPY_ERR_INVALID_CHOICE        (pepy_strings[17])
+#define         PEPY_ERR_MISSING               (pepy_strings[18])
+#define         PEPY_ERR_NOMEM                 (pepy_strings[19])
+#define         PEPY_ERR_TOO_MANY_TAGGED       (pepy_strings[20])
+#define         PEPY_ERR_EXTRA_MEMBERS         (pepy_strings[21])
+
+#endif
diff --git a/src/isode/h/psap2.h b/src/isode/h/psap2.h
new file mode 100644 (file)
index 0000000..d9b33ed
--- /dev/null
@@ -0,0 +1,539 @@
+/* psap2.h - include file for presentation users (PS-USER) continued  */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:38  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:03  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:18  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:51  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _PSAP2_
+#define        _PSAP2_
+
+#ifndef        _PSAP_
+#include "psap.h"              /* definitions for PS-USERs */
+#endif
+#ifndef        _SSAP_
+#include "ssap.h"              /* definitions for SS-USERs */
+#endif
+#ifndef        _ISOADDRS_
+#include "isoaddrs.h"          /* definitions of ISO addresses */
+#endif
+
+/* \f */
+
+#define        NPDATA          125     /* arbitrary */
+
+
+struct PSAPcontext {           /* presentation context */
+    int            pc_id;              /* identifier */
+
+    OID            pc_asn;             /* abstract syntax name */
+
+    OID            pc_atn;             /* abstract transfer name */
+                               /*   NULLOID if provider should handle it */
+    
+    int            pc_result;          /* same codes as pc_result below */
+};
+
+struct PSAPctxlist {           /* list of presentation contexts */
+    int            pc_nctx;            /* number of contexts */
+
+#define        NPCTX   10              /* arbitrary */
+    struct PSAPcontext pc_ctx[NPCTX];
+};
+#define        NULLPC  ((struct PSAPctxlist *) 0)
+
+
+#define        BER             "basic encoding of a single asn.1 type"
+
+#if    USE_BUILTIN_OIDS
+#define BER_OID                str2oid ("2.1.1")
+#else
+#define BER_OID                ode2oid (BER)
+#endif
+
+
+struct SSAPref *addr2ref ();   /* address to session reference */
+
+char   *sprintref ();          /* return session reference in string form */
+
+/* \f */
+
+struct PSAPstart {             /* P-CONNECT.INDICATION */
+    int            ps_sd;              /* PRESENTATION descriptor */
+
+
+    struct PSAPaddr ps_calling;        /* address of peer calling */
+    struct PSAPaddr ps_called; /* address of peer called */
+
+    struct PSAPctxlist ps_ctxlist;/* list of proposed contexts */
+
+    OID            ps_defctx;          /* name of proposed default context */
+    int            ps_defctxresult;    /* what the provider thinks about it */
+    
+    int            ps_prequirements;   /* presentation requirements */
+
+    int            ps_srequirements;   /* session requirements */
+    int            ps_settings;        /* initial settings of tokens */
+    long    ps_isn;            /* initial serial number */
+    
+    struct SSAPref  ps_connect;        /* session connection identifier */
+
+    int            ps_ssdusize;        /* largest atomic SSDU */
+    
+    struct QOStype ps_qos;     /* quality of service */
+    
+                               /* initial data from peer */
+    int            ps_ninfo;           /*   number of elements */
+    PE     ps_info[NPDATA];    /*   data */
+};
+#define        PSFREE(ps) \
+{ \
+    register int PSI; \
+ \
+    for (PSI = (ps) -> ps_ctxlist.pc_nctx - 1; PSI >= 0; PSI--) { \
+       oid_free ((ps) -> ps_ctxlist.pc_ctx[PSI].pc_asn); \
+       oid_free ((ps) -> ps_ctxlist.pc_ctx[PSI].pc_atn); \
+       (ps) -> ps_ctxlist.pc_ctx[PSI].pc_asn = \
+           (ps) -> ps_ctxlist.pc_ctx[PSI].pc_atn = NULLOID; \
+    } \
+    (ps) -> ps_ctxlist.pc_nctx = 0; \
+    if ((ps) -> ps_defctx) \
+       oid_free ((ps) -> ps_defctx), (ps) -> ps_defctx = NULLOID; \
+    for (PSI = (ps) -> ps_ninfo - 1; PSI >= 0; PSI--) \
+       if ((ps) -> ps_info[PSI]) \
+           pe_free ((ps) -> ps_info[PSI]), (ps) -> ps_info[PSI] = NULLPE; \
+    (ps) -> ps_ninfo = 0; \
+}
+
+
+struct PSAPconnect {           /* P-CONNECT.CONFIRMATION */
+    int            pc_sd;              /* PRESENTATION descriptor */
+
+    struct PSAPaddr pc_responding;/* address of peer responding */
+
+    struct PSAPctxlist pc_ctxlist;/* the list of negotiated contexts */
+
+    int            pc_defctxresult;    /* result for proposed default context name */
+    
+    int            pc_prequirements;   /* presentation requirements */
+
+    int            pc_srequirements;   /* session requirements */
+    int            pc_settings;        /* initial settings of tokens */
+    int            pc_please;          /* tokens requested by PS-user */
+    long    pc_isn;            /* initial serial number */
+
+    struct SSAPref pc_connect; /* session connection identifier */
+
+    int            pc_ssdusize;        /* largest atomic SSDU */
+
+    struct QOStype pc_qos;     /* quality of service */
+    
+    int            pc_result;          /* result */
+#define        PC_ACCEPT       (-1)
+
+#define        PC_REJECTED     0       /* Rejected by peer */
+                               /* Provider-reason */
+#define        PC_NOTSPECIFIED 1       /* Reason not specified */
+#define        PC_CONGEST      2       /* Temporary congestion */
+#define        PC_EXCEEDED     3       /* Local limit exceeded */
+#define        PC_ADDRESS      4       /* Called presentation address unknown */
+#define        PC_VERSION      5       /* Protocol version not supported */
+#define        PC_DEFAULT      6       /* Default context not supported */
+#define        PC_READABLE     7       /* User-data not readable */
+#define        PC_AVAILABLE    8       /* No PSAP available */
+                               /* Abort-reason */
+#define        PC_UNRECOGNIZED 9       /* Unrecognized PPDU */
+#define        PC_UNEXPECTED   10      /* Unexpected PPDU */
+#define        PC_SSPRIMITIVE  11      /* Unexpected session service primitive */
+#define        PC_PPPARAM1     12      /* Unrecognized PPDU parameter */
+#define        PC_PPPARAM2     13      /* Unexpected PPDU parameter */
+#define        PC_INVALID      14      /* Invalid PPDU parameter value */
+                               /* Provider-reason */
+#define        PC_ABSTRACT     15      /* Abstract syntax not supported */
+#define        PC_TRANSFER     16      /* Proposed transfer syntaxes not supported */
+#define        PC_DCSLIMIT     17      /* Local limit on DCS exceeded */
+                               /* begin UNOFFICIAL */
+#define        PC_REFUSED      18      /* Connect request refused on this network
+                                  connection */
+#define        PC_SESSION      19      /* Session disconnect */
+#define        PC_PROTOCOL     20      /* Protocol error */
+#define        PC_ABORTED      21      /* Peer aborted connection */
+#define        PC_PARAMETER    22      /* Invalid parameter */
+#define        PC_OPERATION    23      /* Invalid operation */
+#define        PC_TIMER        24      /* Timer expired */
+#define        PC_WAITING      25      /* Indications waiting */
+                               /* end UNOFFICIAL */
+
+#define        PC_FATAL(r)     ((r) < PC_PARAMETER)
+#define        PC_OFFICIAL(r)  ((r) < PC_REFUSED)
+    
+                               /* initial data from peer */
+    int            pc_ninfo;           /*   number of elements */
+    PE     pc_info[NPDATA];    /*   data */
+};
+#define        PCFREE(pc) \
+{ \
+    register int PCI; \
+ \
+    for (PCI = (pc) -> pc_ctxlist.pc_nctx - 1; PCI >= 0; PCI--) { \
+       oid_free ((pc) -> pc_ctxlist.pc_ctx[PCI].pc_asn); \
+       oid_free ((pc) -> pc_ctxlist.pc_ctx[PCI].pc_atn); \
+       (pc) -> pc_ctxlist.pc_ctx[PCI].pc_asn = \
+           (pc) -> pc_ctxlist.pc_ctx[PCI].pc_atn = NULLOID; \
+    } \
+    (pc) -> pc_ctxlist.pc_nctx = 0; \
+    for (PCI = (pc) -> pc_ninfo - 1; PCI >= 0; PCI--) \
+       if ((pc) -> pc_info[PCI]) \
+           pe_free ((pc) -> pc_info[PCI]), (pc) -> pc_info[PCI] = NULLPE; \
+    (pc) -> pc_ninfo = 0; \
+}
+    
+
+                                       /* PRESENTATION requirements */
+#define        PR_MANAGEMENT   0x0001  /* context management */
+#define        PR_RESTORATION  0x0002  /* context restoration */
+
+#define        PR_MYREQUIRE    0x0000
+
+
+struct PSAPdata {              /* P-READ.INDICATION */
+    int            px_type;            /* type of indication */
+                               /* same values as sx_type */
+
+    int            px_ninfo;           /* number of elements */
+    PE     px_info[NPDATA];    /* data */
+};
+#define        PXFREE(px) \
+{ \
+    register int PXI; \
+ \
+    for (PXI = (px) -> px_ninfo - 1; PXI >= 0; PXI--) \
+       if ((px) -> px_info[PXI]) \
+           pe_free ((px) -> px_info[PXI]), (px) -> px_info[PXI] = NULLPE; \
+    (px) -> px_ninfo = 0; \
+}
+
+
+struct PSAPtoken {             /* P-{TOKEN-*,GIVE-CONTROL}.INDICATION */
+    int            pt_type;            /* type of indication */
+                               /* same values as st_type */
+
+    u_char  pt_tokens;         /* tokens offered/wanted */
+                               /* same values as st_tokens */
+
+    u_char  pt_owned;          /* tokens owned by user */
+
+
+                               /* PLEASE TOKEN only */
+    int            pt_ninfo;           /*   number of elements */
+    PE     pt_info[NPDATA];    /*   data */
+};
+#define        PTFREE(pt) \
+{ \
+    register int PTI; \
+ \
+    for (PTI = (pt) -> pt_ninfo - 1; PTI >= 0; PTI--) \
+       if ((pt) -> pt_info[PTI]) \
+           pe_free ((pt) -> pt_info[PTI]), (pt) -> pt_info[PTI] = NULLPE; \
+    (pt) -> pt_ninfo = 0; \
+}
+
+
+struct PSAPsync {              /* P-*-SYNC.{INDICATION,CONFIRMATION} */
+    int            pn_type;            /* type of indication/confirmation */
+                               /* same values as sn_type */
+
+    int            pn_options;         /* options (!!) */
+                               /* same values as sn_options */
+
+    long    pn_ssn;            /* serial number */
+                               /* same values as sn_ssn */
+
+    int            pn_settings;        /* new token settings (RESYNC only) */
+
+                               /* sync data from peer */
+    int            pn_ninfo;           /*   number of elements */
+    PE     pn_info[NPDATA];    /*   data */
+};
+#define        PNFREE(pn) \
+{ \
+    register int PNI; \
+ \
+    for (PNI = (pn) -> pn_ninfo - 1; PNI >= 0; PNI--) \
+       if ((pn) -> pn_info[PNI]) \
+           pe_free ((pn) -> pn_info[PNI]), (pn) -> pn_info[PNI] = NULLPE; \
+    (pn) -> pn_ninfo = 0; \
+}
+
+
+struct PSAPactivity {          /* P-ACTIVITY-*.{INDICATION,CONFIRMATION} */
+    int            pv_type;            /* type of indication/confirmation */
+                               /* same values as sv_type */
+
+    struct SSAPactid pv_id;    /* START/RESUME activity identifier */
+
+    struct SSAPactid pv_oid;   /* RESUME old activity identifier */
+    struct SSAPref   pv_connect;/*       old connection identifier */
+
+    long    pv_ssn;            /* RESUME/END Serial number */
+
+    int            pv_reason;          /* INTERRUPT/DISCARD */
+                               /* same values as sp_reason */
+        
+                               /* activity DATA from peer */
+    int            pv_ninfo;           /*   number of elements */
+    PE     pv_info[NPDATA];    /*   data */
+};
+#define        PVFREE(pv) \
+{ \
+    register int PVI; \
+ \
+    for (PVI = (pv) -> pv_ninfo - 1; PVI >= 0; PVI--) \
+       if ((pv) -> pv_info[PVI]) \
+           pe_free ((pv) -> pv_info[PVI]), (pv) -> pv_info[PVI] = NULLPE; \
+    (pv) -> pv_ninfo = 0; \
+}
+
+
+struct PSAPreport {            /* P-{U,P}-EXCEPTION-REPORT.INDICATION */
+    int            pp_peer;            /* T   = P-U-EXCEPTION-REPORT.INDICATION:
+                                       pp_reason/pp_info both meaningful
+                                  NIL = P-P-EXCEPTION-REPORT.INDICATION:
+                                       pp_reason == SP_NOREASON, or
+                                       pp_reason == SP_PROTOCOL */
+    int            pp_reason;          /* same values as sp_reason */
+
+                               /* report DATA from peer */
+    int            pp_ninfo;           /*   number of elements */
+    PE     pp_info[NPDATA];    /*   data */
+};
+#define        PPFREE(pp) \
+{ \
+    register int PPI; \
+ \
+    for (PPI = (pp) -> pp_ninfo - 1; PPI >= 0; PPI--) \
+       if ((pp) -> pp_info[PPI]) \
+           pe_free ((pp) -> pp_info[PPI]), (pp) -> pp_info[PPI] = NULLPE; \
+    (pp) -> pp_ninfo = 0; \
+}
+
+
+struct PSAPfinish {            /* P-RELEASE.INDICATION */
+                               /* release DATA from peer */
+    int            pf_ninfo;           /*   number of elements */
+    PE     pf_info[NPDATA];    /*   data */
+};
+#define        PFFREE(pf) \
+{ \
+    register int PFI; \
+ \
+    for (PFI = (pf) -> pf_ninfo - 1; PFI >= 0; PFI--) \
+       if ((pf) -> pf_info[PFI]) \
+           pe_free ((pf) -> pf_info[PFI]), (pf) -> pf_info[PFI] = NULLPE; \
+    (pf) -> pf_ninfo = 0; \
+}
+
+
+struct PSAPrelease {           /* P-RELEASE.CONFIRMATION */
+    int            pr_affirmative;     /* T   = connection released
+                                  NIL = request refused */
+
+                               /* release DATA from peer */
+    int            pr_ninfo;           /*   number of elements */
+    PE     pr_info[NPDATA];    /*   data */
+};
+#define        PRFREE(pr) \
+{ \
+    register int PRI; \
+ \
+    for (PRI = (pr) -> pr_ninfo - 1; PRI >= 0; PRI--) \
+       if ((pr) -> pr_info[PRI]) \
+           pe_free ((pr) -> pr_info[PRI]), (pr) -> pr_info[PRI] = NULLPE; \
+    (pr) -> pr_ninfo = 0; \
+}
+
+
+struct PSAPabort {             /* P-{U,P}-ABORT.INDICATION */
+    int            pa_peer;            /* T   = P-U-ABORT.INDICATION:
+                                           pa_info/pa_ninfo is meaningful
+                                  NIL = P-P-ABORT.INDICATION:
+                                           pa_reason/pa_ppdu is meaningful,
+                                           pa_data contains diagnostics */
+
+    int            pa_reason;          /* same codes as pc_result */
+
+                               /* abort information from peer */
+    int            pa_ninfo;           /*   number of elements */
+    PE     pa_info[NPDATA];    /*   data */
+
+                               /* diagnostics from provider */
+#define        PA_SIZE         512
+    int            pa_cc;              /*   length */
+    char    pa_data[PA_SIZE];  /*   data */
+};
+#define        PAFREE(pa) \
+{ \
+    register int PAI; \
+ \
+    for (PAI = (pa) -> pa_ninfo - 1; PAI >= 0; PAI--) \
+       if ((pa) -> pa_info[PAI]) \
+           pe_free ((pa) -> pa_info[PAI]), (pa) -> pa_info[PAI] = NULLPE; \
+    (pa) -> pa_ninfo = 0; \
+}
+
+
+struct PSAPindication {
+    int            pi_type;            /* the union element present */
+#define        PI_DATA         0x00
+#define        PI_TOKEN        0x01
+#define        PI_SYNC         0x02
+#define        PI_ACTIVITY     0x03
+#define        PI_REPORT       0x04
+#define        PI_FINISH       0x05
+#define        PI_ABORT        0x06
+
+    union {
+       struct PSAPdata pi_un_data;
+       struct PSAPtoken pi_un_token;
+       struct PSAPsync pi_un_sync;
+       struct PSAPactivity pi_un_activity;
+       struct PSAPreport pi_un_report;
+       struct PSAPfinish pi_un_finish;
+       struct PSAPabort pi_un_abort;
+    }  pi_un;
+#define        pi_data         pi_un.pi_un_data
+#define        pi_token        pi_un.pi_un_token
+#define        pi_sync         pi_un.pi_un_sync
+#define        pi_activity     pi_un.pi_un_activity
+#define        pi_report       pi_un.pi_un_report
+#define        pi_finish       pi_un.pi_un_finish
+#define        pi_abort        pi_un.pi_un_abort
+};
+
+/* \f */
+
+extern char *psap2version;
+
+
+int    PExec ();               /* SERVER only */
+int    PInit ();               /* P-CONNECT.INDICATION */
+
+int    PConnResponse ();       /* P-CONNECT.RESPONSE */
+                               /* P-CONNECT.REQUEST (backwards-compatible) */
+#define        PConnRequest(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14) \
+       PAsynConnRequest (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,0)
+int    PAsynConnRequest ();    /* P-(ASYN-)CONNECT.REQUEST */
+int    PAsynRetryRequest ();   /* P-ASYN-RETRY.REQUEST (pseudo) */
+int    PDataRequest ();        /* P-DATA.REQUEST */
+int    PDataRequestAux ();     /* P-[*-]DATA.REQUEST */
+#define        PPDU_TTD        8
+#define        PPDU_TE         9
+#define        PPDU_TC        10
+#define        PPDU_TCC       11
+
+#define        PExpdRequest(s,d,n,p) \
+       PDataRequestAux ((s), (d), (n), (p), "expedited", SExpdRequest, \
+                       "SExpdRequest", "P-EXPEDITED-DATA user-data", PPDU_TE)
+
+#define        PTypedRequest(s,d,n,p) \
+       PDataRequestAux ((s), (d), (n), (p), "typed", STypedRequest, \
+                       "STypedRequest", "P-TYPED-DATA user-data", PPDU_TTD)
+
+#define        PCapdRequest(s,d,n,p) \
+       PDataRequestAux ((s), (d), (n), (p), "capability", SCapdRequest, \
+                       "SCapdRequest", "P-CAPABILITY-DATA user-data", PPDU_TC)
+
+#define        PCapdResponse(s,d,n,p) \
+       PDataRequestAux ((s), (d), (n), (p), "capability", SCapdResponse, \
+                       "SCapdResponse","P-CAPABILITY-DATA user-data",PPDU_TCC)
+
+int    PReadRequest ();        /* P-READ.REQUEST (pseudo) */
+int    PGTokenRequest ();      /* P-TOKEN-GIVE.REQUEST */
+int    PPTokenRequest ();      /* P-TOKEN-PLEASE.REQUEST */
+int    PGControlRequest ();    /* P-CONTROL-GIVE.REQUEST */
+int    PMajSyncRequestAux ();  /* P-{MAJOR-SYNC,ACTIVITY-END}.REQUEST */
+
+#define        PMajSyncRequest(s,i,d,n,p) \
+       PMajSyncRequestAux ((s), (i), (d), (n), (p), "majorsync", \
+                       SMajSyncRequest, "SMajSyncRequest")
+
+#define        PActEndRequest(s,i,d,n,p) \
+       PMajSyncRequestAux ((s), (i), (d), (n), (p), "activity end", \
+                       SActEndRequest, "SActEndRequest")
+
+int    PMajSyncResponseAux (); /* P-{MAJOR-SYNC,ACTIVITY-END}.RESPONSE */
+
+#define        PMajSyncResponse(s,d,n,p) \
+       PMajSyncResponseAux ((s), (d), (n), (p), "majorsync", \
+                       SMajSyncResponse, "SMajSyncResponse")
+
+#define        PActEndResponse(s,d,n,p) \
+       PMajSyncResponseAux ((s), (d), (n), (p), "activity end", \
+                       SActEndResponse, "SActEndResponse")
+
+int    PMinSyncRequest ();     /* P-MINOR-SYNC.REQUEST */
+int    PMinSyncResponse ();    /* P-MINOR-SYNC.RESPONSE */
+int    PReSyncRequest ();      /* P-RESYNCHRONIZE.REQUEST */
+int    PReSyncResponse ();     /* P-RESYNCHRONIZE.RESPONSE */
+int    PActStartRequest ();    /* P-ACTIVITY-START.REQUEST */
+int    PActResumeRequest ();   /* P-ACTIVITY-RESUME.REQUEST */
+int    PActIntrRequestAux ();  /* P-ACTIVITY-{INTERRUPT,DISCARD}.REQUEST */
+
+#define        PActIntrRequest(s,r,p) \
+       PActIntrRequestAux ((s), (r), (p), \
+                       SActIntrRequest, "SActIntrRequest")
+
+#define        PActDiscRequest(s,r,p) \
+       PActIntrRequestAux ((s), (r), (p), \
+                       SActDiscRequest, "SActDiscRequest")
+
+int    PActIntrResponseAux (); /* P-ACTIVITY-{INTERRUPT,DISCARD}.RESPONSE */
+
+#define        PActIntrResponse(s,p) \
+       PActIntrResponseAux ((s), (p), \
+                       SActIntrResponse, "SActIntrResponse")
+
+#define        PActDiscResponse(s,p) \
+       PActIntrResponseAux ((s), (p), \
+                       SActDiscResponse, "SActDiscResponse")
+
+int    PUAbortRequest ();      /* P-U-ABORT.REQUEST */
+int    PUReportRequest ();     /* P-U-EXCEPTION-REPORT.REQUEST */
+int    PRelRequest ();         /* P-RELEASE.REQUEST */
+int    PRelRetryRequest ();    /* P-RELEASE-RETRY.REQUEST (pseudo) */
+int    PRelResponse ();        /* P-RELEASE.RESPONSE */
+
+int    PSetIndications ();     /* define vectors for INDICATION events */
+int    PSelectMask ();         /* map presentation descriptors for select() */
+
+char   *PErrString ();         /* return PSAP error code in string form */
+
+#define        PLocalHostName  getlocalhost
+char   *PLocalHostName ();     /* return name of local host (sigh) */
+#endif
diff --git a/src/isode/h/ronot.h b/src/isode/h/ronot.h
new file mode 100644 (file)
index 0000000..4174ebc
--- /dev/null
@@ -0,0 +1,98 @@
+/* ronote.h - Additions to properly support ABSTRACT-BIND */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:40  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:06  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:20  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:52  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+#ifndef        _RoNot_
+#define        _RoNot_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+
+#ifndef        _AcSAP_
+#include "acsap.h"             /* definitions for AcS-USERs */
+#endif
+
+#ifndef        _RoSAP_
+#include "rosap.h"             /* definitions for RoS-USERs */
+#endif
+
+#define BIND_RESULT    1       /* indicates a bind result occured */
+#define BIND_ERROR     2       /* indicates a bind error occured */
+
+struct RoNOTindication {
+    int            rni_reason;         /* reason for failure */
+#define RBI_ACSE               1       /* ACSE provider failed */
+#define RBI_SET_ROSE_PRES      2       /* Failed to set ROS-USER */
+#define RBI_ENC_BIND_ARG       3       /* Failed encoding bind argument */
+#define RBI_ENC_BIND_RES       4       /* Failed encoding bind result */
+#define RBI_ENC_BIND_ERR       5       /* Failed encoding bind error */
+#define RBI_ENC_UNBIND_ARG     6       /* Failed encoding unbind argument */
+#define RBI_ENC_UNBIND_RES     7       /* Failed encoding unbind result */
+#define RBI_ENC_UNBIND_ERR     8       /* Failed encoding unbind error */
+#define RBI_DEC_BIND_ARG       9       /* Failed decoding bind argument */
+#define RBI_DEC_BIND_RES       10      /* Failed decoding bind result */
+#define RBI_DEC_BIND_ERR       11      /* Failed decoding bind error */
+#define RBI_DEC_UNBIND_ARG     12      /* Failed decoding unbind argument */
+#define RBI_DEC_UNBIND_RES     13      /* Failed decoding unbind result */
+#define RBI_DEC_UNBIND_ERR     14      /* Failed decoding unbind error */
+#define RBI_DEC_NINFO          15      /* Erroneous number of user infos */
+
+                               /* diagnostics from provider */
+#define        RB_SIZE 512
+    int            rni_cc;             /*   length */
+    char    rni_data[RB_SIZE]; /*   data */
+};
+
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyRoNOTdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyRoNOTdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyRoNOTdata(base,len,d)       bcopy (base, (char *) d, len)
+#endif
+
+#endif
diff --git a/src/isode/h/ropkt.h b/src/isode/h/ropkt.h
new file mode 100644 (file)
index 0000000..f1682d5
--- /dev/null
@@ -0,0 +1,218 @@
+/* ropkt.h - include file for remote operation providers (RoS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ * Based on an TCP-based implementation by George Michaelson of University
+ * College London.
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:42  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:08  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:22  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:52  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _RoSAP_
+#include "rosap.h"             /* definitions for RoS-USERs */
+#endif
+
+#include "acpkt.h"             /* definitions for AcS-PROVIDERs */
+
+#ifndef        _RtSAP_
+#include "rtsap.h"             /* definitions for RtS-USERs */
+#endif
+
+#ifndef _PSAP2_
+#include "psap2.h"             /* definitions for PS-USERs */
+#endif
+
+#ifndef        _SSAP_
+#include "ssap.h"              /* definitions for SS-USERs */
+#endif
+
+/* \f */
+
+#define        rosapPsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not connected"); \
+    } \
+    if (acb -> acb_flags & ACB_CLOSING) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); \
+    } \
+    if (acb -> acb_flags & ACB_FINN) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor finishing"); \
+    } \
+    if (acb -> acb_putosdu == NULLIFP) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not bound"); \
+    } \
+}
+
+#define        rosapXsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not connected"); \
+    } \
+    if (acb -> acb_flags & ACB_FINN) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor finishing"); \
+    } \
+    if (acb -> acb_putosdu == NULLIFP) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not bound"); \
+    } \
+}
+
+#define        rosapFsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_ROS)) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "not an association descriptor for ROS"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not connected"); \
+    } \
+    if (!(acb -> acb_flags & ACB_FINN)) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not finishing"); \
+    } \
+    if (acb -> acb_putosdu == NULLIFP) { \
+       (void) sigiomask (smask); \
+       return rosaplose (roi, ROS_OPERATION, NULLCP, \
+                           "association descriptor not bound"); \
+    } \
+}
+
+#ifdef __STDC__
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return rosaplose (roi, ROS_PARAMETER, NULLCP, \
+                            "mandatory parameter \"%s\" missing",#p); \
+}
+#else
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return rosaplose (roi, ROS_PARAMETER, NULLCP, \
+                           "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+
+
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyRoSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyRoSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyRoSAPdata(base,len,d)       bcopy (base, (char *) d, len)
+#endif
+
+
+#define        pylose() \
+       ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, "%s", PY_pepy)
+
+
+int    ropktlose (), rosapreject (), rosaplose ();
+
+/* \f */
+
+int    acb2osdu ();
+
+
+int    ro2rtswrite (), ro2rtswait (), ro2rtsready (), ro2rtsasync (),
+       ro2rtsmask ();
+
+
+int    ro2pswrite (), ro2pswait (), ro2psasync (), ro2psmask ();
+
+
+int    ss2roslose (), ss2rosabort ();
+int    ro2sswrite (), ro2sswait (), ro2ssasync (), ro2ssmask (), ro2sslose (),
+       ro2ssready ();
+
+/* \f */
+
+                               /* APDU types */
+#define        APDU_INVOKE     1       /* Invoke */
+#define        APDU_RESULT     2       /* Return result */
+#define        APDU_ERROR      3       /* Return error */
+#define        APDU_REJECT     4       /* Reject */
+
+#define        APDU_UNKNOWN    (-1)    /* anything other than the above */
+
+
+                               /* Reject APDU types */
+#define        REJECT_GENERAL  0       /* General Problem */
+#define          REJECT_GENERAL_BASE   ROS_GP_UNRECOG
+#define        REJECT_INVOKE   1       /* Invoke Problem */
+#define          REJECT_INVOKE_BASE    ROS_IP_DUP
+#define        REJECT_RESULT   2       /* Return Result Problem */
+#define          REJECT_RESULT_BASE    ROS_RRP_UNRECOG
+#define        REJECT_ERROR    3       /* Return Error Problem */
+#define          REJECT_ERROR_BASE     ROS_REP_UNRECOG
+#define        REJECT_COMPLETE 4       /* more Invoke Problem codes */
diff --git a/src/isode/h/rosap.h b/src/isode/h/rosap.h
new file mode 100644 (file)
index 0000000..1c2195b
--- /dev/null
@@ -0,0 +1,289 @@
+/* rosap.h - include file for remote operation users (RoS-USER) */
+
+/* 
+ * $Header$
+ *
+ * Based on an TCP-based implementation by George Michaelson of University
+ * College London.
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:44  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:10  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:24  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _RoSAP_
+#define        _RoSAP_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+
+#ifndef        _AcSAP_
+#include "acsap.h"             /* definitions for AcS-USERs */
+#endif
+
+/* \f */
+
+struct RoSAPaddr {             /* RoSAP address (old-style)*/
+    struct SSAPaddr roa_addr;
+
+    u_short    roa_port;
+};
+#define        NULLRoA                 ((struct RoSAPaddr *) 0)
+
+/* \f */
+
+#define        ROS_MYREQUIRE   SR_DUPLEX/* for direct users of ACSE */
+
+
+struct RoSAPstart {            /* RO-BEGIN.INDICATION */
+    int            ros_sd;             /* ROS descriptor */
+
+    struct RoSAPaddr ros_initiator;/* unique identifier */
+
+    u_short ros_port;          /* application number */
+
+    PE     ros_data;           /* initial DATA from peer */
+};
+#define        ROSFREE(ros) \
+{ \
+    if ((ros) -> ros_data) \
+       pe_free ((ros) -> ros_data), (ros) -> ros_data = NULLPE; \
+}
+
+struct RoSAPconnect {          /* RO-BEGIN.CONFIRMATION */
+    int            roc_sd;             /* ROS descriptor */
+
+    int            roc_result;         /* result */
+#define        ROS_ACCEPT      (-1)
+
+                               /* RO-BEGIN.REQUEST */
+#define        ROS_VALIDATE    0       /* Authentication failure */
+#define        ROS_BUSY        1       /* Busy */
+
+                               /* General Problem */
+#define        ROS_GP_UNRECOG  2       /* Unrecognized APDU */
+#define        ROS_GP_MISTYPED 3       /* Mistyped APDU */
+#define        ROS_GP_STRUCT   4       /* Badly structured APDU */
+
+                               /* Invoke Problem */
+#define        ROS_IP_DUP      5       /* Duplicate invocation */
+#define        ROS_IP_UNRECOG  6       /* Unrecognized operation */
+#define        ROS_IP_MISTYPED 7       /* Mistyped argument */
+#define        ROS_IP_LIMIT    8       /* Resource limitation */
+#define        ROS_IP_RELEASE  9       /* Initiator releasing */
+#define        ROS_IP_UNLINKED 10      /* Unrecognized linked ID */
+#define        ROS_IP_LINKED   11      /* Linked response unexpected */
+#define        ROS_IP_CHILD    12      /* Unexpected child operation */
+
+                               /* Return Result Problem */
+#define        ROS_RRP_UNRECOG 13      /* Unrecognized invocation */
+#define        ROS_RRP_UNEXP   14      /* Result response unexpected */
+#define        ROS_RRP_MISTYPED 15     /* Mistyped result */
+
+                               /* Return Error Problem */
+#define        ROS_REP_UNRECOG 16      /* Unrecognized invocation */
+#define        ROS_REP_UNEXP   17      /* Error response unexpected */
+#define        ROS_REP_RECERR  18      /* Unrecognized error */
+#define        ROS_REP_UNEXPERR 19     /* Unexpected error */
+#define        ROS_REP_MISTYPED 20     /* Mistyped parameter */
+
+                               /* begin UNOFFICIAL */
+#define        ROS_ADDRESS     21      /* Address unknown */
+#define        ROS_REFUSED     22      /* Connect request refused on this network
+                                  connection */
+#define        ROS_SESSION     23      /* Session disconnect */
+#define        ROS_PROTOCOL    24      /* Protocol error */
+#define        ROS_CONGEST     25      /* Congestion at RoSAP */
+#define        ROS_REMOTE      26      /* Remote system problem */
+#define        ROS_DONE        27      /* Association done via async handler */
+#define        ROS_ABORTED     28      /* Peer aborted association */
+#define        ROS_RTS         29      /* RTS disconnect */
+#define        ROS_PRESENTATION 30     /* Presentation disconnect */
+#define        ROS_ACS         31      /* ACS disconnect */
+#define        ROS_PARAMETER   32      /* Invalid parameter */
+#define        ROS_OPERATION   33      /* Invalid operation */
+#define        ROS_TIMER       34      /* Timer expired */
+#define        ROS_WAITING     35      /* Indications waiting */
+#define        ROS_APDU        36      /* APDU not transferred */
+#define        ROS_INTERRUPTED 37      /* stub interrupted */
+                               /* end UNOFFICIAL */
+
+#define        ROS_FATAL(r)    (!(ROS_OFFICIAL (r)) && (r) < ROS_PARAMETER)
+#define        ROS_OFFICIAL(r) ((r) < ROS_ADDRESS)
+
+    PE     roc_data;           /* initial DATA from peer */
+};
+#define        ROCFREE(roc) \
+{ \
+    if ((roc) -> roc_data) \
+       pe_free ((roc) -> roc_data), (roc) -> roc_data = NULLPE; \
+}
+
+
+                               /* Operation Classes */
+#define        ROS_SYNC        0       /* synchronous mode with result or error */
+#define        ROS_ASYNC       1       /* asynchronous mode with result or error */
+
+                               /* APDU priorities */
+#define        ROS_NOPRIO      0       /* no priority */
+
+    
+struct RoSAPinvoke {           /* RO-INVOKE.INDICATION */
+    int            rox_id;             /*   invokeID */
+
+    int            rox_linkid;         /*   linkedID */
+    int     rox_nolinked;      /*   non-zero if no linkedID present */
+
+    int            rox_op;             /*   operation */
+    PE     rox_args;           /*   arguments */
+};
+#define        ROXFREE(rox) \
+{ \
+    if ((rox) -> rox_args) \
+       pe_free ((rox) -> rox_args), (rox) -> rox_args = NULLPE; \
+}
+
+
+struct RoSAPresult {           /* RO-RESULT.INDICATION */
+    int            ror_id;             /*   invokeID */
+
+    int            ror_op;             /*   operation */
+    PE     ror_result;         /*   result */
+};
+#define        RORFREE(ror) \
+{ \
+    if ((ror) -> ror_result) \
+       pe_free ((ror) -> ror_result), (ror) -> ror_result = NULLPE; \
+}
+
+
+struct RoSAPerror {            /* RO-ERROR.INDICATION */
+    int            roe_id;             /*   invokeID */
+
+    int            roe_error;          /*   error */
+    PE     roe_param;          /*   parameter */
+};
+#define        ROEFREE(roe) \
+{ \
+    if ((roe) -> roe_param) \
+       pe_free ((roe) -> roe_param), (roe) -> roe_param = NULLPE; \
+}
+
+
+struct RoSAPureject {          /* RO-U-REJECT.INDICATION */
+    int            rou_id;             /*   invokeID */
+    int            rou_noid;           /*     .. is not present */
+
+    int            rou_reason;         /*   reason (same as roc_result) */
+};
+
+
+struct RoSAPpreject {          /* RO-P-REJECT.INDICATION */
+    int            rop_reason;         /*   reason (same as roc_result) */
+
+                               /* APDU not transferred (reason is ROS_APDU) */
+    int            rop_id;             /*   invokeID */
+    PE     rop_apdu;           /*   APDU */
+
+                               /*   additional failure data from provider */
+#define        ROP_SIZE        512
+    int            rop_cc;             /*   length */
+    char    rop_data[ROP_SIZE];        /*   data */
+};
+#define        ROPFREE(rop) \
+{ \
+    if ((rop) -> rop_apdu) \
+       pe_free ((rop) -> rop_apdu), (rop) -> rop_apdu = NULLPE; \
+}
+
+
+struct RoSAPend {              /* RO-END.INDICATION */
+    int            roe_dummy;          /*   not used */
+};
+
+
+struct RoSAPindication {
+    int            roi_type;           /* the union element present */
+#define        ROI_INVOKE      0x00
+#define        ROI_RESULT      0x01
+#define        ROI_ERROR       0x02
+#define        ROI_UREJECT     0x03
+#define        ROI_PREJECT     0x04
+#define        ROI_END         0x05
+#define        ROI_FINISH      0x06
+
+    union {
+       struct RoSAPinvoke roi_un_invoke;
+       struct RoSAPresult roi_un_result;
+       struct RoSAPerror roi_un_error;
+       struct RoSAPureject roi_un_ureject;
+       struct RoSAPpreject roi_un_preject;
+       struct RoSAPend roi_un_end;
+       struct AcSAPfinish roi_un_finish;
+    }  roi_un;
+#define        roi_invoke      roi_un.roi_un_invoke
+#define        roi_result      roi_un.roi_un_result
+#define        roi_error       roi_un.roi_un_error
+#define        roi_ureject     roi_un.roi_un_ureject
+#define        roi_preject     roi_un.roi_un_preject
+#define        roi_end         roi_un.roi_un_end
+#define        roi_finish      roi_un.roi_un_finish
+};
+    
+/* \f */
+
+extern char *rosapversion;
+
+int    RoExec ();              /* SERVER only */
+int    RoInit ();              /* RO-BEGIN.INDICATION */
+
+int    RoBeginResponse ();     /* RO-BEGIN.RESPONSE */
+int    RoBeginRequest ();      /* RO-BEGIN.REQUEST */
+int    RoEndRequest ();        /* RO-END.REQUEST */
+int    RoEndResponse ();       /* RO-END.RESPONSE */
+
+int    RoInvokeRequest ();     /* RO-INVOKE.REQUEST */
+int    RoResultRequest ();     /* RO-RESULT.REQUEST */
+int    RoErrorRequest ();      /* RO-ERROR.REQUEST */
+int    RoURejectRequest ();    /* RO-U-REJECT.REQUEST */
+#define        RoRejectURequest        RoURejectRequest
+int    RoIntrRequest ();       /* RO-INVOKE.REQUEST (interruptable) */
+int    RoWaitRequest ();       /* RO-WAIT.REQUEST (pseudo) */
+
+int    RoSetIndications ();    /* define vectors for INDICATION events */
+int    RoSelectMask ();        /* map remote operation descriptors for
+                                  select() */
+
+int    RoSetService ();        /* bind underlying service */
+int    RoRtService (), RoPService (), RoSService ();
+int    RoSetThorn ();
+
+char   *RoErrString ();        /* return RoSAP error code in string form */
+#endif
diff --git a/src/isode/h/rosy.h b/src/isode/h/rosy.h
new file mode 100644 (file)
index 0000000..6767d05
--- /dev/null
@@ -0,0 +1,214 @@
+/* rosy.h - include file for ROSY users */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:46  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:12  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:26  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _ROSY_
+#define        _ROSY_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+
+#ifndef        _RoSAP_
+#include "rosap.h"             /* definitions for RoS-USERs */
+#endif
+
+/* \f */
+
+#ifdef PEPSY_VERSION
+#include "pepsy.h"
+#endif
+
+#ifdef PEPSY_DEFINITIONS
+/* This is really to change the name of the function RyOperation but the macro
+ * is unselective so we have to change the name of the structure as well, which
+ * shouldn't cause any problems
+ */
+#define RyOperation            PRyOperation
+#endif PEPSY_DEFINITIONS
+struct RyOperation {
+    char   *ryo_name;          /* operation name */
+    int            ryo_op;             /* operation code */
+
+#ifdef PEPSY_DEFINITIONS
+    modtyp *ryo_arg_mod;       /* pointer to table for arguement type */
+    int            ryo_arg_index;      /* index to entry in tables */
+#else
+    IFP            ryo_arg_encode;     /* encodes argument */
+    IFP            ryo_arg_decode;     /* decodes   .. */
+    IFP            ryo_arg_free;       /* frees     .. */
+#endif
+
+    int            ryo_result;         /* result possible */
+#ifdef PEPSY_DEFINITIONS
+    modtyp *ryo_res_mod;       /* pointer to table for result type */
+    int            ryo_res_index;      /* index to entry in tables */
+#else
+    IFP            ryo_res_encode;     /* encodes result */
+    IFP            ryo_res_decode;     /* decodes   .. */
+    IFP            ryo_res_free;       /* frees     .. */
+#endif
+
+    struct RyError **ryo_errors;/* errors possible */
+};
+
+
+
+struct RyError {
+    char   *rye_name;          /* error name */
+    int            rye_err;            /* error code */
+
+#ifdef PEPSY_DEFINITIONS
+    modtyp *rye_param_mod;     /* pointer to table for result type */
+    int            rye_param_index;    /* index to entry in tables */
+#else
+    IFP            rye_param_encode;   /* encodes parameter */
+    IFP            rye_param_decode;   /* decodes   .. */
+    IFP            rye_param_free;     /* frees     .. */
+#endif
+};
+
+/* \f */
+
+struct opsblk {
+    struct opsblk *opb_forw;   /* doubly-linked list */
+    struct opsblk *opb_back;   /*   .. */
+
+    short      opb_flags;      /* our state */
+#define        OPB_NULL        0x0000
+#define        OPB_EVENT       0x0001  /* event present */
+#define        OPB_INITIATOR   0x0002  /* initiator block */
+#define        OPB_RESPONDER   0x0004  /* responder block */
+
+    int            opb_fd;             /* association descriptor */
+    int            opb_id;             /* invoke ID */
+
+    IFP            opb_resfnx;         /* result vector */
+    IFP            opb_errfnx;         /* error vector */
+
+    struct RyOperation *opb_ryo;/* entry in operation table */
+
+    struct RoSAPindication opb_event;  /* resulting event */
+    caddr_t opb_out;                   /* event parameter */
+#ifdef PEPSY_DEFINITIONS
+    modtyp *opb_free_mod;      /* pointer to table for result type */
+    int            opb_free_index;     /* index to entry in tables */
+#else
+    IFP            opb_free;                   /* free routine for event parameter */
+#endif
+
+    PE     opb_pe;             /* for Simon */
+};
+#define        NULLOPB         ((struct opsblk *) 0)
+
+
+
+
+struct dspblk {
+    struct dspblk *dsb_forw;   /* doubly-linked list */
+    struct dspblk *dsb_back;   /*   .. */
+
+    int            dsb_fd;             /* association descriptor */
+                               /* NOTOK-valued is wildcard for RyWait */
+
+    struct RyOperation *dsb_ryo;/* entry in operation table */
+    
+    IFP            dsb_vector;         /* dispatch vector */
+};
+#define        NULLDSB         ((struct dspblk *) 0)
+
+
+
+#define        RY_RESULT       (-1)    /* distinguishes RESULTs from ERRORs */
+#define        RY_REJECT       (-2)    /* distinguishes REJECTs from ERRORs */
+
+/* \f */
+/* Change the names to use the pepsy based rosy library */
+#ifdef PEPSY_DEFINITIONS
+#define RyDiscard              PRyDiscard
+#define RyDispatch             PRyDispatch
+#define RyDsError              PRyDsError
+#define RyDsResult             PRyDsResult
+#define RyDsUReject            PRyDsUReject
+#define RyGenID                        PRyGenID
+#define RyLose                 PRyLose
+#define RyOpInvoke             PRyOpInvoke
+#define RyStub                 PRyStub
+#define RyWait                 PRyWait
+#define RyWaitAux              PRyWaitAux
+#define finddsblk              Pfinddsblk
+#define finderrbyerr           Pfinderrbyerr
+#define finderrbyname          Pfinderrbyname
+#define findopblk              Pfindopblk
+#define findopbyname           Pfindopbyname
+#define findopbyop             Pfindopbyop
+#define firstopblk             Pfirstopblk
+#define freedsblk              Pfreedsblk
+#define freeopblk              Pfreeopblk
+#define losedsblk              Plosedsblk
+#define loseopblk              Ploseopblk
+#define newdsblk               Pnewdsblk
+#define newopblk               Pnewopblk
+#endif
+
+int    RyWait ();              /* WAIT */
+
+                               /* Initiator */
+int    RyStub ();              /* STUB */
+#define        ROS_INTR        2       /*   invoke stub but return on interrupt */
+int    RyDiscard ();           /* DISCARD */
+int    RyOperation ();         /* OPERATION */
+int    RyOpInvoke ();          /* INVOKE */
+int    RyGenID ();             /* generate unique invoke ID */
+
+                               /* Responder */
+int    RyDispatch ();          /* DISPATCH */
+int    RyDsResult ();          /* RESULT */
+int    RyDsError ();           /* ERROR */
+int    RyDsUReject ();         /* U-REJECT */
+
+int    RyLose ();              /* clean-up after association termination */
+
+struct RyOperation *findopbyop (), *findopbyname ();
+
+struct RyError *finderrbyerr (), *finderrbyname ();
+
+int    freeopblk (), loseopblk ();
+struct opsblk *newopblk (), *findopblk (), *firstopblk ();
+
+int    freedsblk (), losedsblk ();
+struct dspblk *newdsblk (), *finddsblk ();
+
+#endif
diff --git a/src/isode/h/rtpkt.h b/src/isode/h/rtpkt.h
new file mode 100644 (file)
index 0000000..e120ef2
--- /dev/null
@@ -0,0 +1,223 @@
+/* rtpkt.h - include file for reliable transfer providers (RtS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:47  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:14  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:27  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _RtSAP_
+#include "rtsap.h"             /* definitions for RtS-USERs */
+#endif
+
+#include "acpkt.h"             /* definitions for AcS-PROVIDERs */
+
+#ifndef        _SSAP_
+#include "ssap.h"              /* definitions for SS-USERs */
+#endif
+
+/* \f */
+
+#define        rtsapPsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_RTS)) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_OPERATION, NULLCP, \
+                           "not an association descriptor for RTS"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_OPERATION, NULLCP, \
+                           "association descriptor not connected"); \
+    } \
+    if (acb -> acb_flags & ACB_FINN) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_OPERATION, NULLCP, \
+                           "association descriptor finishing"); \
+    } \
+}
+
+#define        rtsapFsig(acb, sd) \
+{ \
+    if ((acb = findacblk (sd)) == NULL) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_PARAMETER, NULLCP, \
+                           "invalid association descriptor"); \
+    } \
+    if (!(acb -> acb_flags & ACB_RTS)) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_OPERATION, NULLCP, \
+                           "not an association descriptor for RTS"); \
+    } \
+    if (!(acb -> acb_flags & ACB_CONN)) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_OPERATION, NULLCP, \
+                           "association descriptor not connected"); \
+    } \
+    if (!(acb -> acb_flags & ACB_FINN)) { \
+       (void) sigiomask (smask); \
+       return rtsaplose (rti, RTS_OPERATION, NULLCP, \
+                           "association descriptor not finishing"); \
+    } \
+}
+
+#ifdef __STDC__
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return rtsaplose (rti, RTS_PARAMETER, NULLCP, \
+                           "mandatory parameter \"%s\" missing", #p); \
+}
+#else 
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return rtsaplose (rti, RTS_PARAMETER, NULLCP, \
+                            "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+
+
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyRtSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyRtSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyRtSAPdata(base,len,d)       bcopy (base, (char *) d, len)
+#endif
+
+
+#define        pylose() \
+       rtpktlose (acb, rti, RTS_PROTOCOL, NULLCP, "%s", PY_pepy)
+
+
+/* would really prefer to determine DEFAULT_CKPOINT dynamically, but can't
+   since need to know it *before* doing the A-ASSOCIATE.REQUEST or
+   S-CONNECT.REQUEST... */
+
+#define        DEFAULT_CKPOINT (65518 >> 10)
+#define        DEFAULT_WINDOW  PCONN_WD_DFLT
+
+
+#define        RTS_MYREQUIRE   (SR_EXCEPTIONS | SR_ACTIVITY | SR_HALFDUPLEX \
+                           | SR_MINORSYNC)
+
+
+#define        RT_ASN          "rtse pci version 1"
+
+#if    USE_BUILTIN_OIDS
+#define RT_ASN_OID     str2oid ("2.3.0")
+#else
+#define RT_ASN_OID     ode2oid (RT_ASN)
+#endif
+
+int    rtpktlose (), rtsaplose ();
+
+/* \f */
+
+#define        SetPS2RtService(acb) \
+{ \
+    (acb) -> acb_pturnrequest = rt2pspturn; \
+    (acb) -> acb_gturnrequest = rt2psgturn; \
+    (acb) -> acb_transferequest = rt2pstrans; \
+    (acb) -> acb_rtwaitrequest = rt2pswait; \
+    (acb) -> acb_rtsetindications = rt2psasync; \
+    (acb) -> acb_rtselectmask = rt2psmask; \
+    (acb) -> acb_rtpktlose = rt2pslose; \
+}
+
+int    acs2rtslose (), acs2rtsabort (), ps2rtslose ();
+int    rt2pspturn (), rt2psgturn (), rt2pstrans (), rt2pswait (),
+       rt2psasync (), rt2psmask (), rt2pslose ();
+
+
+#define        SetSS2RtService(acb) \
+{ \
+    (acb) -> acb_pturnrequest = rt2sspturn; \
+    (acb) -> acb_gturnrequest = rt2ssgturn; \
+    (acb) -> acb_transferequest = rt2sstrans; \
+    (acb) -> acb_rtwaitrequest = rt2sswait; \
+    (acb) -> acb_rtsetindications = rt2ssasync; \
+    (acb) -> acb_rtselectmask = rt2ssmask; \
+    (acb) -> acb_rtpktlose = rt2sslose; \
+}
+
+int    ss2rtslose (), ss2rtsabort ();
+int    rt2sspturn (), rt2ssgturn (), rt2sstrans (), rt2sswait (),
+       rt2ssasync (), rt2ssmask (), rt2sslose ();
+
+/* \f */
+                               /* RTORQ apdu */
+#define        RTORQ_CKPOINT   0       /* checkpointSize tag */
+#define          RTORQ_CK_DFLT 0       /*   default */
+#define        RTORQ_WINDOW    1       /* windowSize tag */
+#define          RTORQ_WD_DFLT 3       /*   default */
+#define        RTORQ_DIALOGUE  2       /* dialogueMode tag */
+#define          RTORQ_DM_MONO 0       /*   monologue */
+#define          RTORQ_DM_TWA  1       /*   two-way alternate */
+#define          RTORQ_DM_DFLT RTORQ_DM_MONO
+#define        RTORQ_CONNDATA  3       /* connectionDataRQ tag */
+#define          RTORQ_CD_OPEN 0       /*   open tag */
+#define          RTORQ_CD_RCVR 1       /*   recover tag */
+
+                               /* RTOAC apdu */
+#define        RTOAC_CKPOINT   0       /* checkpointSize tag */
+#define          RTOAC_CK_DFLT 0       /*   default */
+#define        RTOAC_WINDOW    1       /* windowSize tag */
+#define          RTOAC_WD_DFLT 3       /*   default */
+#define        RTOAC_CONNDATA  2       /* connectionDataAC */
+#define          RTOAC_CD_OPEN 0       /*   open tag */
+#define          RTOAC_CD_RCVR 1       /*   recover tag */
+
+                               /* RTORJ apdu */
+#define        RTORJ_REFUSE    0       /* refuseReason tag */
+#define        RTORJ_USERDATA  1       /* userDataRJ */
+
+                               /* RTAB apdu */
+#define        RTAB_REASON     0       /* abortReason tag */
+#define        RTAB_REFLECT    1       /* relectedParameter tag */
+#define        RTAB_USERDATA   2       /* userDataAB */
+
+extern int rtsap_priority;
diff --git a/src/isode/h/rtsap.h b/src/isode/h/rtsap.h
new file mode 100644 (file)
index 0000000..e4a4711
--- /dev/null
@@ -0,0 +1,236 @@
+/* rtsap.h - include file for reliable transfer users (RtS-USER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:49  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:15  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:29  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _RtSAP_
+#define        _RtSAP_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+
+#ifndef        _AcSAP_
+#include "acsap.h"             /* definitions for AcS-USERs */
+#endif
+
+/* \f */
+
+struct RtSAPaddr {             /* RtSAP address (old-style) */
+    struct SSAPaddr rta_addr;
+
+    u_short    rta_port;
+};
+#define        NULLRtA                 ((struct RtSAPaddr *) 0)
+
+/* \f */
+
+struct RtSAPstart {            /* RT-OPEN.INDICATION */
+    int            rts_sd;             /* RTS descriptor */
+
+    struct RtSAPaddr rts_initiator;/* address */
+
+    int            rts_mode;           /* dialogue mode */
+#define        RTS_MONOLOGUE   0       /*   monologue */
+#define        RTS_TWA         1       /*   two-way alternate */
+
+    int            rts_turn;           /* initial turn */
+#define        RTS_INITIATOR   0       /*   the initiator */
+#define        RTS_RESPONDER   1       /*   the responder */
+
+    u_short rts_port;          /* application number */
+
+    PE     rts_data;           /* initial DATA from peer */
+
+    struct AcSAPstart rts_start;/* info from A-ASSOCIATE.INDICATION */
+};
+#define        RTSFREE(rts) \
+{ \
+    if ((rts) -> rts_data) \
+       pe_free ((rts) -> rts_data), (rts) -> rts_data = NULLPE; \
+    ACSFREE (&((rts) -> rts_start)); \
+}
+
+
+struct RtSAPconnect {          /* RT-OPEN.CONFIRMATION */
+    int            rtc_sd;             /* RTS descriptor */
+
+    int            rtc_result;         /* disposition */
+#define        RTS_ACCEPT      (-1)
+
+                               /* RT-OPEN.REQUEST */
+#define        RTS_BUSY        0       /* Busy */
+#define        RTS_RECOVER     1       /* Cannot recover */
+#define        RTS_VALIDATE    2       /* Validation failure */
+#define        RTS_MODE        3       /* Unacceptable dialogue mode */
+#define        RTS_REJECT      4       /* Rejected by responder */
+
+    PE     rtc_data;           /* initial DATA from peer */
+
+    struct AcSAPconnect rtc_connect;/* info from A-ASSOCIATE.CONFIRMATION */
+};
+#define        RTCFREE(rtc) \
+{ \
+    if ((rtc) -> rtc_data) \
+       pe_free ((rtc) -> rtc_data), (rtc) -> rtc_data = NULLPE; \
+    ACCFREE (&((rtc) -> rtc_connect)); \
+}
+
+
+struct RtSAPturn {             /* RT-TURN-{GIVE,PLEASE}.INDICATION */
+    int            rtu_please;         /* T   = RT-TURN-PLEASE.INDICATION
+                                  NIL = RT-TURN-GIVE.INDICATION */
+
+    int            rtu_priority;       /* priority, iff rtu_please == T */
+};
+
+
+struct RtSAPtransfer {         /* RT-TRANSFER.INDICATION */
+    PE     rtt_data;
+};
+#define        RTTFREE(rtt) \
+{ \
+    if ((rtt) -> rtt_data) \
+       pe_free ((rtt) -> rtt_data), (rtt) -> rtt_data = NULLPE; \
+}
+
+
+struct RtSAPabort {            /* RT-{U,P}-ABORT.INDICATION */
+    int     rta_peer;          /* T   = RT-U-ABORT.INDICATION
+                                  NIL = RT-P-ABORT.INDICATION */
+
+    int            rta_reason;         /* reason */
+                               /* begin UNOFFICIAL */
+#define        RTS_ADDRESS     5       /* Address unknown */
+#define        RTS_REFUSED     6       /* Connect request refused on this network
+                                  connection */
+#define        RTS_SESSION     7       /* Session disconnect */
+#define        RTS_PROTOCOL    8       /* Protocol error */
+#define        RTS_CONGEST     9       /* Congestion at RtSAP */
+#define        RTS_REMOTE      10      /* Remote system problem */
+#define        RTS_PRESENTATION 11     /* Presentation disconnect */
+#define        RTS_ACS         12      /* ACS disconnect */
+#define        RTS_ABORTED     13      /* Peer aborted association */
+#define        RTS_PARAMETER   14      /* Invalid parameter */
+#define        RTS_OPERATION   15      /* Invalid operation */
+#define        RTS_TIMER       16      /* Timer expired */
+#define        RTS_WAITING     17      /* Indications waiting */
+#define        RTS_TRANSFER    18      /* Transfer failure (not really unofficial) */
+                               /* end UNOFFICIAL */
+
+#define        RTS_FATAL(r)    ((r) < RTS_PARAMETER)
+#define        RTS_OFFICIAL(r) ((r) < RTS_ADDRESS)
+
+    PE     rta_udata;          /* failure data from user */
+
+                               /* additional failure data from provider */
+#define        RTA_SIZE        512
+    int            rta_cc;             /*   length */
+    char    rta_data[RTA_SIZE];        /*   data */
+};
+#define        RTAFREE(rta) \
+{ \
+    if ((rta) -> rta_udata) \
+       pe_free ((rta) -> rta_udata), (rta) -> rta_udata = NULLPE; \
+}
+
+
+struct RtSAPclose {            /* RT-CLOSE.INDICATION */
+    int            rtc_dummy;
+};
+
+
+struct RtSAPindication {
+    int            rti_type;           /* the union element present */
+#define        RTI_TURN        0x00
+#define        RTI_TRANSFER    0x01
+#define        RTI_ABORT       0x02
+#define        RTI_CLOSE       0x03
+#define        RTI_FINISH      0x04
+
+    union {
+       struct RtSAPturn rti_un_turn;
+       struct RtSAPtransfer rti_un_transfer;
+       struct RtSAPabort rti_un_abort;
+       struct RtSAPclose rti_un_close;
+       struct AcSAPfinish rti_un_finish;
+    }  rti_un;
+#define        rti_turn        rti_un.rti_un_turn
+#define        rti_transfer    rti_un.rti_un_transfer
+#define        rti_abort       rti_un.rti_un_abort
+#define        rti_close       rti_un.rti_un_close
+#define        rti_finish      rti_un.rti_un_finish
+};
+    
+/* \f */
+
+extern char *rtsapversion;
+
+                               /* RTSE primitives */
+int    RtInit_Aux ();          /* RT-OPEN.INDICATION */
+#define RtInit(vecp,vec,rts,rti) \
+       RtInit_Aux((vecp),(vec),(rts),(rti),NULLOID)
+int    RtOpenResponse ();      /* RT-OPEN.RESPONSE */
+#define RtOpenRequest(mode,turn,ctx,ct1,ct2,ca1,ca2,ctxl,defc,data,qos,rtc,rti)\
+       RtOpenRequest2((mode),(turn),(ctx),(ct1),(ct2),(ca1),(ca2),\
+               (ctxl),(defc),(data),(qos),NULLOID,(rtc),(rti))
+int    RtOpenRequest2 ();      /* RT-OPEN.REQUEST */
+int    RtCloseRequest ();      /* RT-CLOSE.REQUEST */
+int    RtCloseResponse ();     /* RT-CLOSE.RESPONSE */
+int    RtUAbortRequest ();     /* RT-U-ABORT.REQUEST */
+
+                               /* X.410 primitives */
+int    RtExec ();              /* SERVER only */
+int    RtBInit ();             /* RT-BEGIN.INDICATION (X.410 OPEN.INDICATION) */
+int    RtBeginResponse ();     /* RT-BEGIN.RESPONSE (X.410 OPEN.RESPONSE) */
+int    RtBeginRequest2 ();     /* RT-BEGIN.REQUEST (X.410 OPEN.REQUEST) */
+#define RtBeginRequest(called, mode, turn, data, rtc, rti) \
+       RtBeginRequest2((called), NULLRtA, (mode), (turn), (data), (rtc), (rti))
+int    RtEndRequest ();        /* RT-END.REQUEST (X.410 CLOSE.REQUEST) */
+int    RtEndResponse ();       /* RT-END.RESPONSE (X.410 CLOSE.RESPONSE) */
+
+int    RtPTurnRequest ();      /* RT-TURN-PLEASE.REQUEST */
+int    RtGTurnRequest ();      /* RT-TURN-GIVE.REQUEST */
+int    RtTransferRequest ();   /* RT-TRANSFER.REQUEST */
+int    RtWaitRequest ();       /* RT-WAIT.REQUEST (pseudo) */
+
+int    RtSetIndications ();    /* define vectors for INDICATION events */
+int    RtSelectMask ();        /* map reliable transfer descriptors for
+                                  select() */
+
+int    RtSetDownTrans ();      /* set downtrans upcall */
+int    RtSetUpTrans ();        /* set uptrans upcall */
+
+char   *RtErrString ();                /* return RtSAP error code in string form */
+#endif
diff --git a/src/isode/h/spkt.h b/src/isode/h/spkt.h
new file mode 100644 (file)
index 0000000..3f0a23f
--- /dev/null
@@ -0,0 +1,943 @@
+/* spkt.h - include file for session providers (SS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:52  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:18  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:31  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:55  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _SSAP_
+#include "ssap.h"              /* definitions for SS-USERs */
+#endif
+
+#include "tsap.h"              /* definitions for TS-USERs */
+
+
+/* \f */
+
+#define        ssapPsig(sb, sd) \
+{ \
+    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"); \
+    } \
+    if (sb -> sb_flags & SB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+    if (sb -> sb_flags & SB_MAP) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "majorsync in progress"); \
+    } \
+    if (sb -> sb_flags & SB_RS) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "resync in progress"); \
+    } \
+    if (sb -> sb_flags & SB_RA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your resync response"); \
+    } \
+    if (sb -> sb_flags & SB_AI) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "activity interrupt/discard in progress"); \
+    } \
+    if (sb -> sb_flags & SB_AIA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your activity interrupt/discard response"); \
+    } \
+    if (sb -> sb_flags & (SB_ED | SB_EDACK | SB_ERACK)) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "exception in progress"); \
+    } \
+}
+
+#define        ssapXsig(sb, sd) \
+{ \
+    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"); \
+    } \
+    if (sb -> sb_flags & SB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+    if (sb -> sb_flags & SB_RS) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "resync in progress"); \
+    } \
+    if (sb -> sb_flags & SB_RA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your resync response"); \
+    } \
+    if (sb -> sb_flags & SB_AI) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "activity interrupt/discard in progress"); \
+    } \
+    if (sb -> sb_flags & SB_AIA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your activity interrupt/discard response"); \
+    } \
+    if (sb -> sb_flags & SB_ED) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "exception in progress"); \
+    } \
+}
+
+#define        ssapRsig(sb, sd) \
+{ \
+    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"); \
+    } \
+    if (sb -> sb_flags & SB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+    if (sb -> sb_flags & SB_RS) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "resync in progress"); \
+    } \
+    if (sb -> sb_flags & SB_AI) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "activity interrupt/discard in progress"); \
+    } \
+    if (sb -> sb_flags & SB_AIA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your activity interrupt/discard response"); \
+    } \
+    if (sb -> sb_flags & SB_AE) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "activity end in progress"); \
+    } \
+    if (sb -> sb_flags & SB_ED) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "exception in progress"); \
+    } \
+}
+
+#define        ssapAsig(sb, sd) \
+{ \
+    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"); \
+    } \
+    if (sb -> sb_flags & SB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+    if (sb -> sb_flags & SB_MAA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your majorsync response"); \
+    } \
+    if (sb -> sb_flags & SB_RS) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "resync in progress"); \
+    } \
+    if (sb -> sb_flags & SB_AI) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "activity interrupt/discard in response"); \
+    } \
+    if (sb -> sb_flags & (SB_ED | SB_EDACK | SB_ERACK)) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "exception in progress"); \
+    } \
+}
+
+#define        ssapFsig(sb, sd) \
+{ \
+    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 not finishing"); \
+    } \
+    if (sb -> sb_flags & SB_RELEASE) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "release in progress"); \
+    } \
+    if (sb -> sb_flags & SB_MAA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your majorsync response"); \
+    } \
+    if (sb -> sb_flags & SB_RS) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "resync in progress"); \
+    } \
+    if (sb -> sb_flags & SB_RA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your resync response"); \
+    } \
+    if (sb -> sb_flags & SB_AI) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "activity interrupt/discard in progress"); \
+    } \
+    if (sb -> sb_flags & SB_AIA) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "awaiting your activity interrupt/discard response"); \
+    } \
+    if (sb -> sb_flags & (SB_ED | SB_EDACK | SB_ERACK)) { \
+       (void) sigiomask (smask); \
+       return ssaplose (si, SC_OPERATION, NULLCP, \
+                           "exception in progress"); \
+    } \
+}
+
+#ifdef __STDC__
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return ssaplose (si, SC_PARAMETER, NULLCP, \
+                           "mandatory parameter \"%s\" missing", #p); \
+}
+#else
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return ssaplose (si, SC_PARAMETER, NULLCP, \
+                            "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+
+#define        refmuchP(sr) \
+{ \
+    if ((sr) -> sr_ulen > SREF_USER_SIZE \
+           || (sr) -> sr_clen > SREF_COMM_SIZE \
+           || (sr) -> sr_alen > SREF_ADDT_SIZE \
+           || (sr) -> sr_vlen > SREF_USER_SIZE) \
+       return ssaplose (si, SC_PARAMETER, NULLCP, \
+               "bad format for reference"); \
+}
+
+#define        idmuchP(sd) \
+{ \
+    if ((sd) -> sd_len > SID_DATA_SIZE) \
+       return ssaplose (si, SC_PARAMETER, NULLCP, \
+               "bad format for activity ID"); \
+}
+
+#define        toomuchP(sb,b,n,m,p) \
+{ \
+    if (b == NULL) \
+       n = 0; \
+    else \
+       if (n > (sb -> sb_version < SB_VRSN2 ? m : ENCLOSE_MAX)) { \
+           (void) sigiomask (smask); \
+           return ssaplose (si, SC_PARAMETER, NULLCP, \
+                           "too much %s user data, %d octets", p, n); \
+       } \
+}
+
+
+#define        NULLTX  ((struct TSAPdata *) 0)
+#define        NULLSD  ((struct SSAPactid *) 0)
+#define        NULLSR  ((struct SSAPref *) 0)
+
+
+#ifndef        lint
+#ifndef        __STDC__
+#define        copySSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+
+#define        copySPKTdata(s,d) \
+{ \
+    d -> d/* */_data = s -> s_udata, d -> d/* */_cc = s -> s_ulen; \
+    s -> s_udata = NULL; \
+}
+#else
+#define        copySSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+
+#define        copySPKTdata(s, d) \
+{ \
+    d -> d##_data = s -> s_udata, d -> d##_cc = s -> s_ulen; \
+    s -> s_udata = NULL; \
+}
+#endif
+#else
+#define        copySSAPdata(base,len,d)        bcopy (base, (char *) d, len)
+
+#define        copySPKTdata(s,d)       bcopy (s -> s_udata, (char *) d, s -> s_ulen)
+#endif
+
+
+#define        AB_TIM          30      /* drain for 30 seconds on ABORTs */
+#define        RF_TIM          30      /* drain for 30 seconds on REFUSEs */
+
+
+#define        SC_REFUSE       (SC_BASE << 1)  /* larger than any sc_reason */
+
+
+int    spktlose (), ssaplose ();
+
+/* \f */
+
+struct ssapblk {
+    struct ssapblk *sb_forw;   /* doubly-linked list */
+    struct ssapblk *sb_back;   /*   .. */
+
+    int     sb_fd;             /* transport descriptor */
+
+    int            sb_version;         /* version number of protocol */
+#define        SB_VRSN1        0       /*   1 */
+#define        SB_VRSN2        1       /*   2 */
+#define        SB_ALLVRSNS     ((1 << SB_VRSN1) | (1 << SB_VRSN2))
+    int            sb_vrsnmask;        /* for initiating SPM... */
+
+    long    sb_flags;          /* our state */
+#define        SB_NULL         0x000000
+#define        SB_CONN         0x000001/* connected */
+#define        SB_FINN         0x000002/* other side wants to finish */
+#define        SB_INIT         0x000004/* this side initiated the session */
+#define        SB_ASYN         0x000008/* asynchronous */
+#define        SB_EXPD         0x000010/* expedited service available on transport */
+#define        SB_CD           0x000020/* CD request in progress */
+#define        SB_CDA          0x000040/* awaiting CD response from user */
+#define        SB_GTC          0x000080/* GTC request in progress */
+#define        SB_MAP          0x000100/* MAP request in progress */
+#define        SB_MAA          0x000200/* awaiting MAP response from user */
+#define        SB_AE           0x000400/* MAP is really AE */
+#define        SB_RS           0x000800/* RS request in progress */
+#define        SB_RA           0x001000/* awaiting RS response from user */
+#define        SB_AI           0x002000/* AI request in progress */
+#define        SB_AIA          0x004000/* awaiting AI response from user */
+#define        SB_ED           0x008000/* user exception in progress */
+#define        SB_EDACK        0x010000/* awaiting user exception to be cleared */
+#define        SB_ERACK        0x020000/* awaiting provider exception to be cleared */
+#define        SB_Vact         0x040000/* activity in progress */
+#define        SB_Vsc          0x080000/* okay to reply to minorsync */
+#define        SB_Vnextact     0x100000/* activity MAP sent/received */
+#define        SB_RELEASE      0x200000/* release in progress */
+
+#define SB_ASYNC_CONN  0x400000/* connections are async */
+#define SB_TS_CONN     0x800000/* TS is established */
+
+    struct TSAPconnect sb_tc;
+    struct ssapkt *sb_retry;   /* initial/final spkt */
+
+    long    sb_V_A;            /* lowest unconfirmed ssn */
+    long    sb_V_M;            /* next ssn */
+    long    sb_V_R;            /* lowest ssn for resynchronization */
+    int            sb_rs;              /* resynchronization type
+                                    (an SYNC_xxx code, plus...) */
+#define        SYNC_INTR       3       /* Activity Interrupt */
+#define        SYNC_DISC       4       /* Activity Discard */
+    long    sb_rsn;            /* resync serial number */
+    u_char  sb_rsettings;      /* proposed token settings */
+
+    int            sb_pr;              /* SPDU to prepare for (an SPDU code) */
+    struct ssapkt *sb_xspdu;   /* saved expedited SPDU
+                                  (really should be a linked list!) */
+
+    struct ssapkt *sb_spdu;    /* for concatenated SPDUs */
+
+    struct qbuf sb_qbuf;       /* for segmented (T)SSDUs */
+    int            sb_len;             /*   .. */
+    int            sb_code;            /*   .. */
+
+    u_char  sb_options;                /* connect options */
+    u_char  sb_settings;       /* tokens settings on connect */
+
+    u_short sb_tsdu_us;                /* our max TSDU size */
+    u_short sb_tsdu_them;      /* their max TSDU size */
+#define        BAD_TSDU_SIZE(s)        ((s) ? (s) < DT_MINSIZE : 0)
+#define        GET_TSDU_SIZE(s)        ((s) < DT_MINSIZE ? 0 : (s))
+
+    u_char  sb_owned;          /* tokens we own */
+    u_short sb_requirements;   /* functional units selected */
+
+    struct SSAPaddr sb_initiating;     /* initiator */
+    struct SSAPaddr sb_responding;     /* responder */
+
+    int            sb_maxtime;         /* for SPM response during S-CONNECT */
+
+    IFP            sb_DataIndication;          /* INDICATION handlers */
+    IFP            sb_TokenIndication;         /*   .. */
+    IFP            sb_SyncIndication;          /*   .. */
+    IFP            sb_ActivityIndication;      /*   .. */
+    IFP            sb_ReportIndication;        /*   .. */
+    IFP            sb_ReleaseIndication;       /*   .. */
+    IFP            sb_AbortIndication;         /*   .. */
+};
+#define        NULLBP          ((struct ssapblk *) 0)
+
+int    freesblk ();
+struct ssapblk *newsblk (), *findsblk ();
+
+
+int    ts2sslose ();
+
+int    spkt2sd ();
+struct ssapkt *sb2spkt ();
+
+/* \f   SPKT datastructure */
+
+struct ssapkt {
+    int            s_errno;
+
+    int            s_mask;
+
+    u_char    s_code;
+#define        SPDU_CN         0x0d    /* CONNECT */
+#define        SPDU_AC         0x0e    /* ACCEPT */
+#define        SPDU_RF         0x0c    /* REFUSE */
+#define        SPDU_FN         0x09    /* FINISH */
+#define        SPDU_DN         0x0a    /* DISCONNECT */
+#define        SPDU_NF         0x08    /* NOT FINISHED */
+#define        SPDU_AB         0x19    /* ABORT */
+#define        SPDU_AA         0x1a    /* ABORT ACCEPT */
+#define        SPDU_DT         SPDU_GT /* DATA TRANSFER */
+#define        SPDU_EX         0x05    /* EXPEDITED */
+#define        SPDU_TD         0x21    /* TYPED DATA */
+#define        SPDU_CD         0x3d    /* CAPABILITY DATA */
+#define        SPDU_CDA        0x3e    /* CAPABILITY DATA ACK */
+#define        SPDU_GT         0x01    /* GIVE TOKENS */
+#define        SPDU_PT         0x02    /* PLEASE TOKENS */
+#define        SPDU_GTC        0x15    /* GIVE TOKENS CONFIRM */
+#define        SPDU_GTA        0x16    /* GIVE TOKENS ACK */
+#define        SPDU_MIP        0x31    /* MINOR SYNCHRONIZATION POINT */
+#define        SPDU_MIA        0x32    /* MINOR SYNC ACK */
+#define        SPDU_MAP        0x29    /* MAJOR SYNCHRONIZATION POINT */
+#define        SPDU_MAA        0x2a    /* MAJOR SYNC ACK */
+#define        SPDU_RS         0x35    /* RESYNCHRONIZE */
+#define        SPDU_RA         0x22    /* RESYNCHRONIZE ACK */
+#define        SPDU_PR         0x07    /* PREPARE */
+#define        SPDU_ER         0x00    /* EXCEPTION REPORT */
+#define        SPDU_ED         0x30    /* EXCEPTION DATA */
+#define        SPDU_AS         0x2d    /* ACTIVITY START */
+#define        SPDU_AR         0x1d    /* ACTIVITY RESUME */
+#define        SPDU_AI         SPDU_AB /* ACTIVITY INTERRUPT */
+#define        SPDU_AIA        SPDU_AA /* ACTIVITY INTERRUPT ACK */
+#define        SPDU_AD         0x39    /* ACTIVITY DISCARD */
+#define        SPDU_ADA        0x3a    /* ACTIVITY DISCARD ACK */
+#define        SPDU_AE         SPDU_MAP/* ACTIVITY END */
+#define        SPDU_AEA        SPDU_MAA/* ACTIVITY END ACK */
+
+    u_long    s_li;
+#define        SPDU_MAXLEN     65535   /* segment if SSDU larger */
+
+/* A nice magic number:
+       for the GT SPDU, 2 octets
+       for the DT SPDU, 2 octets + 3 octets for the enclosure option
+
+    2 + 2 + 3 = 7
+ */
+#define        SSDU_MAGIC      7
+
+    union {
+       struct {                /* CONNECT/ACCEPT SPDU */
+#define        SMASK_CN_REF    0x0001
+           struct SSAPref un_cn_reference;
+
+           struct {
+#define        SMASK_CN_OPT    0x0002
+               u_char  un_cn_options;
+#define        CR_OPT_NULL     0x00
+#define        CR_OPT_EXTD     0x01    /* will receive extended concatenated SPDUs,
+                                  this implementation DOESN'T; segmenting is
+                                  enough... */
+#define        CR_OPT_MASK     CR_OPT_EXTD
+
+#define        SMASK_CN_TSDU   0x0004
+               u_short un_cn_tsdu_init;
+               u_short un_cn_tsdu_resp;
+
+#define        SMASK_CN_VRSN   0x0008
+               u_char  un_cn_version;
+
+#define        SMASK_CN_ISN    0x0010
+#define        SIZE_CN_ISN     6
+               u_long  un_cn_isn;
+
+#define        SMASK_CN_SET    0x0020
+               u_char  un_settings;
+           }   un_cn_item;
+
+#define        SMASK_AC_TOKEN  0x0040
+           u_char      un_ac_token;/* ACCEPT SPDU only */
+
+#define        SMASK_CN_REQ    0x0080
+           u_short     un_cn_requirements;
+
+#define        SMASK_CN_CALLING 0x0100
+           char        un_cn_calling[SSSIZE];
+           int         un_cn_callinglen;
+
+#define        SMASK_CN_CALLED 0x0200
+           char        un_cn_called[SSSIZE];
+           int         un_cn_calledlen;
+       }       un_cn;
+#define        CN_SIZE         512
+#define        CONNECT_MAX     10240   /* someday support CDO/OA SPDUs and Data
+                                  Overflow PI... */
+#define CN_BASE_SIZE   56
+#define        AC_SIZE         512
+#define AC_BASE_SIZE   62
+
+       struct {                /* REFUSE SPDU */
+#define        SMASK_RF_REF    0x0001
+           struct SSAPref un_rf_reference;
+
+#define        SMASK_RF_DISC   0x0002
+           u_char      un_rf_disconnect;
+#define        RF_DISC_RELEASE 0x01    /* release transport connection */
+#define        RF_DISC_MASK    RF_DISC_RELEASE
+
+#define        SMASK_RF_REQ    0x0004
+           u_short     un_rf_requirements;
+
+#define        SMASK_RF_VRSN   0x0008
+           u_char      un_rf_version;
+
+           char       *un_rf_rdata;
+           int         un_rf_rlen;
+       }       un_rf;
+#define        RF_SIZE         513
+#define RF_BASE_SIZE   13
+       
+       struct {                /* FINISH SPDU */
+#define        SMASK_FN_DISC   0x0001
+           u_char      un_fn_disconnect;
+#define        FN_DISC_RELEASE 0x01    /* release transport connection */
+#define        FN_DISC_MASK    FN_DISC_RELEASE
+       }       un_fn;
+#define        FN_SIZE         512
+#define FN_BASE_SIZE   6
+           
+                               /* DISCONNECT SPDU */
+#define        DN_SIZE         512
+#define DN_BASE_SIZE   3
+
+                               /* NOT FINISHED SPDU */
+#define        NF_SIZE         512
+#define NF_BASE_SIZE   3
+
+       struct {                /* ABORT SPDU */
+#define        SMASK_AB_DISC   0x0001
+           u_char      un_ab_disconnect;
+#define        AB_DISC_RELEASE 0x01    /* release transport connection */
+#define        AB_DISC_USER    0x02    /* user abort */
+#define        AB_DISC_PROTO   0x04    /* protocol error */
+#define        AB_DISC_UNKNOWN 0x08    /* no reason */
+#define        AB_DISC_MASK    (AB_DISC_RELEASE | AB_DISC_USER | AB_DISC_PROTO \
+                           | AB_DISC_UNKNOWN)
+
+#define        SMASK_AB_REFL   0x0002
+#define        AB_REFL_SIZE    9
+           u_char      un_ab_reflect[AB_REFL_SIZE];
+       }       un_ab;
+#define        AB_SIZE         9
+#define AB_BASE_SIZE   17
+#define        SMASK_SPDU_AB   0x0004
+                               /* to distinguish between AB and AI SPDUs */
+
+       
+                               /* ABORT ACCEPT SPDU */
+#define        AA_SIZE         0
+#define AA_BASE_SIZE   0
+#define        SMASK_SPDU_AA   0x0001  /* to distinguish between AA and AIA SPDUs */
+
+
+                               /* DATA TRANSFER SPDU */
+#define        DT_SIZE         65535
+#define        DT_MINSIZE      64      /* don't segment if MSS < this */
+#define DT_BASE_SIZE   3
+       
+                               /* EXPEDITED DATA SPDU */
+#define        EX_SIZE         SX_EXSIZE
+#define EX_BASE_SIZE   0
+
+                               /* TYPED DATA SPDU */
+#define        TD_SIGHS        65535   /* should be TD_SIZE, but <tsap.h>
+                                  got there first */
+#define        TD_MINSIZE      64      /* don't segment if MSS < this */
+#define TD_BASE_SIZE   3
+
+                               /* CAPABILITY DATA SPDU */
+#define        CD_SIZE         SX_CDSIZE
+#define CD_BASE_SIZE   3
+
+                               /* CAPABILITY DATA ACK SPDU */
+#define        CDA_SIZE        SX_CDASIZE
+#define CDA_BASE_SIZE  3
+
+       struct {                /* GIVE TOKENS SPDU */
+#define        SMASK_GT_TOKEN  0x0001
+           u_char      un_gt_token;
+       }       un_gt;
+#define        GT_SIZE         0
+#define GT_BASE_SIZE   3
+#define        SMASK_SPDU_GT   0x0002  /* to distinguish between DT and GT SPDUs */
+       
+       struct {                /* PLEASE TOKENS SPDU */
+#define        SMASK_PT_TOKEN  0x0001
+           u_char      un_pt_token;
+       }       un_pt;
+#define        PT_SIZE         512
+#define PT_BASE_SIZE   6
+
+                               /* GIVE TOKENS CONFIRM SPDU */
+#define        GTC_SIZE        0
+#define GTC_BASE_SIZE  0
+
+                               /* GIVE TOKENS ACK SPDU */
+#define        GTA_SIZE        0
+#define GTA_BASE_SIZE  0
+
+       struct {                /* MINOR SYNC POINT SPDU */
+#define        SMASK_MIP_SYNC  0x0001
+           u_char      un_mip_sync;
+#define        MIP_SYNC_NOEXPL 0x01    /* NO EXPLICIT ACK REQUIRED */
+#define        MIP_SYNC_MASK   MIP_SYNC_NOEXPL
+
+#define        SMASK_MIP_SERIAL 0x0002
+           u_long      un_mip_serial;
+       }       un_mip;
+#define        MIP_SIZE        512
+#define MIP_BASE_SIZE  14
+
+       struct {                /* MINOR SYNC ACK SPDU */
+#define        SMASK_MIA_SERIAL 0x0001
+           u_long      un_mia_serial;
+       }       un_mia;
+#define        MIA_SIZE        512
+#define MIA_BASE_SIZE  11
+
+       struct {                /* MAJOR SYNC POINT SPDU */
+#define        SMASK_MAP_SYNC  0x0001
+           u_char      un_map_sync;
+#define        MAP_SYNC_NOEND  0x01    /* ACTIVITY NOT ENDED (i.e., MAP not AE) */
+#define        MAP_SYNC_MASK   MAP_SYNC_NOEND
+
+#define        SMASK_MAP_SERIAL 0x0002
+           u_long      un_map_serial;
+       }       un_map;
+#define        MAP_SIZE        512
+#define MAP_BASE_SIZE  14
+
+       struct {                /* MAJOR SYNC ACK SPDU */
+#define        SMASK_MAA_SERIAL 0x0001
+           u_long      un_maa_serial;
+       }       un_maa;
+#define        MAA_SIZE        512
+#define MAA_BASE_SIZE  11
+
+       struct {                /* RESYNCHRONIZE SPDU */
+#define        SMASK_RS_SET    0x0001
+           u_char      un_rs_settings;
+
+#define        SMASK_RS_TYPE   0x0002
+           u_char      un_rs_type;
+#define        SYNC_OK(r)      (((unsigned) (r)) <= SYNC_SET)
+
+#define        SMASK_RS_SSN    0x0004
+           u_long      un_rs_serial;
+    }      un_rs;
+#define        RS_SIZE         512
+#define RS_BASE_SIZE   17
+
+       struct {                /* RESYNCHRONIZE ACK SPDU */
+#define        SMASK_RA_SET    0x0001
+           u_char      un_ra_settings;
+
+#define        SMASK_RA_SSN    0x0002
+           u_long      un_ra_serial;
+       }    un_ra;
+#define        RA_SIZE         512
+#define RA_BASE_SIZE   14
+
+       struct {                /* PREPARE SPDU */
+#define        SMASK_PR_TYPE   0x0001
+           u_char          un_pr_type;
+#define        PR_MAA          1       /* expect SPDU_MAA */
+#define        PR_RS           2       /* expect SPDU_RS */
+#define        PR_RA           3       /* expect SPDU_RA */
+#define        PR_AB           4       /* expect SPDU_AB */
+#define        PR_MAX          PR_AB
+       }    un_pr;
+#define        PR_SIZE         0
+#define PR_BASE_SIZE   3
+
+                               /* EXCEPTION REPORT SPDU */
+#define        ER_SIZE         0
+#define ER_BASE_SIZE   0
+
+       struct {                /* EXCEPTION DATA SPDU */
+#define        SMASK_ED_REASON 0x0001
+           u_char      un_ed_reason;
+#define        SP_OK(r)        (((r) < SP_PROCEDURAL \
+                               && (r) != SP_RSVD1 \
+                               && (r) != SP_RSVD2) \
+                           || (r) == SP_DEMAND)
+       }    un_ed;
+#define        ED_SIZE         512
+#define ED_BASE_SIZE   6
+
+       struct {                /* ACTIVITY START SPDU */
+#define        SMASK_AS_ID     0x0001
+           struct SSAPactid un_as_id;
+       }    un_as;     
+#define        AS_SIZE         512
+#define AS_BASE_SIZE   11
+
+       struct {                /* ACTIVITY RESUME SPDU */
+           struct {
+#define        SMASK_AR_REF    0x0001
+               struct SSAPref un_ar_reference;
+
+#define        SMASK_AR_OID    0x0002
+               struct SSAPactid un_ar_oid;
+
+#define        SMASK_AR_SSN    0x0004
+               u_long  un_ar_serial;
+           }   un_ar_link;
+
+#define        SMASK_AR_ID     0x0008
+           struct SSAPactid un_ar_id;
+       }    un_ar;
+#define        AR_SIZE         512
+#define AR_BASE_SIZE   29
+
+       struct {                /* ACTIVITY INTERRUPT (ABORT) SPDU */
+#define        SMASK_AI_REASON 0x0001  /* don't collide with SMASK_AB_DISC */
+           u_char      un_ai_reason;
+       }    un_ai;
+#define        AI_SIZE         0
+#define AI_BASE_SIZE   3
+
+                               /* ACTIVITY INTERRUPT (ABORT) ACK SPDU */
+#define        AIA_SIZE        0
+#define AIA_BASE_SIZE  0
+
+
+       struct {                /* ACTIVITY DISCARD SPDU */
+#define        SMASK_AD_REASON 0x0001
+           u_char      un_ad_reason;
+       }    un_ad;
+#define        AD_SIZE         0
+#define AD_BASE_SIZE   3
+
+                               /* ACTIVITY DISCARD ACK SPDU */
+#define        ADA_SIZE        0
+#define ADA_BASE_SIZE  0
+
+                               /* ACTIVITY END (MAJOR SYNC) SPDU */
+#define        AE_SIZE         512
+#define AE_BASE_SIZE   8
+
+                               /* ACTIVITY END (MAJOR SYNC) ACK SPDU */
+#define        AEA_SIZE        MAA_SIZE
+#define AEA_BASE_SIZE  MAA_BASE_SIZE
+    }  s_un;
+#define        s_cn_reference  s_un.un_cn.un_cn_reference
+#define        s_options       s_un.un_cn.un_cn_item.un_cn_options
+#define s_tsdu_init    s_un.un_cn.un_cn_item.un_cn_tsdu_init
+#define s_tsdu_resp    s_un.un_cn.un_cn_item.un_cn_tsdu_resp
+#define s_cn_version   s_un.un_cn.un_cn_item.un_cn_version
+#define s_isn          s_un.un_cn.un_cn_item.un_cn_isn
+#define s_settings     s_un.un_cn.un_cn_item.un_settings
+#define        s_ac_token      s_un.un_cn.un_ac_token
+#define        s_cn_require    s_un.un_cn.un_cn_requirements
+#define        s_calling       s_un.un_cn.un_cn_calling
+#define        s_callinglen    s_un.un_cn.un_cn_callinglen
+#define        s_called        s_un.un_cn.un_cn_called
+#define        s_calledlen     s_un.un_cn.un_cn_calledlen
+
+#define        s_rf_reference  s_un.un_rf.un_rf_reference
+#define        s_rf_disconnect s_un.un_rf.un_rf_disconnect
+#define        s_rf_require    s_un.un_rf.un_rf_requirements
+#define        s_rf_version    s_un.un_rf.un_rf_version
+#define        s_rdata         s_un.un_rf.un_rf_rdata
+#define        s_rlen          s_un.un_rf.un_rf_rlen
+
+#define        s_fn_disconnect s_un.un_fn.un_fn_disconnect
+
+#define        s_ab_disconnect s_un.un_ab.un_ab_disconnect
+#define        s_reflect       s_un.un_ab.un_ab_reflect
+
+#define        s_gt_token      s_un.un_gt.un_gt_token
+
+#define        s_pt_token      s_un.un_pt.un_pt_token
+
+#define        s_mip_sync      s_un.un_mip.un_mip_sync
+#define        s_mip_serial    s_un.un_mip.un_mip_serial
+
+#define        s_mia_serial    s_un.un_mia.un_mia_serial
+
+#define        s_map_sync      s_un.un_map.un_map_sync
+#define        s_map_serial    s_un.un_map.un_map_serial
+
+#define        s_maa_serial    s_un.un_maa.un_maa_serial
+
+#define        s_rs_settings   s_un.un_rs.un_rs_settings
+#define        s_rs_type       s_un.un_rs.un_rs_type
+#define        s_rs_serial     s_un.un_rs.un_rs_serial
+
+#define        s_ra_settings   s_un.un_ra.un_ra_settings
+#define        s_ra_serial     s_un.un_ra.un_ra_serial
+
+#define        s_pr_type       s_un.un_pr.un_pr_type
+
+#define        s_ed_reason     s_un.un_ed.un_ed_reason
+
+#define        s_as_id         s_un.un_as.un_as_id
+
+#define        s_ar_reference  s_un.un_ar.un_ar_link.un_ar_reference
+#define        s_ar_oid        s_un.un_ar.un_ar_link.un_ar_oid
+#define        s_ar_serial     s_un.un_ar.un_ar_link.un_ar_serial
+#define        s_ar_id         s_un.un_ar.un_ar_id
+
+#define        s_ai_reason     s_un.un_ai.un_ai_reason
+
+#define        s_ad_reason     s_un.un_ad.un_ad_reason
+
+
+#define        SMASK_ENCLOSE   0x2000
+    u_char    s_enclose;
+#define        ENCL_BEGIN      0x01    /* beginning of SSDU */
+#define        ENCL_END        0x02    /* end of SSDU */
+#define        ENCL_MASK       (ENCL_BEGIN | ENCL_END)
+#define        ENCLOSE_MAX     65400   /* maximum size of enclosure per segment
+                                  less slop; slop varies based on SPDU, but
+                                  we'll always assume the worst case */
+#define        SEGMENT_MAX     65528   /* for things other than S-DATA and
+                                  S-TYPED-DATA under version 2 we allow only
+                                  ONE enclosure */
+
+#define        SMASK_UDATA_PGI 0x4000
+    char   *s_udata;           /* user data PGI */
+    int            s_ulen;             /*   .. */
+
+#define        SMASK_SPDU_EXPD 0x8000  /* SPDU arrived on the expedited connection */
+
+    struct qbuf s_qbuf;                /* user info */
+    int            s_qlen;             /*   .. */
+};
+#define        NULLSPKT        ((struct ssapkt *) 0)
+
+
+int    freespkt ();
+struct ssapkt *newspkt ();
+
+void   text2spkt (), spkt2text ();
+
+int    spkt2tsdu ();
+struct ssapkt *tsdu2spkt ();
+
+char   *spkt2str ();
+struct ssapkt *str2spkt ();
diff --git a/src/isode/h/ssap.h b/src/isode/h/ssap.h
new file mode 100644 (file)
index 0000000..ad521fc
--- /dev/null
@@ -0,0 +1,518 @@
+/* ssap.h - include file for session users (SS-USER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:29:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:21  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:34  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:56  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _SSAP_
+#define        _SSAP_
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+#ifndef        _ISOADDRS_
+#include "isoaddrs.h"
+#endif
+
+/* \f */
+
+struct SSAPactid {             /* Activity Identifier */
+#define        SID_DATA_SIZE   6
+    u_char  sd_len;
+    char    sd_data[SID_DATA_SIZE];
+};
+
+struct SSAPref {               /* SSAP reference */
+                               /* USER reference */
+#define        SREF_USER_SIZE          64
+    u_char  sr_ulen;
+    char    sr_udata[SREF_USER_SIZE];
+
+                               /* COMMON reference */
+#define        SREF_COMM_SIZE          64
+    u_char  sr_clen;
+    char    sr_cdata[SREF_COMM_SIZE];
+
+                               /* ADDITIONAL reference */
+#define        SREF_ADDT_SIZE  4
+    u_char  sr_alen;
+    char    sr_adata[SREF_ADDT_SIZE];
+
+                               /* for S-ACTIVITY-RESUME */
+    u_char  sr_vlen;
+    char    sr_vdata[SREF_USER_SIZE];
+
+#define        sr_calling      sr_udata
+#define        sr_calling_len  sr_ulen
+#define        sr_called       sr_vdata
+#define        sr_called_len   sr_vlen
+};
+
+/* \f */
+
+struct SSAPstart {             /* S-CONNECT.INDICATION */
+    int            ss_sd;              /* SESSION descriptor */
+
+    struct SSAPref  ss_connect;        /* session connection identifier */
+    
+    struct SSAPaddr ss_calling;        /* address of peer calling */
+    struct SSAPaddr ss_called; /* address of peer called */
+
+    int            ss_requirements;    /* session requirements */
+    int            ss_settings;        /* initial settings of tokens */
+    long    ss_isn;            /* initial serial number */
+
+    int            ss_ssdusize;        /* largest atomic SSDU */
+
+    struct QOStype ss_qos;     /* quality of service */
+
+                               /* initial DATA from peer */
+#define        SS_SIZE         512
+    int            ss_cc;              /*   length */
+    char   *ss_data;           /*   data */
+};
+#define        SSFREE(ss) \
+{ \
+    if ((ss) -> ss_data) \
+       free ((ss) -> ss_data), (ss) -> ss_data = NULL; \
+}
+
+    
+struct SSAPconnect {           /* S-CONNECT.CONFIRMATION */
+    int            sc_sd;              /* SESSION descriptor */
+
+    struct SSAPref  sc_connect;        /* session connection identifier */
+    
+    struct SSAPaddr sc_responding;/* address of peer responding */
+
+    int            sc_result;          /* result */
+#define        SC_ACCEPT       (-1)
+
+#define        SC_BASE         0x80            /* reject by SSAP-provider */
+#define        SC_SSAPID       (SC_BASE + 1)   /* SSAP identifier unknown */
+#define        SC_SSUSER       (SC_BASE + 2)   /* SS-user not attached to SSAP */
+#define        SC_CONGEST      (SC_BASE + 3)   /* Congestion at SSAP */
+#define        SC_VERSION      (SC_BASE + 4)   /* Proposed protocol versions not
+                                          supported */
+
+                                       /* begin UNOFFICIAL */
+#define        SC_ADDRESS      (SC_BASE + 5)   /* Address unknown */
+#define        SC_REFUSED      (SC_BASE + 6)   /* Connect request refused on this
+                                          network connection */
+#define        SC_TRANSPORT    (SC_BASE + 7)   /* Transport disconnect */
+#define        SC_ABORT        (SC_BASE + 8)   /* Provider-initiated abort */
+#define        SC_PROTOCOL     (SC_BASE + 9)   /* Protocol error */
+#define        SC_PARAMETER    (SC_BASE + 10)  /* Invalid parameter */
+#define        SC_OPERATION    (SC_BASE + 11)  /* Invalid operation */
+#define        SC_TIMER        (SC_BASE + 12)  /* Timer expired */
+#define        SC_WAITING      (SC_BASE + 13)  /* Indications waiting */
+                                       /* end UNOFFICIAL */
+
+                                       /* reject by SSAP-user */
+#define        SC_NOTSPECIFIED 0               /* Reason not specified */
+#define        SC_CONGESTION   1               /* Temporary congestion */
+#define        SC_REJECTED     2               /* Rejected */
+
+#ifdef notdef
+#define        SC_FATAL(r)     ((r) < SC_BASE || (r) < SC_PARAMETER)
+#define        SC_OFFICIAL(r)  ((r) < SC_BASE || (r) < SC_ADDRESS)
+#else
+#define        SC_FATAL(r)     ((r) < SC_PARAMETER)
+#define        SC_OFFICIAL(r)  ((r) < SC_ADDRESS)
+#endif
+
+    int            sc_requirements;    /* session requirements */
+    int            sc_settings;        /* initial assignment of tokens */
+    int            sc_please;          /* tokens requested by SS-user
+                                  (S-TOKEN-PLEASE.INDICATION) */
+    long    sc_isn;            /* initial serial number */
+
+    int            sc_ssdusize;        /* largest atomic SSDU */
+
+    struct QOStype sc_qos;     /* quality of service */
+
+                               /* initial DATA from peer */
+#ifdef HPUX
+#undef SC_SIZE
+#endif
+#define        SC_SIZE         512
+    int            sc_cc;              /*   length */
+    char   *sc_data;           /*   data */
+    char   *sc_realdata;       /*   real head of data */
+};
+#define        SCFREE(sc) \
+{ \
+    if ((sc) -> sc_realdata) \
+       free ((sc) -> sc_realdata), \
+           (sc) -> sc_realdata = (sc) -> sc_data = NULL; \
+    else \
+       if ((sc) -> sc_data) \
+           free ((sc) -> sc_data), (sc) -> sc_data = NULL; \
+}
+
+
+                                       /* SESSION requirements */
+#define        SR_HALFDUPLEX   0x0001  /* half-duplex */
+#define        SR_DUPLEX       0x0002  /* full-duplex */
+#define        SR_EXPEDITED    0x0004  /* expedited data transfer */
+#define        SR_MINORSYNC    0x0008  /* minor synchronize */
+#define        SR_MAJORSYNC    0x0010  /* major synchronize */
+#define        SR_RESYNC       0x0020  /* resynchronize */
+#define        SR_ACTIVITY     0x0040  /* activity management */
+#define        SR_NEGOTIATED   0x0080  /* negotiated release */
+#define        SR_CAPABILITY   0x0100  /* capability data transfer */
+#define        SR_EXCEPTIONS   0x0200  /* exceptions reporting */
+#define        SR_TYPEDATA     0x0400  /* typed data transfer */
+#define        SR_SYMMETRIC    0x0800  /* symmetric synchronize */
+
+#define        SR_RLS_EXISTS   SR_NEGOTIATED
+#define        SR_MAJ_EXISTS   (SR_MAJORSYNC | SR_ACTIVITY)
+#define        SR_ACT_EXISTS   SR_ACTIVITY
+#define        SR_MIN_EXISTS   SR_MINORSYNC
+#define        SR_DAT_EXISTS   SR_HALFDUPLEX
+
+#define        SR_TOKENS       (SR_RLS_EXISTS | SR_MAJ_EXISTS | SR_ACT_EXISTS \
+                           | SR_MIN_EXISTS | SR_DAT_EXISTS)
+
+#define        SR_BASUBSET     (SR_HALFDUPLEX | SR_TYPEDATA | SR_CAPABILITY \
+                           | SR_MINORSYNC | SR_EXCEPTIONS | SR_ACTIVITY)
+#define        SR_BCSUBSET     (SR_HALFDUPLEX | SR_DUPLEX)
+#define        SR_BSSUBSET     (SR_NEGOTIATED | SR_HALFDUPLEX | SR_DUPLEX \
+                           | SR_TYPEDATA | SR_MINORSYNC | SR_MAJORSYNC \
+                           | SR_RESYNC)
+#define        SR_MYREQUIRE    (SR_BASUBSET | SR_BCSUBSET | SR_BSSUBSET \
+                           | SR_EXPEDITED)
+#define        SR_DEFAULT      (SR_HALFDUPLEX | SR_MINORSYNC | SR_ACTIVITY \
+                           | SR_CAPABILITY | SR_EXCEPTIONS)
+
+                                       /* SESSION tokens */
+#define        ST_INIT_VALUE   0x00    /* initiator's side */
+#define        ST_RESP_VALUE   0x01    /* responder's side */
+#define        ST_CALL_VALUE   0x02    /* called SS-user's choice */
+#define        ST_RSVD_VALUE   0x03    /* reserved */
+
+#define        ST_MASK         0x03
+
+#define        ST_RLS_SHIFT    6       /* release token */
+#define        ST_MAJ_SHIFT    4       /* major/activity token */
+#define        ST_ACT_SHIFT    ST_MAJ_SHIFT
+#define        ST_MIN_SHIFT    2       /* synchronize-minor token */
+#define        ST_DAT_SHIFT    0       /* data token */
+
+#define        dotokens() \
+{ \
+    dotoken (SR_RLS_EXISTS, ST_RLS_SHIFT, ST_RLS_TOKEN, "release"); \
+    dotoken (SR_MAJ_EXISTS, ST_MAJ_SHIFT, ST_MAJ_TOKEN, "majorsync"); \
+    dotoken (SR_MIN_EXISTS, ST_MIN_SHIFT, ST_MIN_TOKEN, "minorsync"); \
+    dotoken (SR_DAT_EXISTS, ST_DAT_SHIFT, ST_DAT_TOKEN, "data"); \
+}
+
+
+struct SSAPdata {              /* S-READ.INDICATION */
+    int            sx_type;            /* type of indication */
+#define        SX_NORMAL       0x00    /* S-DATA.INDICATION */
+#define        SX_EXPEDITED    0x01    /* S-EXPEDITED-DATA.INDICATION */
+#define        SX_TYPED        0x02    /* S-TYPED-DATA.INDICATION */
+#define        SX_CAPDIND      0x03    /* S-CAPABILITY-DATA.INDICATION */
+#define        SX_CAPDCNF      0x04    /* S-CAPABILITY-DATA.CONFIRMATION */
+
+#define        SX_EXSIZE       14      /* EXPEDITED DATA (XSSDU) only */
+#define        SX_CDSIZE       512     /* CAPABILITY DATA only */
+#define        SX_CDASIZE      512     /* CAPABILITY DATA ACK only */
+    int            sx_cc;              /*   total length */
+    struct qbuf sx_qbuf;       /*   chained data */
+};
+#define        SXFREE(sx)      QBFREE (&((sx) -> sx_qbuf))
+
+
+struct SSAPtoken {             /* S-{TOKEN-*,GIVE-CONTROL}.INDICATION */
+    int            st_type;            /* type of indication */
+#define        ST_GIVE         0x00    /* S-TOKEN-GIVE.INDICATION */
+#define        ST_PLEASE       0x01    /* S-TOKEN-PLEASE.INDICATION */
+#define        ST_CONTROL      0x02    /* S-GIVE-CONTROL.INDICATION */
+
+    u_char  st_tokens;         /* tokens offered/wanted */
+#define        ST_RLS_TOKEN    (0x01 << ST_RLS_SHIFT)
+#define        ST_MAJ_TOKEN    (0x01 << ST_MAJ_SHIFT)
+#define        ST_ACT_TOKEN    (0x01 << ST_ACT_SHIFT)
+#define        ST_MIN_TOKEN    (0x01 << ST_MIN_SHIFT)
+#define        ST_DAT_TOKEN    (0x01 << ST_DAT_SHIFT)
+
+    u_char  st_owned;          /* tokens owned by user */
+
+#define        ST_SIZE         512     /* PLEASE TOKEN only */
+    int            st_cc;              /*   length */
+    char   *st_data;           /*   data */
+};
+#define        STFREE(st) \
+{ \
+    if ((st) -> st_data) \
+       free ((st) -> st_data), (st) -> st_data = NULL; \
+}
+
+
+struct SSAPsync {              /* S-*-SYNC.{INDICATION,CONFIRMATION} */
+    int            sn_type;            /* type of indication/confirmation */
+#define        SN_MAJORIND     0x00    /* S-MAJOR-SYNC.INDICATION */
+#define        SN_MAJORCNF     0x01    /* S-MAJOR-SYNC.CONFIRMATION */
+#define        SN_MINORIND     0x02    /* S-MINOR-SYNC.INDICATION */
+#define        SN_MINORCNF     0x03    /* S-MINOR-SYNC.CONFIRMATION */
+#define        SN_RESETIND     0x04    /* S-RESYNCHRONIZE.INDICATION */
+#define        SN_RESETCNF     0x05    /* S-RESYNCHRONIZE.CONFIRMATION */
+
+    int            sn_options;         /* options (!!) */
+                               /* for S-MINOR-SYNC.INDICATION */
+#define        SYNC_CONFIRM    1       /* wants confirmation */
+#define        SYNC_NOCONFIRM  0       /*   .. nope */
+                               /* for S-RESYNCHRONIZE.INDICATION */
+#define        SYNC_RESTART    0       /* restart */
+#define        SYNC_ABANDON    1       /* abandon */
+#define        SYNC_SET        2       /* set */
+
+    long    sn_ssn;            /* serial number */
+#define        SERIAL_NONE     (-1L)   /* No SSN */
+#define        SERIAL_MIN      000000L /* the min SSN */
+#define        SERIAL_MAX      999998L /* the max SSN */
+
+    int            sn_settings;        /* new token settings (RESYNC only) */
+
+                               /* sync data from peer */
+#define        SN_SIZE         512
+    int            sn_cc;              /*   length */
+    char   *sn_data;           /*   data */
+};
+#define        SNFREE(sn) \
+{ \
+    if ((sn) -> sn_data) \
+       free ((sn) -> sn_data), (sn) -> sn_data = NULL; \
+}
+
+
+struct SSAPactivity {          /* S-ACTIVITY-*.{INDICATION,CONFIRMATION} */
+    int            sv_type;            /* type of indication/confirmation */
+#define        SV_START        0x00    /* S-ACTIVITY-START.INDICATION */
+#define        SV_RESUME       0x01    /* S-ACTIVITY-RESUME.INDICATION */
+#define        SV_INTRIND      0x02    /* S-ACTIVITY-INTERRUPT.INDICATION */
+#define        SV_INTRCNF      0x03    /* S-ACTIVITY-INTERRUPT.CONFIRMATION */
+#define        SV_DISCIND      0x04    /* S-ACTIVITY-DISCARD.INDICATION */
+#define        SV_DISCCNF      0x05    /* S-ACTIVITY-DISCARD.CONFIRMATION */
+#define        SV_ENDIND       0x06    /* S-ACTIVITY-END.INDICATION */
+#define        SV_ENDCNF       0x07    /* S-ACTIVITY-END.CONFIRMATION */
+
+    struct SSAPactid sv_id;    /* START/RESUME activity identifier */
+
+    struct SSAPactid sv_oid;   /* RESUME old activity identifier */
+    struct SSAPref   sv_connect;/*       old connection identifier */
+
+    long    sv_ssn;            /* RESUME/END Serial number */
+
+    int            sv_reason;          /* INTERRUPT/DISCARD */
+                               /* same values as sp_reason */
+        
+                               /* activity DATA from peer */
+#define        SV_SIZE         512
+    int            sv_cc;              /*   length */
+    char   *sv_data;           /*   data */
+};
+#define        SVFREE(sv) \
+{ \
+    if ((sv) -> sv_data) \
+       free ((sv) -> sv_data), (sv) -> sv_data = NULL; \
+}
+
+
+struct SSAPreport {            /* S-{U,P}-EXCEPTION-REPORT.INDICATION */
+    int            sp_peer;            /* T   = S-U-EXCEPTION-REPORT.INDICATION:
+                                       sp_reason/sp_data both meaningful
+                                  NIL = S-P-EXCEPTION-REPORT.INDICATION:
+                                       sp_reason == SP_NOREASON, or
+                                       sp_reason == SP_PROTOCOL */
+    int            sp_reason;
+#define        SP_NOREASON     0       /* No specific reason stated */
+#define        SP_JEOPARDY     1       /* User receiving ability jeopardized */
+#define        SP_RSVD1        2       /* reserved */
+#define        SP_SEQUENCE     3       /* User sequence error */
+#define        SP_RSVD2        4       /* reserved */
+#define        SP_LOCAL        5       /* Local SS-user error */
+#define        SP_PROCEDURAL   6       /* Unrecoverable procedural error */
+#define        SP_DEMAND       128     /* Demand data token */
+
+#define        SP_PROTOCOL     (-1)    /* SS-provider protocol error */
+
+                               /* report DATA from peer */
+#define        SP_SIZE         512
+    int            sp_cc;              /*   length */
+    char   *sp_data;           /*   data */
+};
+#define        SPFREE(sp) \
+{ \
+    if ((sp) -> sp_data) \
+       free ((sp) -> sp_data), (sp) -> sp_data = NULL; \
+}
+
+
+struct SSAPfinish {            /* S-RELEASE.INDICATION */
+                               /* release DATA from peer */
+#define        SF_SIZE         512
+    int            sf_cc;              /*   length */
+    char   *sf_data;           /*   data */
+};
+#define        SFFREE(sf) \
+{ \
+    if ((sf) -> sf_data) \
+       free ((sf) -> sf_data), (sf) -> sf_data = NULL; \
+}
+
+
+struct SSAPrelease {           /* S-RELEASE.CONFIRMATION */
+    int            sr_affirmative;     /* T   = connection released
+                                  NIL = request refused */
+
+                               /* release DATA from peer */
+#define        SR_SIZE         512
+    int            sr_cc;              /*   length */
+    char   *sr_data;           /*   data */
+};
+#define        SRFREE(sr) \
+{ \
+    if ((sr) -> sr_data) \
+       free ((sr) -> sr_data), (sr) -> sr_data = NULL; \
+}
+
+
+struct SSAPabort {             /* S-{U,P}-ABORT.INDICATION */
+    int            sa_peer;            /* T   = S-U-ABORT.INDICATION:
+                                            sa_info/sa_cc is meaningful
+                                  NIL = S-P-ABORT.INDICATION:
+                                            sa_reason is meaningful,
+                                            sa_data/sa_cc contains diagnostics */
+
+    int            sa_reason;          /* same codes as sc_result */
+
+                               /* abort DATA from peer */
+#define        SA_SIZE         512     /* N.B.: the ISO DIS says 9, but we use
+                                  512 instead so ASE-level aborts will work
+                                  reasonably */
+    int            sa_cc;              /*   length */
+    char   *sa_info;           /*   data (from the peer) */
+    char   *sa_realinfo;       /*   real head of data */
+    char    sa_data[512];      /*   data (for messages from provider) */
+};
+#define        SAFREE(sa) \
+{ \
+    if ((sa) -> sa_realinfo) \
+       free ((sa) -> sa_realinfo), (sa) -> sa_realinfo = NULL; \
+}
+
+
+struct SSAPindication {
+    int            si_type;            /* the union element present */
+#define        SI_DATA         0x00
+#define        SI_TOKEN        0x01
+#define        SI_SYNC         0x02
+#define        SI_ACTIVITY     0x03
+#define        SI_REPORT       0x04
+#define        SI_FINISH       0x05
+#define        SI_ABORT        0x06
+
+    union {
+       struct SSAPdata si_un_data;
+       struct SSAPtoken si_un_token;
+       struct SSAPsync si_un_sync;
+       struct SSAPactivity si_un_activity;
+       struct SSAPreport si_un_report;
+       struct SSAPfinish si_un_finish;
+       struct SSAPabort si_un_abort;
+    }  si_un;
+#define        si_data         si_un.si_un_data
+#define        si_token        si_un.si_un_token
+#define        si_sync         si_un.si_un_sync
+#define        si_activity     si_un.si_un_activity
+#define        si_report       si_un.si_un_report
+#define        si_finish       si_un.si_un_finish
+#define        si_abort        si_un.si_un_abort
+};
+
+/* \f */
+
+extern char *ssapversion;
+
+
+int    SExec ();               /* SERVER only */
+int    SInit ();               /* S-CONNECT.INDICATION */
+
+int    SConnResponse ();       /* S-CONNECT.RESPONSE */
+int    SConnRequest ();        /* S-CONNECT.REQUEST (backwards-compatible) */
+#define        SConnRequest(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) \
+       SAsynConnRequest (a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,0)
+int    SAsynConnRequest ();    /* S-(ASYN-)CONNECT.REQUEST */
+int    SAsynRetryRequest ();   /* S-ASYN-RETRY.REQUEST (pseudo) */
+int    SDataRequest ();        /* S-DATA.REQUEST */
+int    SSendRequest ();        /* S-SEND.REQUEST (segmented) */
+int    SWriteRequest ();       /* S-WRITE.REQUEST (pseudo) */
+int    SExpdRequest ();        /* S-EXPEDITED-DATA.REQUEST */
+int    STypedRequest ();       /* S-TYPED-DATA.REQUEST */
+int    SCapdRequest ();        /* S-CAPABILITY-DATA.REQUEST */
+int    SCapdResponse ();       /* S-CAPABILITY-DATA.RESPONSE */
+int    SReadRequest ();        /* S-READ.REQUEST (pseudo) */
+int    SGTokenRequest ();      /* S-TOKEN-GIVE.REQUEST */
+int    SPTokenRequest ();      /* S-TOKEN-PLEASE.REQUEST */
+int    SGControlRequest ();    /* S-CONTROL-GIVE.REQUEST */
+int    SMajSyncRequest ();     /* S-MAJOR-SYNC.REQUEST */
+int    SMajSyncResponse ();    /* S-MAJOR-SYNC.RESPONSE */
+int    SMinSyncRequest ();     /* S-MINOR-SYNC.REQUEST */
+int    SMinSyncResponse ();    /* S-MINOR-SYNC.RESPONSE */
+int    SReSyncRequest ();      /* S-RESYNCHRONIZE.REQUEST */
+int    SReSyncResponse ();     /* S-RESYNCHRONIZE.RESPONSE */
+int    SActStartRequest ();    /* S-ACTIVITY-START.REQUEST */
+int    SActResumeRequest ();   /* S-ACTIVITY-RESUME.REQUEST */
+int    SActIntrRequest ();     /* S-ACTIVITY-INTERRUPT.REQUEST */
+int    SActIntrResponse ();    /* S-ACTIVITY-INTERRUPT.RESPONSE */
+int    SActDiscRequest ();     /* S-ACTIVITY-DISCARD.REQUEST */
+int    SActDiscResponse ();    /* S-ACTIVITY-DISCARD.RESPONSE */
+int    SActEndRequest ();      /* S-ACTIVITY-END.REQUEST */
+int    SActEndResponse ();     /* S-ACTIVITY-END.RESPONSE */
+int    SUAbortRequest ();      /* S-U-ABORT.REQUEST */
+int    SUReportRequest ();     /* S-U-EXCEPTION-REPORT.REQUEST */
+int    SRelRequest ();         /* S-RELEASE.REQUEST */
+int    SRelRetryRequest ();    /* S-RELEASE-RETRY.REQUEST (pseudo) */
+int    SRelResponse ();        /* S-RELEASE.RESPONSE */
+
+int    SSetIndications ();     /* define vectors for INDICATION events */
+int    SSelectMask ();         /* map session descriptors for select() */
+
+char   *SErrString ();         /* return SSAP error code in string form */
+
+#define        SLocalHostName  getlocalhost
+char   *SLocalHostName ();     /* return name of local host (sigh) */
+#endif
diff --git a/src/isode/h/sys.dirent.h b/src/isode/h/sys.dirent.h
new file mode 100644 (file)
index 0000000..b29694a
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+       <sys/dirent.h> -- file system independent directory entry (SVR3)
+
+       last edit:      25-Apr-1987     D A Gwyn
+
+       prerequisite:   <sys/types.h>
+*/
+
+
+/* The following nonportable ugliness could have been avoided by defining
+   DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments. */
+#define        DIRENTBASESIZ           (((struct dirent *)0)->d_name \
+                               - (char *)&((struct dirent *)0)->d_ino)
+#define        DIRENTSIZ( namlen )     ((DIRENTBASESIZ + sizeof(long) + (namlen)) \
+                               / sizeof(long) * sizeof(long))
+
+/* DAG -- the following was moved from <dirent.h>, which was the wrong place */
+#define        MAXNAMLEN       512             /* maximum filename length */
+
+#ifndef NAME_MAX
+#define        NAME_MAX        (MAXNAMLEN - 1) /* DAG -- added for POSIX */
+#endif
+
+
+#ifdef dirent
+#undef dirent
+#else
+#ifdef AUX
+#define dirent _dirent
+#endif
+#endif
+
+struct dirent                          /* data from getdents()/readdir() */
+       {
+#ifdef apollo
+       long    d_ino;                  /* inode number of entry */
+       unsigned short  d_reclen;       /* length of this record */
+       unsigned short  d_namlen;       /* length of string in d_name */
+       off_t   d_off;                  /* offset of disk directory entry */
+       char    d_name[MAXNAMLEN + 1];  /* name must be no longer than this */
+#else
+       long            d_ino;          /* inode number of entry */
+       off_t           d_off;          /* offset of disk directory entry */
+       unsigned short  d_reclen;       /* length of this record */
+       char            d_name[1];      /* name of file */      /* non-POSIX */
+#endif
+       };
+
+#ifdef XOS_2                           
+#define        S_ISDIR( mode )         (((mode) & S_IFMT) == S_IFDIR)
+#endif
diff --git a/src/isode/h/sys.file.h b/src/isode/h/sys.file.h
new file mode 100644 (file)
index 0000000..465e1fa
--- /dev/null
@@ -0,0 +1,58 @@
+/* sys.file.h - system independent sys/file.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:00  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:25  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:39  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:57  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+#ifndef _ISODE_SYS_FILE_H
+#define _ISODE_SYS_FILE_H
+
+#include "general.h"
+
+/* Beware the ordering is important to avoid symbol clashes */
+
+#ifndef SVR4_UCB
+#include <sys/ioctl.h>
+#endif
+
+#ifdef  BSD42
+#include <sys/file.h>
+#else    
+#ifdef  SYS5
+#include <fcntl.h>
+#else
+#include <sys/fcntl.h>
+#endif
+#endif
+
+#ifdef SYS5
+#include <termio.h>
+#endif
+
+#endif 
diff --git a/src/isode/h/tailor.h b/src/isode/h/tailor.h
new file mode 100644 (file)
index 0000000..c5f91a4
--- /dev/null
@@ -0,0 +1,177 @@
+/* tailor.h - ISODE tailoring */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:03  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:27  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:41  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:57  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _TAILOR_
+#define        _TAILOR_
+
+#ifndef        _LOGGER_
+#include "logger.h"
+#endif
+
+
+/* SYSTEM AREAS */
+
+extern char    *isodename;
+extern char    *isodebinpath;
+extern char    *isodesbinpath;
+extern char    *isodetcpath;
+extern char    *isodelogpath;
+
+
+/* LOGGING */
+
+extern LLog *compat_log, _compat_log;
+extern LLog *addr_log, _addr_log;
+extern LLog *tsap_log, _tsap_log;
+extern LLog *ssap_log, _ssap_log;
+extern LLog *psap_log, _psap_log;
+extern LLog *psap2_log, _psap2_log;
+extern LLog *acsap_log, _acsap_log;
+extern LLog *rtsap_log, _rtsap_log;
+extern LLog *rosap_log, _rosap_log;
+
+
+/* TRANSPORT-SWITCH */
+
+extern int     ts_stacks;
+#define        TS_NONE 0x00
+#define        TS_TCP  0x01
+#define        TS_X25  0x02
+#define        TS_BRG  0x04
+#define        TS_TP4  0x08
+#define TS_X2584 0x10
+#define        TS_ALL  0xff
+
+struct ts_interim {
+    char   *ts_name;           /* community name, also MACRO name */
+    char   *ts_value;          /*   .. MACRO value */
+
+    int            ts_subnet;          /* internal key */
+    int            ts_syntax;          /* same values as na_stack */
+
+    char    ts_prefix[20];     /* NSAP prefix */
+    int            ts_length;          /*   .. and length */
+};
+extern struct ts_interim ts_interim[];
+
+extern int     ts_communities[];
+extern int     ts_comm_nsap_default;
+extern int     ts_comm_x25_default;
+extern int     ts_comm_tcp_default;
+
+extern char *tsb_addresses[];
+extern int tsb_communities[];
+
+extern char *tsb_default_address;
+
+
+
+/* X.25 */
+
+#ifdef X25
+extern char    *x25_local_dte;
+extern char    *x25_local_pid;
+
+extern char     x25_intl_zero;
+extern char     x25_strip_dnic;
+extern char    *x25_dnic_prefix;
+
+extern u_char   reverse_charge;
+extern u_short  recvpktsize;
+extern u_short  sendpktsize;
+extern u_char   recvwndsize;
+extern u_char   sendwndsize;
+extern u_char   recvthruput;
+extern u_char   sendthruput;
+extern u_char   cug_req;
+extern u_char   cug_index;
+extern u_char   fast_select_type;
+extern u_char   rpoa_req;
+extern u_short  rpoa;
+
+extern LLog *x25_log, _x25_log;
+
+#ifdef CAMTEC_CCL
+extern char     x25_outgoing_port;
+#endif
+
+#ifdef ULTRIX_X25
+extern char     *x25_default_template;
+extern char     *x25_default_filter;
+extern char     *x25_default_class;
+#endif
+#endif
+
+
+/* BRIDGE X.25 */
+
+#ifdef BRIDGE_X25
+extern char    *x25_bridge_host;
+extern char    *x25_bridge_addr;
+extern char    *x25_bridge_listen;
+extern char    *x25_bridge_pid;
+extern char    *x25_bridge_discrim;
+#endif
+
+#if    defined (BRIDGE_X25) || defined (X25)
+extern u_short  x25_bridge_port;
+#endif
+
+
+/* SESSION */
+
+extern int     ses_ab_timer;
+extern int     ses_dn_timer;
+extern int     ses_rf_timer;
+
+
+/* USER-FRIENDLY NAMESERVICE */
+
+extern char    ns_enabled;
+extern char    *ns_address;
+
+
+/* ROUTINES */
+
+void   isodetailor ();
+int    isodesetvar ();
+void   isodexport ();
+
+#define        isodefile(file,ispgm) \
+       _isodefile ((ispgm) ? isodesbinpath : isodetcpath, (file))
+
+char   *_isodefile ();
+
+char   *getlocalhost ();
+
+#endif
diff --git a/src/isode/h/tp4.h b/src/isode/h/tp4.h
new file mode 100644 (file)
index 0000000..7a19ce0
--- /dev/null
@@ -0,0 +1,157 @@
+/* tp4.h - TP4 abstractions */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:05  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:29  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:43  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _TP4_
+#define        _TP4_
+
+/* \f */
+
+#ifdef BSD_TP4
+#ifndef        SOCK_STREAM
+#include <sys/socket.h>
+#endif
+#include <netiso/iso.h>
+#include <netiso/iso_errno.h>
+#include <netiso/tp_user.h>
+
+union sockaddr_osi {
+    struct sockaddr_iso    osi_sockaddr;
+    char osi_bigaddr[104];
+};
+
+union osi_control_msg {
+    struct {
+       struct cmsghdr ocm_cmhdr;
+       char    ocm_cmdata[128 - sizeof (struct cmsghdr)];
+    }    ocm_control;
+
+    char ocm_data[128];
+};
+
+int    gen2tp4 (), tp42gen ();
+
+
+#define        CLTS                    /* have CL-mode transport service */
+
+#ifndef        _DGRAM_
+#include "dgram.h"
+#endif
+
+int    start_clts_server ();
+#define        start_clts_client       start_clts_server
+
+#define        join_clts_server(fd,sock) \
+               join_dgram_aux ((fd), (struct sockaddr *) (sock), 0)
+#define        join_clts_client(fd,sock) \
+               join_dgram_aux ((fd), (struct sockaddr *) (sock), 1)
+
+#define        read_clts_socket        read_dgram_socket
+#define        write_clts_socket       write_dgram_socket
+#define        close_clts_socket       close_dgram_socket
+
+#define        select_clts_socket      select_dgram_socket
+#define        check_clts_socket       check_dgram_socket
+#endif
+
+/* \f   SunLink OSI */
+
+#ifdef SUN_TP4
+#if    defined(SUNLINK_6_0) && !defined(SUNLINK_5_2)
+#define        SUNLINK_5_2
+#endif
+
+#ifndef        SUNLINK_6_0
+#include <sys/ieee802.h>
+#else
+#include <net/if_ieee802.h>
+#endif
+#ifndef        SOCK_STREAM
+#include <sys/socket.h>
+#endif
+#include <netosi/osi.h>
+#ifdef SUNLINK_5_2
+#include <netosi/osi_profile.h>
+#endif
+#include <netosi/osi_addr.h>
+#include <netosi/osi_error.h>
+#include <netosi/tp_event.h>
+
+
+#define        MSG_OOB         0x1     /* process out-of-band data */
+
+
+struct tp4pkt {
+    union {
+       TP_MSG            tp_msg;
+       TP_MSG_CONNECT    tp_connect;
+       TP_MSG_DATA       tp_data;
+       TP_MSG_X_DATA     tp_x_data;
+       TP_MSG_DISCONNECT tp_disconnect;
+    } tp_un;
+#define tp4_event      tp_un.tp_msg.tp_event
+#define tp4_called     tp_un.tp_connect.dst_address
+#define tp4_calling    tp_un.tp_connect.src_address
+#define tp4_expedited  tp_un.tp_connect.expedited_selected
+#define tp4_qos                tp_un.tp_connect.tp_qos
+#define tp4_eot                tp_un.tp_data.eot
+#define tp4_reason     tp_un.tp_disconnect.reason
+};
+
+struct tp4pkt *newtp4pkt ();
+#define        freetp4pkt(tp)  cfree ((char *) (tp))
+
+int    gen2tp4 (), tp42gen ();
+#endif
+
+#ifdef TLI_TP
+#include <tiuser.h>
+#define select_tp4_socket selsocket
+#endif
+
+/* \f */
+
+#ifdef BSD_TP4
+#define        close_tp4_socket        close
+#define        select_tp4_socket       selsocket
+#endif
+
+#ifdef SUN_TP4
+#define        close_tp4_socket        close
+#define        select_tp4_socket       selsocket
+#endif
+
+int    close_tp4_socket ();
+int    select_tp4_socket ();
+
+#endif
+
diff --git a/src/isode/h/tpkt.h b/src/isode/h/tpkt.h
new file mode 100644 (file)
index 0000000..f905abc
--- /dev/null
@@ -0,0 +1,499 @@
+/* tpkt.h - include file for transport providers (TS-PROVIDER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:07  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:30  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:45  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "tsap.h"              /* definitions for TS-USERs */
+
+/* \f */
+
+
+#define        tsapPsig(tb, sd) \
+{ \
+    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 not connected"); \
+    } \
+}
+
+#ifdef __STDC__
+#define missingP(p) \
+{ \
+    if (p == NULL) \
+        return tsaplose (td, DR_PARAMETER, NULLCP, \
+                            "mandatory parameter \"%s\" missing", #p); \
+}
+#else
+#define        missingP(p) \
+{ \
+    if (p == NULL) \
+       return tsaplose (td, DR_PARAMETER, NULLCP, \
+                           "mandatory parameter \"%s\" missing", "p"); \
+}
+#endif
+
+#define        toomuchP(b,n,m,p) \
+{ \
+    if (b == NULL) \
+       n = 0; \
+    else \
+       if (n > m) \
+           return tsaplose (td, DR_PARAMETER, NULLCP, \
+                           "too much %s user data, %d octets", p, n); \
+}
+
+#define        copyTPKTdata(t,base,len) \
+{ \
+    register struct udvec *uv = t -> t_udvec; \
+    if (len > 0) \
+       uv -> uv_base = base, uv -> uv_len = len, uv++; \
+    uv -> uv_base = NULL; \
+}
+
+#ifndef        lint
+#ifndef        __STDC__
+#define        copyTSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d/* */_cc = min (i, sizeof d -> d/* */_data)) > 0) \
+       bcopy (base, d -> d/* */_data, d -> d/* */_cc); \
+}
+#else
+#define        copyTSAPdata(base,len,d) \
+{ \
+    register int i = len; \
+    if ((d -> d##_cc = min (i, sizeof d -> d##_data)) > 0) \
+       bcopy (base, d -> d##_data, d -> d##_cc); \
+}
+#endif
+#else
+#define        copyTSAPdata(base,len,d)        bcopy (base, (char *) d, len)
+#endif
+
+
+int    tpktlose (), tsaplose ();
+
+/* \f */
+
+struct tsapADDR {
+    struct NSAPaddr ta_addr;
+    int            ta_present;
+
+    int            ta_selectlen;
+    
+    union un_ta_type un_ta;
+};
+
+                               /* network type codes:
+                                       must be outside [0-9A-Fa-f] */
+#define        NT_TCP  'T'             /* TCP */
+#define        NT_X25  'X'             /* X.25 */
+#define        NT_BRG  'G'             /* Bridge */
+#define        NT_BSD  'Z'             /* 4.4BSD */
+#define        NT_SUN  'S'             /* SunLink OSI */
+#define NT_TLI 't'             /* TLI */
+#define NT_X2584 'N'           /* X25(84) NSAP */
+
+struct tsapblk {
+    struct tsapblk *tb_forw;   /* doubly-linked list */
+    struct tsapblk *tb_back;   /*   .. */
+
+    int     tb_fd;             /* file descriptor */
+
+    char    tb_flags;          /* our state */
+#define        TB_NULL         0x00
+#define        TB_CONN         0x01    /* connected */
+#define        TB_ASYN         0x02    /* asynchronous */
+#define        TB_EXPD         0x04    /* expedited transfer selected */
+#define        TB_TCP          0x08    /* underlying service is TCP */
+#define        TB_X25          0x10    /*   ..               is X.25 */
+#define TB_BRG         0x20    /*   ..               is Bridge */
+#define        TB_TP0          (TB_TCP | TB_X25 | TB_BRG)
+#define        TB_TP4          0x40    /*   ..               is TP4 */
+                               /* all TP4's use this value as it make
+                                  sense to have only one TP4 service
+                                  compiled in... */
+#define TB_STACKS      (TB_TP0|TB_TP4) /* all TS stacks */
+#define        TB_QWRITES      0x80    /* queued writes OK */
+
+    char   *tb_magic;          /* generic pointer */
+
+                               /* saved retry variables */
+    char  *tb_data;            /* saved user data */
+    int    tb_cc;              /* saved user data count */
+    char   tb_expedited;       /* saved expedited */
+    struct TSAPaddr *tb_called;        /* saved addresses */
+    struct TSAPaddr *tb_calling;/*   .. */
+
+    struct tsapkt *tb_retry;   /* initial tpkt */
+
+    u_short tb_srcref;         /* source reference */
+    u_short tb_dstref;         /* destination reference */
+
+    int            tb_tsdusize;        /* maximum TSDU size */
+    int            tb_tpduslop;        /*   .. */
+    int            tb_tpdusize;        /* for tp0ts */
+
+    int            tb_sent;            /* TPDU bytes sent */
+    int            tb_recv;            /* TPDU bytes recv */
+
+    struct QOStype tb_qos;     /* quality of service */
+
+    struct qbuf tb_qbuf;       /* for segmented TSDUs */
+    int            tb_len;             /*   .. */
+    
+    struct tsapADDR tb_initiating;/* initiator */
+    struct tsapADDR tb_responding;/* responder */
+
+    IFP            tb_retryfnx;        /* resume async connection */
+
+    IFP            tb_connPfnx;        /* TP connect */
+    IFP            tb_retryPfnx;       /* TP retry connect */
+    IFP            tb_startPfnx;       /* TP start accept */
+    IFP            tb_acceptPfnx;      /* TP accept */
+    IFP            tb_writePfnx;       /* TP write data */
+    IFP            tb_readPfnx;        /* TP read data */
+    IFP            tb_discPfnx;        /* TP disconnect */
+    IFP            tb_losePfnx;        /* TP loses */
+
+    IFP            tb_drainPfnx;       /* TP drain queued writes */
+    IFP            tb_queuePfnx;       /* TP note queued writes */
+    struct qbuf tb_qwrites;    /* queue of writes to retry */
+
+    IFP            tb_initfnx;         /* init for read from network */
+    IFP            tb_readfnx;         /* read from network */
+    IFP            tb_writefnx;        /* write to network */
+    IFP            tb_closefnx;        /* close network */
+    IFP            tb_selectfnx;       /* select network */
+    IFP            tb_checkfnx;        /* check network prior to select */
+    IFP            tb_nreadfnx;        /* estimate of octets waiting to be read */
+
+    IFP            tb_DataIndication;  /* INDICATION handlers */
+    IFP     tb_DiscIndication; /*   .. */
+
+#ifdef  MGMT
+    IFP     tb_manfnx;          /* for management reports */
+    int     tb_pdus;            /* PDUs sent */
+    int     tb_pdur;            /* PDUs recv */
+    int     tb_bytes;           /* bytes sent since last report */
+    int     tb_byter;           /* bytes recv        ..         */
+#endif
+};
+#define        NULLBP          ((struct tsapblk *) 0)
+
+
+int    freetblk ();
+struct tsapblk *newtblk (), *findtblk ();
+
+/* \f   TPKT datastructure */
+
+struct tsapkt {
+    int                t_errno;
+
+    struct {
+       u_char    pk_vrsn;
+#define        TPKT_VRSN       3
+
+       u_char    pk_rsrvd;
+
+       u_short   pk_length;
+#define        TPKT_MAXLEN     0xffff
+    }       t_pkthdr;
+#define        t_vrsn          t_pkthdr.pk_vrsn
+#define        t_rsrvd         t_pkthdr.pk_rsrvd
+#define        t_length        t_pkthdr.pk_length
+
+#define TPKT_HDRLEN(t) (sizeof ((t) -> t_pkthdr) + sizeof ((t) -> t_li) \
+                           + sizeof ((t) -> t_code))
+
+    struct {
+       u_char    tp_li;
+#ifndef        lint
+#ifndef        __STDC__
+#define        TPDU_MINLEN(t,c)        (c/* */_SIZE(t) + sizeof ((t) -> t_code))
+#else
+#define        TPDU_MINLEN(t,c)        (c##_SIZE(t) + sizeof ((t) -> t_code))
+#endif
+#else
+#define        TPDU_MINLEN(t,c)        (sizeof ((t) -> t_code))
+#endif
+#define        TPDU_MAXLEN(t)  \
+       (min (0xfe, (t) -> t_length - sizeof ((t) -> t_pkthdr) \
+                                   - sizeof ((t) -> t_li)))
+#define        TPDU_USRLEN(t)  \
+       ((t) -> t_length - sizeof ((t) -> t_pkthdr) \
+                        - sizeof ((t) -> t_li) - (t) -> t_li)
+
+       u_char    tp_code;
+#define        TPDU_CODE(t)    ((t) -> t_code & 0xf0)
+#define        TPDU_CR         0xe0    /* CONNECTION REQUEST */
+#define        TPDU_CC         0xd0    /* CONNECTION CONFIRMATION */
+#define        TPDU_DR         0x80    /* DISCONNECT REQUEST */
+#define        TPDU_DC         0xc0    /* DISCONNECT CONFIRMATION */
+#define        TPDU_DT         0xf0    /* DATA */
+#define        TPDU_ED         0x10    /* EXPEDITED DATA */
+#define        TPDU_AK         0x60    /* ACKNOWLEDGE */
+#define        TPDU_EA         0x20    /* EXPEDITED ACKNOWLEDGE */
+#define        TPDU_RJ         0x50    /* REJECT */
+#define        TPDU_ER         0x70    /* ERROR */
+
+       union {
+           struct {
+                               /* FIXED part */
+               u_short   un_cr_dstref;
+               u_short   un_cr_srcref;
+
+               u_char    un_cr_class;
+#define        CR_CLASS(t)     ((t) -> t_cr.cr_class & 0xf0)
+#define        CR_CLASS_TP0    0x00    /* class 0 */
+#define        CR_CLASS_TP1    0x10    /*   ..  1 */
+#define        CR_CLASS_TP2    0x20    /*   ..  2 */
+#define        CR_CLASS_TP3    0x30    /*   ..  3 */
+#define        CR_CLASS_TP4    0x40    /*   ..  4 */
+#define        CR_OPT_EXTD     0x02    /* extended formats in classes 2-4 */
+#define        CR_OPT_EXPL     0x01    /* explicit flow control in class 2 */
+
+                               /* VARIABLE part */
+               char      un_cr_called[TSSIZE];
+               int       un_cr_calledlen;
+               
+               char      un_cr_calling[TSSIZE];
+               int       un_cr_callinglen;
+
+               u_char    un_cr_tpdusize;
+
+               u_short   un_cr_options;
+
+               u_char    un_cr_alternate;
+           }       un_cr;
+#define        cr_dstref       un_cr_dstref
+#define        cr_srcref       un_cr_srcref
+#define        cr_class        un_cr_class
+#define        cr_tpdusize     un_cr_tpdusize
+#define        cr_options      un_cr_options
+#define        cr_alternate    un_cr_alternate
+#define        CR_SIZE(t)      5
+
+#define        un_cc           un_cr
+#define        cc_dstref       un_cr_dstref
+#define        cc_srcref       un_cr_srcref
+#define        cc_class        un_cr_class
+#define        cc_tpdusize     un_cr_tpdusize
+#define        cc_options      un_cr_options
+#define        CC_SIZE(t)      5
+
+           struct {
+                               /* FIXED part */
+               u_short   un_dr_dstref;
+               u_short   un_dr_srcref;
+               u_char    un_dr_reason;
+           }       un_dr;
+#define        dr_dstref       un_dr_dstref
+#define        dr_srcref       un_dr_srcref
+#define        dr_reason       un_dr_reason
+#define        DR_SIZE(t)      5
+
+           struct {
+                               /* FIXED part */
+               u_char   un_dt_nr;
+#define        DT_EOT          0x80
+           }       un_dt;
+#define        dt_nr           un_dt_nr
+#define        DT_SIZE(t)      1
+#define        DT_MAGIC        (2 + 1)
+
+/* Expedited service is not allowed in TP0, but for testing purposes,
+   we permit it when the underlying service is TCP.  Note we use a
+   non-standard packet format (identical to the DT format).
+ */
+#define        un_ed           un_dt
+#define        ed_nr           un_dt_nr
+#define        ED_SIZE(t)      1
+
+           struct {
+                               /* FIXED part */
+               u_short    un_er_dstref;
+               u_char     un_er_reject;
+#define        ER_REJ_NOTSPECIFIED     0x00    /* Reason not specified */
+#define        ER_REJ_CODE             0x01    /* Invalid parameter code */
+#define        ER_REJ_TPDU             0x02    /* Invalid TPDU type */
+#define        ER_REJ_VALUE            0x03    /* Invalid parameter value */
+           }       un_er;
+#define        er_dstref       un_er_dstref
+#define        er_reject       un_er_reject
+#define        ER_SIZE(t)      3
+       }       tp_un;
+#define        tp_cr           tp_un.un_cr
+#define        tp_cc           tp_un.un_cc
+#define        tp_dr           tp_un.un_dr
+#define        tp_dt           tp_un.un_dt
+#define        tp_ed           tp_un.un_ed
+#define        tp_er           tp_un.un_er
+
+       int             tp_vlen;
+       char           *tp_vbase;
+
+       struct qbuf    *tp_qbuf;        /* fd2tpkt ONLY */
+
+#define        NTPUV           12              /* really should be
+                                               MSG_MAXIOVLEN - 4 */
+       struct udvec tp_udvec[NTPUV];   /* tpkt2fd ONLY */
+    }               t_tpdu;
+#define        t_li            t_tpdu.tp_li
+#define        t_code          t_tpdu.tp_code
+#define        t_cr            t_tpdu.tp_un.un_cr
+#define        t_called        t_tpdu.tp_un.un_cr.un_cr_called
+#define        t_calledlen     t_tpdu.tp_un.un_cr.un_cr_calledlen
+#define        t_calling       t_tpdu.tp_un.un_cr.un_cr_calling
+#define        t_callinglen    t_tpdu.tp_un.un_cr.un_cr_callinglen
+#define        t_tpdusize      t_tpdu.tp_un.un_cr.un_cr_tpdusize
+#define        t_options       t_tpdu.tp_un.un_cr.un_cr_options
+#define        t_alternate     t_tpdu.tp_un.un_cr.un_cr_alternate
+#define        t_cc            t_tpdu.tp_un.un_cc
+#define        t_dr            t_tpdu.tp_un.un_dr
+#define        t_dt            t_tpdu.tp_un.un_dt
+#define        t_ed            t_tpdu.tp_un.un_ed
+#define        t_er            t_tpdu.tp_un.un_er
+
+#define        t_vdata         t_tpdu.tp_vbase
+#define        t_vlen          t_tpdu.tp_vlen
+
+#define        t_qbuf          t_tpdu.tp_qbuf
+
+#define        t_udvec         t_tpdu.tp_udvec
+};
+#define        NULLPKT         ((struct tsapkt *) 0)
+
+
+int    freetpkt ();
+struct tsapkt *newtpkt ();
+
+void   text2tpkt (), tpkt2text ();
+
+int    tpkt2fd ();
+struct tsapkt  *fd2tpkt ();
+
+char   *tpkt2str ();
+struct tsapkt  *str2tpkt ();
+
+/* \f   VARIABLE DATA codes, from ISO8073: */
+
+                                       /* for CR/CC TPDUs */
+#define        VDAT_TSAP_SRV   0xc2            /* TSAP ID of the calling TSAP */
+#define        VDAT_TSAP_CLI   0xc1            /* TSAP ID of the called TSAP */
+#define        VDAT_SIZE       0xc0            /* TPDU SIZE */
+#define          SIZE_8K       0x0d            /*   8192 */
+#define          SIZE_4K       0x0c            /*   4096 */
+#define          SIZE_2K       0x0b            /*   2048 */
+#define          SIZE_1K       0x0a            /*   1024 */
+#define          SIZE_512      0x09            /*    512 */
+#define          SIZE_256      0x08            /*    256 */
+#define          SIZE_128      0x07            /*    128 */
+#define          SIZE_DFLT     SIZE_128
+#define          SIZE_MAXTP0   SIZE_2K
+#define        VDAT_VRSN       0xc4            /* Version number */
+#define        VDAT_SECURITY   0xc5            /* Security parameters */
+#define        VDAT_CHECKSUM   0xc3            /* Checksum */
+#define        VDAT_OPTIONS    0xc6            /* Additional option selections */
+#define          OPT_NEXPEDITE 0x08            /*     Use network expedited */
+#define          OPT_CONFIRM   0x04            /*     Use receipt confirmation */
+#define          OPT_CHECKSUM  0x02            /*     Use 16-bit checksum */
+#define          OPT_TEXPEDITE 0x01            /*     Use transport expedited */
+#define        VDAT_ALTERNATE  0xc7            /* Alterated protocol class(es) */
+#define          ALT_TP0         0x01          /*     class 0 */
+#define          ALT_TP1         0x02          /*     class 1 */
+#define          ALT_TP2         0x04          /*     class 2 */
+#define          ALT_TP3         0x08          /*     class 3 */
+#define          ALT_TP4         0x10          /*     class 4 */
+#define        VDAT_ACKTIME    0x85            /* Acknowledge time */
+#define        VDAT_THROUGHPUT 0x89            /* Throughput */
+#define        VDAT_ERRORATE   0x86            /* Residual error rate */
+#define        VDAT_PRIORITY   0x87            /* Priority */
+#define        VDAT_DELAY      0x88            /* Transit delay */
+#define        VDAT_TTR        0x8b            /* Reassignment time */
+
+                                       /* for DR TPDUs */
+#define        VDAT_ADDITIONAL 0xe0            /* Additional information */
+
+                                       /* for AK TPDUs */
+#define        VDAT_SUBSEQ     0x8c            /* Sub-sequence number */
+#define        VDAT_FLOWCTL    0x8b            /* Flow control confirmation */
+
+                                       /* for ER TPDUs */
+#define        VDAT_INVALID    0xc1            /* invalid TPDU */
+
+/* \f */
+
+/* TP0 is the protocol */
+
+int    tp0init ();
+int    tp0write ();
+
+
+/* TCP is NS-provider */
+
+int    tcpopen ();
+
+char   *tcpsave ();
+int    tcprestore ();
+
+
+/* X.25 is NS-provider */
+
+int    x25open ();
+
+char   *x25save ();
+int    x25restore ();
+
+
+/* Bridge is NS-provider */
+
+int    bridgeopen ();
+int    bridgediscrim ();
+
+char   *bridgesave ();
+int    bridgerestore ();
+
+
+/* TP4 is the protocol and the TS-provider */
+
+int    tp4init ();
+
+int    tp4open ();
+
+char   *tp4save ();
+int    tp4restore ();
diff --git a/src/isode/h/tsap.h b/src/isode/h/tsap.h
new file mode 100644 (file)
index 0000000..7c21465
--- /dev/null
@@ -0,0 +1,207 @@
+/* tsap.h - include file for transport users (TS-USER) */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:09  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:33  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:47  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:33:59  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef        _TSAP_
+#define        _TSAP_                  
+
+#ifndef        _MANIFEST_
+#include "manifest.h"
+#endif
+#ifndef        _GENERAL_
+#include "general.h"
+#endif
+#ifndef        _ISOADDRS_
+#include "isoaddrs.h"
+#endif
+
+/* \f */
+
+struct TSAPstart {             /* T-CONNECT.INDICATON */
+    int     ts_sd;             /* TRANSPORT descriptor */
+
+    struct TSAPaddr ts_calling;        /* address of peer calling */
+    struct TSAPaddr ts_called; /* address of peer called */
+
+    int     ts_expedited;      /* EXPEDITED DATA ok */
+
+    int            ts_tsdusize;        /* largest atomic TSDU */
+
+    struct QOStype ts_qos;     /* quality of service */
+
+                               /* initial DATA from peer */
+#define        TS_SIZE         32
+    int            ts_cc;              /*   length */
+    char    ts_data[TS_SIZE];  /*   data */
+};
+
+
+struct TSAPconnect {           /* T-CONNECT.CONFIRMATION */
+    int     tc_sd;             /* TRANSPORT descriptor */
+
+    struct TSAPaddr tc_responding;/* address of peer responding */
+
+    int     tc_expedited;      /* EXPEDITED DATA ok */
+
+    int            tc_tsdusize;        /* largest atomic TSDU */
+
+    struct QOStype tc_qos;     /* quality of service */
+
+                               /* initial DATA from peer */
+#define        TC_SIZE         32
+    int            tc_cc;              /*   length */
+    char    tc_data[TC_SIZE];  /*   data */
+};
+
+
+struct TSAPdata {              /* T-READ.INDICATION */
+    int     tx_expedited;
+
+                               /* DATA from peer */
+#define        TX_SIZE         16      /* EXPEDITED DATA only */
+    int            tx_cc;              /*   total length */
+    struct qbuf tx_qbuf;       /*   chained data */
+};
+#define        TXFREE(tx)      QBFREE (&((tx) -> tx_qbuf))
+
+
+struct TSAPdisconnect {                /* T-DISCONNECT.INDICATION */
+    int     td_reason;         /* reason for DISCONNECT, from ISO8072: */
+#define        DR_BASE         0x80
+#define        DR_NORMAL       (DR_BASE + 0)   /* NORMAL disconnect by SESSION
+                                          entity */
+#define        DR_REMOTE       (DR_BASE + 1)   /* Remote TRANSPORT entity congested at
+                                          connect request time */
+#define        DR_CONNECT      (DR_BASE + 2)   /* Connection negotiation failed */
+#define        DR_DUPLICATE    (DR_BASE + 3)   /* Duplicate source reference detected
+                                          for the same pair of NSAPs */
+#define        DR_MISMATCH     (DR_BASE + 4)   /* Mismatched references */
+#define        DR_PROTOCOL     (DR_BASE + 5)   /* Protocol error */
+#define        DR_OVERFLOW     (DR_BASE + 7)   /* Reference overflow */
+#define        DR_REFUSED      (DR_BASE + 8)   /* Connect request refused on this
+                                          network connection */
+#define        DR_LENGTH       (DR_BASE + 10)  /* Header or parameter length
+                                          invalid */
+
+                                       /* begin UNOFFICIAL */
+#define        DR_NETWORK      (DR_BASE + 11)  /* Network disconnect */
+#define        DR_PARAMETER    (DR_BASE + 12)  /* Invalid parameter */
+#define        DR_OPERATION    (DR_BASE + 13)  /* Invalid operation */
+#define        DR_TIMER        (DR_BASE + 14)  /* Timer expired */
+#define        DR_WAITING      (DR_BASE + 15)  /* Indications waiting */
+                                       /* end UNOFFICIAL */
+
+#define        DR_UNKNOWN      0               /* Reason not specifed */
+#define        DR_CONGEST      1               /* Congestion at TSAP */
+#define        DR_SESSION      2               /* Session entity not attached to
+                                          TSAP */
+#define        DR_ADDRESS      3               /* Address unknown */
+
+#ifdef notdef
+#define        DR_FATAL(r)     ((r) < DR_BASE || (r) < DR_PARAMETER)
+#define        DR_OFFICIAL(r)  ((r) < DR_BASE || (r) < DR_NETWORK)
+#else
+#define        DR_FATAL(r)     ((r) < DR_PARAMETER)
+#define        DR_OFFICIAL(r)  ((r) < DR_NETWORK)
+#endif
+
+#define DR_CONS                        256             /* Base for CONS reson codes */
+#define DR_CONS_UNDEFINED      DR_CONS+0       /* Undefined */
+               /* originator: NS_PROVIDER */
+#define        DR_CONS_PROVIDER        DR_CONS+224     /* GENERIC */
+#define        DR_CP_DIS_TRANS         DR_CONS+225     /* Disconnect - transient */
+#define        DR_CP_DIS_PERM          DR_CONS+226     /* Disconnect - permanent */
+#define        DR_CP_REJ_UNSPEC_TRANS  DR_CONS+227     /* Reject - transient */
+#define        DR_CP_REJ_UNSPEC_PERM   DR_CONS+228     /* Reject - permanent */
+#define        DR_CP_REJ_NO_QOS_TRANS  DR_CONS+229     /* No QOS - transient */
+#define        DR_CP_REJ_NO_QOS_PERM   DR_CONS+230     /* No QOS - permanent */
+#define        DR_CP_REJ_NSAP_UNREACH_TRANS    DR_CONS+231     /* NSAP unreachable */
+#define        DR_CP_REJ_NSAP_UNREACH_PERM     DR_CONS+232     /* NSAP unreachable */
+#define        DR_CP_RESET_UNSPEC      DR_CONS+233     /* Unspecified RESET */
+#define        DR_CP_RESET_CONGESTION  DR_CONS+234     /* RESET due to congestion */
+#define        DR_CP_REJ_NSAP_UNKNOWN_PERM     DR_CONS+235     /* Unknown NSAP */
+               /* originator: NS_USER */
+#define        DR_CONS_USER            DR_CONS+240     /* GENERIC */
+#define        DR_CU_DIS_NORMAL        DR_CONS+241     /* Normal disconnect */
+#define        DR_CU_DIS_ABNORMAL      DR_CONS+242     /* Abnormal disconnect */
+#define        DR_CU_REJ_UNSPEC_TRANS  DR_CONS+244     /* Reject - transient */
+#define        DR_CU_REJ_UNSPEC_PERM   DR_CONS+245     /* Reject - permanent */
+#define        DR_CU_REJ_NO_QOS_TRANS  DR_CONS+246     /* No QOS - transient */
+#define        DR_CU_REJ_NO_QOS_PERM   DR_CONS+247     /* No QOS - permanent */
+#define        DR_CU_REJ_INCOMPAT      DR_CONS+248     /* Incompatable NS user data */
+#define        DR_CU_RESET_USER_RESYNCH DR_CONS+250    /* User RESET */
+
+                               /* disconnect DATA from peer */
+#define        TD_SIZE         64
+    int            td_cc;              /*   length */
+    char    td_data[TD_SIZE];  /*   data */
+};
+
+/* \f */
+
+extern char *tsapversion;
+
+
+int    TInit ();               /* T-CONNECT.INDICATION */
+
+int    TConnResponse ();       /* T-CONNECT.RESPONSE */
+                               /* T-CONNECT.REQUEST (backwards-compatible) */
+#define        TConnRequest(a1,a2,a3,a4,a5,a6,a7,a8) \
+       TAsynConnRequest(a1,a2,a3,a4,a5,a6,a7,a8,0)
+int    TAsynConnRequest ();    /* T-(ASYN-)CONNECT.REQUEST */
+int    TAsynRetryRequest ();   /* T-ASYN-RETRY.REQUEST (pseudo) */
+int    TDataRequest ();        /* T-DATA.REQUEST */
+int    TWriteRequest ();       /* T-WRITE.REQUEST (pseudo) */
+int    TExpdRequest ();        /* T-EXPEDITED-DATA.REQUEST */
+int    TReadRequest ();        /* T-READ.REQUEST (pseudo) */
+int    TDiscRequest ();        /* T-DISCONNECT.REQUEST */
+
+int    TSetIndications ();     /* define vectors for INDICATION events */
+int    TSelectMask ();         /* map transport descriptors for select() */
+int    TSelectOctets ();       /* estimate of octets that might be returned */
+int    TGetAddresses ();       /* get TSAPs */
+int    TSetManager ();         /* defining transport manager */
+
+char   *TErrString ();         /* return TSAP error code in string form */
+
+int    TNetListen ();          /* start listenting on an TSAP */
+int    TNetUnique ();          /* start listenting on a set of unique TSAPs */
+#define        TNetAccept(p,v,n,r,w,e,s,t) \
+       TNetAcceptAux ((p), (v), NULLIP, NULLTA, (n), (r), (w), (e), (s), (t))
+int    TNetAcceptAux ();       /* accept a call on an TSAP */
+int    TNetClose ();           /* stop listening on an TSAP */
+int    TSetQueuesOK ();        /* enable/disable queued (non-blocking)
+                                  writes */
+
+#define        TLocalHostName  getlocalhost
+char   *TLocalHostName ();     /* return name of local host (sigh) */
+#endif
diff --git a/src/isode/h/usr.dirent.h b/src/isode/h/usr.dirent.h
new file mode 100644 (file)
index 0000000..6b460a9
--- /dev/null
@@ -0,0 +1,63 @@
+/* usr.dirent.h - ISODE's version of DAG's SVR3 directory access routines */
+
+/*
+       <dirent.h> -- definitions for SVR3 directory access routines
+
+       last edit:      25-Apr-1987     D A Gwyn
+
+       Prerequisite:   <sys/types.h>
+*/
+
+#ifndef        _CONFIG_
+#include "config.h"            /* system-specific configuration */
+#endif
+#ifndef        GETDENTS
+#if    defined(SUNOS4)
+#define        GETDENTS
+#endif
+#endif
+
+#ifdef GETDENTS
+#include <dirent.h>
+#else
+#include       "sys.dirent.h"
+
+#define        DIRBUF          8192            /* buffer size for fs-indep. dirs */
+       /* must in general be larger than the filesystem buffer size */
+
+typedef struct
+       {
+       int     dd_fd;                  /* file descriptor */
+       int     dd_loc;                 /* offset in block */
+       int     dd_size;                /* amount of valid data */
+       char    *dd_buf;                /* -> directory block */
+       }       DIR;                    /* stream data from opendir() */
+
+#define        opendir         _opendir
+#define        readdir         _readdir
+#define        telldir         _telldir
+#define        seekdir         _seekdir
+#define        rewinddir       _rewinddir
+#define        closedir        _closedir
+
+extern DIR             *opendir();
+extern struct dirent   *readdir();
+extern off_t           telldir();
+extern void            seekdir();
+extern void            rewinddir();
+extern int             closedir();
+
+#ifndef NULL
+#define        NULL    0                       /* DAG -- added for convenience */
+#endif
+#endif /* not GETDENTS */
+
+#define        getcwd          _getcwd
+
+extern char             *getcwd ();
+
+
+#define        scandir _scandir
+#define        alphasort _alphasort
+
+extern char *direntversion;
diff --git a/src/isode/h/x25.h b/src/isode/h/x25.h
new file mode 100644 (file)
index 0000000..9cd2cff
--- /dev/null
@@ -0,0 +1,276 @@
+/* x25.h - X.25 abstractions */
+
+/*
+ * $Header$
+ *
+ * Contributed by John Pavel, Department of Trade and Industry/National
+ * Physical Laboratory in the UK
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:13  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:37  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:38:51  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:34:00  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#ifndef _X25_
+#define _X25_
+
+/*
+ *
+ * #defines for generic addressing & TSEL encoded addresses.
+ *
+ */
+
+#ifndef _INTERNET_
+#include <sys/socket.h>
+#endif
+
+#ifdef  SUN_X25
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <sundev/syncstat.h>
+#include <netx25/x25_pk.h>
+#include <netx25/x25_ctl.h>
+#include <netx25/x25_ioctl.h>
+#endif
+
+#ifdef  HPUX_X25
+#include <x25/x25.h>
+#include <x25/x25addrstr.h>
+#include <x25/x25ioctls.h>
+#include <x25/x25str.h>
+#include <x25/x25codes.h>
+
+#define       MAX_EVENT_SIZE          34
+typedef struct x25addrstr     X25_ADDR;
+typedef struct x25_userdata     X25_USERDATA;
+typedef struct {
+      X25_ADDR                addr;
+      X25_USERDATA            cudf;
+      }                       CONN_DB;
+typedef struct x25_cause_diag   X25_CAUSE_DIAG;
+typedef struct x25_msg_stat     X25_MSG_STAT;
+typedef struct x25_facilities   CCITT_FACILITY_DB;
+typedef       struct facility_dB_S {
+#define REVCHARGE             0x01
+#define       FAST_OFF                0
+#define FAST_SELECT           1
+#define       FAST_ACPT_CLR           2
+#define       FAST_CLR_ONLY           1
+#define       CCITT_FAST_OFF          0
+#define CCITT_FAST_SELECT     0x80
+#define       CCITT_FAST_ACPT_CLR     0x80
+#define       CCITT_FAST_CLR_ONLY     0xC0
+    u_char    t_01;
+       /* Bit 0:       rev-charge allowed                      */
+      /* Bit 7:       restricted fast-select (CLR only)       */
+      /* Bit 8:       fast-select allowd                      */
+
+    u_char    t_02;
+      /* Bits 0-3:    send-thruput                            */
+      /* Bits 4-7:    recv-thruput                            */
+
+#define CCITT_CUG             1
+#define CCITT_CUG_EXTENDED    3
+    u_char    t_03_sel;
+    u_short   t_03;
+      /* closed user group in 2- or 4-digit BCD               */
+
+#define REQ_CHARGE_INF                1
+    u_char    t_04;
+      /* Bit 0:       charging information requested          */
+
+#define ACK_EXPECTED  0x01
+#define NACK_EXPECTED 0x02
+    u_char    t_07;
+      /* Bit 0:       send ACK                                */
+      /* Bit 1:       send NACK                               */
+
+    u_char    t_08;
+      /* called line address modified notification            */
+define CCITT_OUTCUG_EXTENDED 3
+    u_char    t_09_sel;
+    u_short   t_09;
+      /* closed user group in 2- or 4-digit BCD               */
+
+    u_char    t_41_sel;
+    u_short   t_41;
+      /* bilateral closed user group in 4-digit BCD           */
+
+    u_char    t_42 [2];
+      /* Byte 0:      recv-pcktsize (log2)                    */
+      /* Byte 1:      send-pcktsize (log2)                    */
+
+    u_char    t_43 [2];
+      /* Byte 0:      recv-windowsize                         */
+      /* Byte 1:      send-windowsize                         */
+
+#define CCITT_RPOA            1
+    u_char    t_44_sel;
+    u_short   t_44;
+      /* RPOA transit number                                  */
+
+    u_char    t_49_sel;
+    u_short   t_49;
+      /* Transit delay selection and indication               */
+
+    u_char    *t_c1;
+      /* call duration charge-information                     */
+      /* Byte 0:      length of fac. parm. field              */
+    u_char    *t_c2;
+      /* segment count charge-information                     */
+      /* Byte 0:      length of fac. parm. field              */
+
+    u_char    *t_c3;
+      /* call deflection/restriction notification             */
+      /* Byte 0:      length of fac. parm. field              */
+      /* Byte 1:      deflection reason                       */
+
+    u_char    *t_c4;
+      /* RPOA extended format                                 */
+      /* Byte 0:      length of fac. parm. field              */
+
+    u_char    *t_c5;
+      /* monetary unit charge-information                     */
+      /* Byte 0:      length of fac. parm. field              */
+
+    u_char    *t_c6;
+      /* NUI selection                                        */
+      /* Byte 0:      length of fac. parm. field              */
+
+    u_char    *t_d1;
+      /* CALL deflection                                      */
+      /* Byte 0:      length of fac. parm. field              */
+      /* Byte 1:      deflection reason from remote DTE       */
+      /* Byte 2:      length of alt. DTE (in digits)          */
+} FACILITY_DB;
+#endif
+
+
+#include <sys/protosw.h>
+#include <sys/domain.h>
+#include <sys/socketvar.h>
+#include <sys/errno.h>
+#include <net/if.h>
+
+#ifdef  CAMTEC
+#include <cci.h>
+typedef struct  ccontrolp CONN_DB;
+#undef  NTPUV
+#define NTPUV   2               /* CAMTEC allows only 2 iov's per read/write */
+#endif
+
+#ifdef  CAMTEC_CCL
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <netccl/ccl.h>
+
+typedef struct ccliovec CONN_DB;
+#endif
+
+
+#ifdef UBC_X25
+#include <netccitt/x25_sockaddr.h>
+#ifdef BSD44
+#include <sys/ioctl.h>
+#endif
+
+#define         X25_PACKETSIZE  128
+
+typedef struct x25_sockaddr CONN_DB;
+#endif
+
+
+#ifdef ULTRIX_X25
+#include <netx25/x25.h>
+#include <stdio.h>
+#include <sys/time.h>
+
+typedef struct NSAPaddr CONN_DB; /* 
+                                * address translation is delayed until
+                                * connect()/accept() time and returns
+                                * as fields in a packed structure. calls
+                                * to an X25Encode() X25Decode() routine
+                                * unpacks this directly into the ISODE
+                                * NSAPaddr buffer. not as simple as
+                                * some but DEC like to be different (sigh)
+                                */
+
+#define select_x25_socket    selsocket
+#define read_x25_socket      read
+#define write_x25_socket     write
+
+#endif /* ULTRIX_X25 */
+/* \f */
+
+#ifdef SUN_X25
+#define close_x25_socket     close
+#define select_x25_socket    selsocket
+#define read_x25_socket      read
+#define write_x25_socket     write
+#endif
+
+#ifdef HPUX_X25
+#define REST_TYPE 2
+#define select_x25_socket    selsocket
+#define read_x25_socket      read
+#define write_x25_socket     write
+#endif
+
+#if     defined(UBC_X25) || defined(CAMTEC_CCL) 
+#define close_x25_socket     close
+#define select_x25_socket    selsocket
+#endif
+
+#ifndef        RECV_DIAG
+#define RECV_DIAG 0
+#define DIAG_TYPE 1
+#define WAIT_CONFIRMATION 2
+#endif
+
+int     start_x25_client ();
+int     start_x25_server ();
+int     join_x25_client ();
+int     join_x25_server ();
+int     read_x25_socket ();
+int     write_x25_socket ();
+int     close_x25_socket ();
+int     select_x25_socket ();
+
+struct NSAPaddr *if2gen();
+CONN_DB *gen2if();
+
+
+#define ADDR_LOCAL      0
+#define ADDR_REMOTE     1
+#define ADDR_LISTEN     2
+#define SEPARATOR ':'
+
+
+#define MAXNSDU 2048                   /* must be equal to largest TP0 TPDU */
+#endif
diff --git a/src/isode/pepsy/Makefile.in b/src/isode/pepsy/Makefile.in
new file mode 100644 (file)
index 0000000..b26daa0
--- /dev/null
@@ -0,0 +1,357 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE PEPSY process
+###############################################################################
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+BUILDTOP = ../../
+TOPDIR = $(BUILDTOP)
+
+OPTIONS        =       -I. -I$(HDIR) $(PEPYPATH) $(KRBOPT)
+CFLAGS  =       $(OPTIONS) $(LOPTIONS) 
+
+HDIR   =       $(TOPDIR)isode/h/
+UTILDIR        =       $(TOPDIR)isode/util/
+INCDIRM        =       $(HDIR)
+INCDIR =       $(INCDIRM)/
+PEPSYDIRM=     $(INCDIR)pepsy
+PEPSYDIR=      $(PEPSYDIRM)/
+PSAPDIRM=      $(TOPDIR)isode/psap
+PSAPDIR=       $(PSAPDIRM)/
+LIBISODE=      $(TOPDIR)libisode.a
+LIBDSAP        =       $(TOPDIR)libdsap.a
+
+KRBINC =       $(TOPDIR)include/
+ISODEINCM=     $(KRBINC)isode
+ISODEINC=      $(KRBINC)isode/
+PEPSYINCM=     $(ISODEINC)pepsy
+PEPSYINC=      $(ISODEINC)pepsy/
+
+LIBES  =       libcompat.a
+LLIBS   =
+LN     =       ln
+LDCC   =       $(CC)
+###############################################################################
+#
+#                               NOTICE
+#
+#    Acquisition, use, and distribution of this module and related
+#    materials 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 -DPEPSYPATH=\".:$(PEPSYDIRM)\" 
+
+# to prevent a lot of unnecessary re-loading
+PEPSYLIBES=    $(PSAPDIR)/sprintoid.o $(PSAPDIR)/pl_tables.o \
+               $(PSAPDIR)/oid_cmp.o $(PSAPDIR)/oid_cpy.o \
+               $(PSAPDIR)/oid_free.o ../compat/libcompat.a
+LIBES   =      $(TOPDIR)libpsap.a $(TOPDIR)libcompat.a
+LLIBS   =      $(TOPDIR)llib-lpsap $(TOPDIR)llib-lcompat
+HFILES =       $(HDIR)psap.h \
+               $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+
+DRFILES        =       enc.o dec.o fre.o prnt.o util.o
+SUPFILES=      vprint.o UNIV_tables.o pepsy_str.o py_advise.o
+LIBFILES=      $(DRFILES) $(SUPFILES)
+
+CFILES =       enc.c dec.c fre.c prnt.c main.c util.c  \
+               vprint.c pepsy_str.c py_advise.c
+
+HFILES =       $(HDIR)/pepsy.h test_table.h
+HEADERS        =       UNIV.ph UNIV-types.h
+
+OFILES =       $(LIBFILES) main.o
+
+T_FILES =      T1_tables.c T2_tables.c T3_tables.c
+
+
+##################################################################
+# Here it is...
+##################################################################
+all:           pepsy libpepsy # peptest
+               -mkdir $(ISODEINCM)
+               -mkdir $(PEPSYINCM)
+               @for h in $(HEADERS); do cp $$h $(PEPSYINC)/$$h; done
+               -@echo copied $(HEADERS)
+
+inst-all:      inst-pepsy inst-headers manuals # inst-libpepsy
+install:       inst-all clean
+lint:          l-pepsy l-libpepsy
+
+
+##################################################################
+# pepsy
+##################################################################
+
+PEPSY-C = pepsy.c pepsy-yacc.c pepsy_misc.c pass2.c etabs.c dtabs.c ptabs.c \
+               dfns.c mod.c
+PEPSY-O        = pepsy.o pepsy-yacc.o pepsy_misc.o pass2.o etabs.o dtabs.o ptabs.o \
+               dfns.o mod.o
+
+inst-pepsy:    $(BINDIR)pepsy
+
+$(BINDIR)pepsy:        xpepsy
+               -cp $@ zxpepsy
+               -rm -f $@
+               cp xpepsy $@
+               -@ls -gls $@
+               -@echo ""
+
+pepsy:         xpepsy
+               -@echo ""
+
+xpepsy:                pepsyvrsn.o $(PEPSYLIBES)
+               $(LDCC) $(LDFLAGS) -o $@ $(PEPSY-O) \
+                       pepsyvrsn.o $(PEPSYLIBES) -lm
+
+pepsy.o:       pepsy.c pepsydefs.h $(HFILES)
+               $(CC) $(CFLAGS) -c pepsy.c
+
+
+pepsyvrsn.c:   $(PEPSY-O)
+               $(UTILDIR)version.sh pepsy > $@
+
+pepsy-yacc.o:  pepsy-yacc.c lex.c
+               $(CC) $(CFLAGS) -c pepsy-yacc.c
+
+pepsy-yacc.c:  pepsy-yacc.y
+               -@echo "expect 40 shift/reduce and 11 reduce/reduce conflicts"
+               yacc $(YACCFLAGS) pepsy-yacc.y
+               mv y.tab.c $@
+
+pepsy-yacc.y:  yacc.y.gnrc
+               $(UTILDIR)extract.sh PEPSY SCTRL < $? > $@
+
+pepsy_misc.o:  pepsy_misc.c pepsydefs.h
+               $(CC) $(CFLAGS) -c pepsy_misc.c
+
+lex.c:         lex.l
+               $(LEX) $(LEXFLAGS) lex.l
+               mv lex.yy.c $@
+
+lex.l:         lex.l.gnrc
+               $(UTILDIR)extract.sh PEPSY < $? > $@
+
+pepsydefs.h:   pepsydefs.h.gnrc
+               $(UTILDIR)extract.sh PEPSY < $? > $@
+
+pepsy.h:       pepsy.h.gnrc
+               $(UTILDIR)extract.sh PEPSY < $? > $@
+
+pass2.o:       pass2.c
+               $(CC) $(CFLAGS) -c pass2.c
+etabs.o:       etabs.c
+               $(CC) $(CFLAGS) -c etabs.c
+dtabs.o:       dtabs.c
+               $(CC) $(CFLAGS) -c dtabs.c
+ptabs.o:       ptabs.c
+               $(CC) $(CFLAGS) -c ptabs.c
+dfns.o:                dfns.c
+               $(CC) $(CFLAGS) -c dfns.c
+mod.o:         mod.c
+               $(CC) $(CFLAGS) -c mod.c
+
+
+l-pepsy:       $(PEPSY-C) pepsydefs.h pepsyvrsn.c true
+               $(LINT) $(LFLAGS) -DPEPSYPATH=\".:$(PEPSYDIRM)\" $(PEPSY-C) \
+                       pepsyvrsn.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+
+################################################################
+# libpepsy
+################################################################
+
+inst-libpepsy: $(LIBDIR)libpepsy.a inst-headers
+
+libpepsy:      libpepsy.a true
+               -@rm -f $(HDIR)/UNIV*.h
+               -@$(LN) UNIV-types.h $(HDIR)/UNIV-types.h || cp UNIV-types.h $(HDIR)/UNIV-types.h
+
+libpepsy.a:     $(LIBFILES)
+               -rm -f $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $@ $(LIBFILES)
+               -@rm -f $(TOPDIR)libpepsy.a
+               -@$(LN) libpepsy.a $(TOPDIR)libpepsy.a || cp libpepsy.a $(TOPDIR)libpepsy.a
+               -@ls -l $@
+               -@echo "PEPSY library built normally"
+
+inst-headers:; -mkdir $(PEPSYDIRM)
+               @for h in $(HEADERS); do $(MAKE) TARGET=$$h inst-target; done
+
+inst-target:   $(PEPSYDIR)$(TARGET)
+
+$(PEPSYDIR)$(TARGET):  $(TARGET)
+               -cp $@ z$(TARGET)
+               cp $(TARGET) $@
+               -@ls -gls $@
+               -@echo ""
+
+UNIV_tables.o: UNIV_tables.c UNIV-types.h
+
+UNIV-types.h UNIV_tables.c: UNIV.py xpepsy
+               ./xpepsy -A -f -h -m UNIV.py
+
+l-libpepsy:    $(CFILES) $(T_FILES) true
+               $(LINT) $(LFLAGS) $(CFILES) $(T_FILES) \
+                       $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+vprint.o:      UNIV-types.h $(HDIR)psap.h $(HDIR)general.h $(HDIR)manifest.h \
+               $(HDIR)logger.h
+
+
+##################################################################
+# pep
+##################################################################
+alltests:      tabletest peptest
+
+peptest:       pep.results pep.output
+               -diff pep.output pep.results
+               touch peptest
+
+pep.results:   pep
+               ./pep > pep.results
+
+tabletest:     xpepsy t1test t2test t3test psap2test acsaptest ftamtest 
+
+psap2test:     ../psap2/PS_tables.c ../psap2/PS-types.h
+       ./xpepsy -A -f -h -m ../psap2/ps.py
+       -diff ../psap2/PS_tables.c . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff ../psap2/PS-types.h . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -rm -f PS_tables.c PS-types.h 
+
+acsaptest:     ../acsap/ACS_tables.c ../acsap/ACS-types.h
+       ./xpepsy -A -f -h -m ../acsap/acs.py
+       -diff ../acsap/ACS_tables.c . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff ../acsap/ACS-types.h . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -rm -f ACS_tables.c ACS-types.h 
+
+ftamtest:      ../ftam/FTAM_tables.c ../ftam/FTAM-types.h
+       ./xpepsy -A -f -h -m ../ftam/ftam.py
+       -diff ../ftam/FTAM_tables.c . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff ../ftam/FTAM-types.h . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -rm -f FTAM_tables.c FTAM-types.h 
+
+fadutest:      ../ftam/FADU_tables.c ../ftam/FADU-types.h
+       ./xpepsy -A -f -h -m ../ftam/fadu.py
+       -diff ../ftam/FADU_tables.c . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff ../ftam/FADU-types.h . | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -rm -f FADU_tables.c FADU-types.h 
+
+t1test:        T1_tables.c T1-types.h
+       mv T1_tables.c T1_tables.c_orig
+       mv T1-types.h T1-types.h_orig
+       ./xpepsy -A -f -m t1.py
+       -diff T1_tables.c_orig T1_tables.c | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff T1-types.h_orig T1-types.h | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+
+t2test:        T2_tables.c T2-types.h
+       mv T2_tables.c T2_tables.c_orig
+       mv T2-types.h T2-types.h_orig
+       ./xpepsy -A -f -m t2.py
+       -diff T2_tables.c_orig T2_tables.c | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff T2-types.h_orig T2-types.h | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+
+t3test:        T3_tables.c T3-types.h
+       mv T3_tables.c T3_tables.c_orig
+       mv T3-types.h T3-types.h_orig
+       ./xpepsy -A -f -m -i pepsy-refs.h t3.py
+       -diff T3_tables.c_orig T3_tables.c | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+       -diff T3-types.h_orig T3-types.h | grep -v "^[><] # line" \
+               | grep -v "do not edit"
+
+PEPLIBS        =       ../libpsap.a ../libcompat.a
+PEPFILES=      T1_tables.o T2_tables.o T3_tables.o $(OFILES) $(PEPLIBS) # malloctrace.a
+
+pep:           $(PEPFILES)
+               #$(LDCC) $(LDFLAGS) -o pep $(PEPFILES) malloctrace.a $(LSOCKET)
+               $(LDCC) $(LDFLAGS) -o pep $(PEPFILES) $(LSOCKET) -lm
+
+pep-saber:     $(PEPFILES)
+               #load $(CFLAGS) (PEPFILES)
+
+main.o:        T1-types.h test_table.h main.c
+               $(CC) $(CFLAGS) -DPRNT=1 -c main.c
+
+enc.o:         enc.c pepsy-driver.h
+               $(CC) $(CFLAGS) -c enc.c
+
+dec.o:         dec.c pepsy-driver.h
+               $(CC) $(CFLAGS) -c dec.c
+
+prnt.o:        prnt.c pepsy-driver.h
+               $(CC) $(CFLAGS) -c prnt.c
+
+util.o:        util.c pepsy-driver.h
+               $(CC) $(CFLAGS) -c util.c
+
+T1_tables.o:   T1_tables.c T1-types.h UNIV-types.h
+
+T1_tables.c T1-types.h:        t1.py xpepsy
+               ./xpepsy -A -f -m t1.py
+
+T1_tables.c:   T2-types.h T3-types.h
+
+T2_tables.o:   T2_tables.c T2-types.h UNIV-types.h
+
+T2_tables.c T2-types.h:        t2.py xpepsy
+               ./xpepsy -A -f -m t2.py
+
+T3_tables.o:   T3_tables.c T3-types.h UNIV-types.h
+
+T3_tables.c T3-types.h:        t3.py xpepsy
+               ./xpepsy -A -f -m -i pepy-refs.h t3.py
+
+prt.o:         prnt.c $(HDIR)/pepsy.h
+               $(CC) $(CFLAGS) -Dprintf=vprint -o $@ prnt.c
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       pepsy.1 # libpepsy.3
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a x* z* _* core pepsydefs.h *yacc.y *yacc.c lex.l \
+                       lex.c *.ph UNIV_* UNIV-* _* core $(HDIR)/UNIV*.h \
+                       pp.c pp pep libpepsy.a pepsy-yacc.y T1* T2* T3* t? \
+                       peptest pep.results pepsyvrsn.c
+
+grind:;                iprint Makefile
+               tgrind -lc pepsydefs.h pepsy.c pepsy.c pepsyvrsn.c
+               tgrind -ly yacc.y lex.l
+               tgrind -lpepsy -d $(TOPDIR)pepy/grindefs UNIV.py
+               tgrind -lc $(CFILES)
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
+
+true:;
diff --git a/src/isode/pepsy/UNIV.py b/src/isode/pepsy/UNIV.py
new file mode 100644 (file)
index 0000000..ef5b929
--- /dev/null
@@ -0,0 +1,140 @@
+-- ASN.1 UNIVERSAL defined types
+
+--
+-- 
+--
+
+--
+--                               NOTICE
+--
+--    Acquisition, use, and distribution of this module and related
+--    materials 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$";
+#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/src/isode/pepsy/configure.in b/src/isode/pepsy/configure.in
new file mode 100644 (file)
index 0000000..cdff2db
--- /dev/null
@@ -0,0 +1,2 @@
+AC_INIT(configure.in)
+AC_OUTPUT(Makefile)
diff --git a/src/isode/pepsy/dec.c b/src/isode/pepsy/dec.c
new file mode 100644 (file)
index 0000000..85845ce
--- /dev/null
@@ -0,0 +1,2154 @@
+/* dec.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:23  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:50  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:04  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:52  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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       "pepsy-driver.h"
+#include       "psap.h"
+#include       "pepsy.h"
+#include       "tailor.h"
+
+extern int pepsylose ();
+
+extern tpe *next_tpe(), *fdflt_b();
+
+#define NEXT_TPE(p)    (p = next_tpe(p))
+#define CHKTAG(mod, p, pe)     ismatch(p, mod, pe->pe_class, pe->pe_id)
+
+
+static char oomsg[] = "Out of memory";
+#define oom(a,b)       pepsylose ((a), (b), NULLPE, oomsg)
+
+static char inpmsg[] = "Illegal Null Pointer";
+#define inpm(a,b)      pepsylose ((a), (b), NULLPE, inpmsg)
+
+static PE setpresent();
+
+#define F_CI 0x100     /* called internally */
+
+/* Have we got an optional object which we have allocated space for */
+#define ALLOC_MEM(p, parm)     (p->pe_type == SOBJECT \
+       && p[-1].pe_type == MEMALLOC)
+
+static int pr_obj();
+static int pr_type();
+static int pr_seq();
+static int pr_set();
+static int pr_seqof();
+static int pr_setof();
+static int pr_choice();
+static int pr_etype();
+static int setdval();
+static int fix_mem();
+
+/*
+ * decode the specified type of the specified module into the given
+ * pe
+ */
+dec_f(typ, mod, pe, explicit, len, buf, parm)
+/* ARGSUSED */
+int     typ;                   /* which type it is */
+modtyp *mod;                   /* Module it is from */
+PE      pe;
+int    explicit;
+int    *len;
+char   **buf;
+char   **parm;
+{
+    tpe    *p;
+    int            iflag;      /* are we called internally ? */
+
+    if (typ < 0 || typ >= mod->md_nentries) {
+       return (pepsylose (mod, NULLTPE, NULLPE, "dec_f: Illegal typ %d", typ));
+    }
+
+    p = mod->md_dtab[typ];
+    if (p->pe_type != PE_START) {
+       return (pepsylose (mod, NULLTPE, NULLPE, "dec_f: missing PE_START"));
+    }
+    p++;
+    iflag = explicit & F_CI;
+    explicit &= ~F_CI;
+    if (!iflag)
+       *parm = NULLCP; /* initialise this for the MALLOCs that follow */
+
+    if (pr_obj(explicit, pe, parm, p, mod) == NOTOK)
+       goto bad;
+
+    return (OK);
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse an object. The top level of an object does not have any
+ * offset field which makes it different to pr_type routine which
+ * must assume that it has an offset.
+ */
+static int
+pr_obj(expl, pe, parm, p, mod)
+int     expl;                  /* do we look at the tag */
+PE      pe;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    int     cnt = 0;
+
+
+    DLOG (psap_log, LLOG_DEBUG, ("1st Decoding the type %d", p->pe_type));
+
+    while (p->pe_type != PE_END) {
+
+       if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) {
+           if (DEFAULT(p)) 
+               return pepsylose (mod, p, pe,
+                                 "pr_obj:Default not implemented");
+           else if (OPTIONAL(p)) {
+               if (ALLOC_MEM(p, parm))
+                   fix_mem(parm, p);
+               goto next;
+           } else
+               return pepsylose (mod, p, pe, "pr_obj:missing mandatory parameter");
+       }
+       DLOG (psap_log, LLOG_DEBUG, ("2nd Decoding the type %d", p->pe_type));
+
+       switch (p->pe_type) {
+       case PE_END:
+       case PE_START:
+           return pepsylose (mod, p, pe, "pr_obj:illegal END/START");
+
+       /*
+        * This allows Functions to be called at the very end of the 
+        * decoding -- With the decoded data - I hope - very messy
+        */
+       case UCODE:
+           if (mod->md_ducode == NULLIFP
+           || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+               goto bad;
+           break;
+
+
+       default:
+           if (pr_type(expl, pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+       }
+       if (ISDTYPE(p) && cnt > 0)
+           return pepsylose (mod, p, NULLPE, "pr_obj:compound type found");
+next:
+       if (NEXT_TPE(p) == NULLTPE)
+           goto bad;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse a single type. If a basic type parse it, if a compound type
+ * call the appropriate parsing routine
+ */
+static int
+pr_type(expl, pe, parm, p, mod)
+int     expl;                  /* do we look at the tag */
+PE      pe;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    int        cnt = 0;
+    int len;
+    OID     oid;
+    char    *nparm;
+    /* there is no such pointer as &(*parm + p->pe_ucode) (ucode non zero) so
+     * we fudge it by making a temporary one. As no memory needs to be
+     * allocated through it this should work
+     */
+
+
+    DLOG (psap_log, LLOG_DEBUG, ("pr_type:type %d", p->pe_type));
+
+    while (p->pe_type != PE_END) {
+
+       if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) {
+           if (DEFAULT(p)) {
+               if (setdval(p, FDFLT_B(p), parm, mod) == NOTOK)
+                   goto bad;
+               return (NO_DATA_USED);
+           } else if (OPTIONAL(p)) {
+               if (ALLOC_MEM(p, parm))
+                   fix_mem(parm, p);
+               return (NO_DATA_USED);
+           } else
+               return pepsylose (mod, p, pe,
+                                 "pr_type:missing mandatory parameter");
+       }
+       DLOG (psap_log, LLOG_DEBUG, ("pr_type: type %d", p->pe_type));
+
+       switch (p->pe_type) {
+       case PE_END:
+       case PE_START:
+           return pepsylose (mod, p, pe, "pr_type:illegal END/START");
+
+       case BOPTIONAL:
+           if (CHKTAG(mod, p + 1, pe) == 0) {
+               if (ALLOC_MEM(p, parm))
+                    fix_mem(parm, p);
+               if (IF_USELECT(p)) {
+                   if (p -> pe_ucode >= 0 &&
+                       (mod -> md_ducode == NULLIFP ||
+                        (*mod->md_ducode)(parm, pe, p, 0) == NOTOK))
+                       goto bad;
+               }
+               else CLR_OPT_PRESENT(p, parm);
+               return (NO_DATA_USED);
+           }
+           if (IF_USELECT(p)) {
+               if (p -> pe_ucode >= 0 &&
+                   (mod -> md_ducode == NULLIFP ||
+                    (*mod->md_ducode)(parm, pe, p, 1) == NOTOK))
+                   goto bad;
+           }
+           else
+               SET_OPT_PRESENT(p, parm);
+           p++;
+           continue;
+
+       case FREE_ONLY: /* the next entry(s) only for freeing routines 
+                        * so skip this and next entry
+                        */
+           break;
+       
+       case FFN_CALL:  /* call function to free - skip this here */
+           break;
+
+       case UCODE:
+           if (mod->md_ducode == NULLIFP
+           || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+               goto bad;
+           break;
+
+       case ETAG:
+           switch (p->pe_ucode) {
+           default:
+               p++;
+               if (pr_etype(pe->pe_cons, parm, p, mod) == NOTOK)
+                   return (NOTOK);
+           }
+           break;
+
+       case MEMALLOC:
+           if (*parm)
+               break;  /* already allocated */
+           if ((*(parm) = (char *) calloc(1, (unsigned ) p->pe_tag)) == NULL)
+               return oom(mod, p);
+           break;
+
+       /* The difference between here and the en_type makes me think
+        * that this is never called for SEQ_START ???? 
+        */
+       case SSEQ_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_seq(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_seq(pe, parm, p, mod) == NOTOK)
+                   goto bad;
+           break;
+
+       case SEQ_START:
+           if (pr_seq(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SSEQOF_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_seqof(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_seqof(pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQOF_START:
+           if (pr_seqof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SSET_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_set(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_set(pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SET_START:
+           if (pr_set(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SSETOF_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_setof(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_setof(pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SETOF_START:
+           if (pr_setof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case IMP_OBJ:
+           p++;
+           if (p->pe_type == EXTOBJ) {
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *)0,
+                     (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                     goto bad;
+           } else if (p->pe_type == SEXTOBJ) {
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *)0,
+                         (char **) 0, (char **) &nparm) == NOTOK)
+                         goto bad;
+               } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *)0,
+                         (char **) 0, (char **) parm) == NOTOK)
+                     goto bad;
+           } else {
+               if (p->pe_type == SOBJECT) {
+                   if (p->pe_ucode > 0) {
+                       if (*parm == NULLCP)
+                           return inpm(mod, p);
+                       nparm = *parm + p->pe_ucode;
+                       if (pr_obj(0, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod)
+                               == NOTOK)
+                           goto bad;
+                   } else if (pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)
+                               == NOTOK)
+                       goto bad;
+               } else if (pr_obj(0, pe, (char **) (*parm + p->pe_ucode),
+                       mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+                   goto bad;
+           }
+           break;
+
+       case SOBJECT:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_obj(expl, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod)==NOTOK)
+                   goto bad;
+           } else if (pr_obj(expl, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)==NOTOK)
+               goto bad;
+           break;
+
+       case OBJECT:
+
+           if (pr_obj(expl, pe, (char **) (*parm + p->pe_ucode),
+              mod->md_dtab[p->pe_tag] + 1, mod)==NOTOK)
+               goto bad;
+           break;
+
+       case SCHOICE_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_choice(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_choice(pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case CHOICE_START:
+           if (pr_choice(pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p, pe, "pr_type: missing EXTMOD");
+               nparm = *parm + p->pe_ucode;
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *)0,
+                     (char **) 0, &nparm) == NOTOK)
+                     goto bad;
+               } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *)0,
+                     (char **) 0, parm) == NOTOK)
+                 goto bad;
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, p, pe, "pr_type: missing EXTMOD");
+           if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *)0,
+                 (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                 goto bad;
+           break;
+
+       case INTEGER:
+           if (pe != NULLPE) {
+               DLOG (psap_log, LLOG_DEBUG, ("pr_type:integer %d",
+                                            prim2num(pe)));
+               if (((*(integer *) (*parm + p->pe_ucode)) = prim2num(pe))
+                   == NOTOK && pe->pe_errno != PE_ERR_NONE)
+                   return pepsylose (mod, p, pe, "pr_type:bad integer %s",
+                                     pe_error(pe->pe_errno));
+           }
+           break;
+
+#ifdef PEPSY_REALS
+       case REALTYPE:
+           if (pe != NULLPE) {
+               DLOG (psap_log, LLOG_DEBUG, ("pr_type:Real %g",
+                                             prim2real(pe)));
+
+               if (((*(double *) (*parm + p->pe_ucode)) = prim2real(pe))
+                   == NOTOK && pe->pe_errno != PE_ERR_NONE)
+                   return pepsylose (mod, p, pe, "pr_type:bad real %s",
+                                     pe_error(pe->pe_errno));
+           }
+           break;
+
+#endif
+
+       case BOOLEAN:
+           if (pe != NULLPE) {
+               int     i;
+
+               DLOG (psap_log, LLOG_DEBUG, ("boolean %d",
+                                            prim2flag(pe)));
+               if ((i = prim2flag (pe)) == NOTOK)
+                     return pepsylose (mod, p, pe, "pr_type:bad integer %s",
+                                       pe_error(pe->pe_errno));
+               *(char *) (*parm + p->pe_ucode) = i & 0xff;
+           }
+           break;
+
+       case T_NULL:
+           break;
+
+       case SANY:
+           if (pe != NULLPE) {
+               ((*(PE *) (parm + p->pe_ucode)) = pe)->pe_refcnt++;
+               if (pe->pe_errno != PE_ERR_NONE)
+                   return pepsylose (mod, p, pe, "pr_type:bad ANY %s",
+                                     pe_error(pe->pe_errno));
+           }
+           break;
+
+       case ANY:
+           if (pe != NULLPE) {
+               (*(PE *) (*parm + p->pe_ucode) = pe)->pe_refcnt++;
+               if (pe->pe_errno != PE_ERR_NONE)
+                   return pepsylose(mod, p, pe, "pr_type:bad ANY %s",
+                                    pe_error(pe->pe_errno));
+           }
+           break;
+
+       case SOCTETSTRING:
+           if (pe != NULLPE) {
+               if ((*((struct qbuf **) (parm + p->pe_ucode)) = prim2qb(pe)) ==
+                   (struct qbuf *) NULL && pe->pe_errno != PE_ERR_NONE)
+                   return pepsylose(mod, p, pe, "pr_type:bad octet string %s",
+                                    pe_error(pe->pe_errno));
+           }
+           break;
+
+       case OCTETSTRING:
+           if (pe != NULLPE) {
+               if ((*((struct qbuf **) (*parm + p->pe_ucode))
+                    = prim2qb(pe)) == (struct qbuf *) NULL
+                   && pe->pe_errno != PE_ERR_NONE)
+                   return pepsylose (mod, p, pe,
+                                     "pr_type:bad octet string %s",
+                                     pe_error(pe->pe_errno));
+           }
+           break;
+
+       case T_STRING:
+           if ((*((char **) (*parm + p->pe_ucode)) = prim2str(pe, &len))
+               == NULLCP && pe->pe_errno != PE_ERR_NONE)
+                 return pepsylose (mod, p, pe, "pr_type:bad octet string %s",
+                                 pe_error(pe->pe_errno));
+           /* undocumented feature of prim2str that it adds a NULL char
+            * to the end of the string
+            */
+           break;
+
+       case BITSTR_PTR:
+           if (p[1].pe_type != BITSTR_LEN)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "pr_type: missing BITSTR_PTR");
+
+           pe = prim2bit(pe);
+           if ((*((char **) (*parm + p->pe_ucode)) =
+               bitstr2strb(pe, (int *)(*parm + (p + 1)->pe_ucode)))
+               == NULLCP && pe->pe_errno != PE_ERR_NONE)
+                 return pepsylose (mod, p, pe, "pr_type:bad bit string %s",
+                                 pe_error(pe->pe_errno));
+           break;
+
+
+       case OCTET_PTR:
+           if (p[1].pe_type != OCTET_LEN)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "pr_type: missing OCTET_PTR");
+           if ((*((char **) (*parm + p->pe_ucode)) =
+               prim2str(pe, (int *)(*parm + (p + 1)->pe_ucode)))
+               == NULLCP && pe->pe_errno != PE_ERR_NONE)
+                 return pepsylose (mod, p, pe, "pr_type:bad octet string %s",
+                                 pe_error(pe->pe_errno));
+           break;
+
+
+       case SBITSTRING:
+           if (pe != NULLPE) {
+               if ((*((PE *) (parm + p->pe_ucode)) = prim2bit(pe_cpy(pe))) == NULLPE)
+                   return pepsylose (mod, p, pe, "pr_type:out of memory");
+           }
+           break;
+
+       case BITSTRING:
+           if (pe != NULLPE) {
+               if ((*((PE *) (*parm + p->pe_ucode)) =
+                    prim2bit(pe_cpy(pe))) == NULLPE)
+                   return pepsylose(mod, p, pe, "pr_type:out of memory");
+           }
+           break;
+
+       case SOBJID:
+           /*
+            * This is messy because ISODE's library routine uses a
+            * static. Don't know why they do
+            */
+           if ((oid = prim2oid(pe + p->pe_ucode)) == NULLOID
+               || (*(OID *) parm = oid_cpy(oid)) == NULLOID) {
+               if (oid && oid->oid_elements) {
+                   free((char *) oid->oid_elements);
+                   oid->oid_elements = NULL;
+               }
+               return pepsylose (mod, p, pe,
+                                 "pr_type:Object Identifier: out of memory");
+           }
+           if (oid && oid->oid_elements) {
+               free((char *) oid->oid_elements);
+               oid->oid_elements = NULL;
+           }
+           break;
+
+       case OBJID:
+           if ((oid = prim2oid(pe)) == NULLOID
+               || (*(OID *) (*parm + p->pe_ucode) = oid_cpy(oid)) == NULLOID) {
+               if (oid && oid->oid_elements) {
+                   free((char *) oid->oid_elements);
+                   oid->oid_elements = NULL;
+               }
+               return pepsylose (mod, p, pe,
+                                 "pr_type:Object Identifier: out of memory");
+           }
+           if (oid && oid->oid_elements) {
+               free((char *) oid->oid_elements);
+               oid->oid_elements = NULL;
+           }
+           break;
+
+       case FN_CALL:
+           if ((FN_PTR(mod, p))(parm, pe) == NOTOK)
+               return pepsylose (mod, p, NULLPE,
+                                 "pr_type:FN_CALL:call failed");
+           break;
+
+       default:
+           return pepsylose (mod, p, pe, "pr_type: type not implemented");
+       }
+       if (ISDTYPE(p) && cnt > 0)
+           return pepsylose (mod, p, pe, "pr_type:compound type found");
+
+       if (ISDTYPE(p) && pe != NULLPE)
+           return (OK);
+       if (NEXT_TPE(p) == NULLTPE)
+           goto bad;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse a sequence, calling appropriate routines to parse each sub
+ * type
+ */
+static int
+pr_seq(head, parm, p, mod)
+PE      head;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+    int    *popt = NULL;       /* Pointer to optional field */
+    int     optcnt = 0;                /* Number of optionals bits so far */
+    char    *nparm;
+
+    if (p->pe_type != SEQ_START && p->pe_type != SSEQ_START)
+       return pepsylose (mod, p, head, "pr_seq: missing SEQ_START");
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    pe = first_member(head);
+    while (p->pe_type != PE_END) {
+       DLOG (psap_log, LLOG_DEBUG, ("pr_seq:type %d", p->pe_type));
+
+       if (ISDTYPE(p) && OPTIONAL(p)) {
+           switch (p->pe_type) {
+           case INTEGER:
+           case REALTYPE:
+           case BOOLEAN:
+           case T_NULL:
+           basictype:
+               if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
+                   optcnt++;
+                   goto next;
+               }
+               SETBIT(*popt, optcnt++);
+               break;
+
+           case ETAG:                  /* XXX ? optional things in seq's? */
+               switch (p[1].pe_type) {
+               case INTEGER:
+               case REALTYPE:
+               case BOOLEAN:
+               case T_NULL:
+                   goto basictype;
+               }
+               /* else fall through... */
+
+           default:
+               if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
+                   if (ALLOC_MEM(p, parm))
+                       fix_mem(parm, p);
+                   goto next;
+               }
+               break;
+           }
+       } else if (ISDTYPE(p) && (pe == NULLPE || CHKTAG(mod, p, pe) == 0)) {
+           if (DEFAULT(p)) {
+               if(setdval(p, FDFLT_B(p), parm, mod) == NOTOK)
+                   goto bad;
+               goto next;
+           } else 
+               return pepsylose (mod, p, pe,
+                                 "pr_seq:missing mandatory parameter");
+       }
+       switch (p->pe_type) {
+       case OPTL:
+           popt = (int *) (*parm + p->pe_ucode);
+           break;
+
+       case FREE_ONLY: /* the next entry(s) only for freeing routines 
+                        * so skip this and next entry
+                        */
+           break;
+       
+       case FFN_CALL:  /* call function to free - skip this here */
+           break;
+
+       case UCODE:
+           if (mod->md_ducode == NULLIFP
+           || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+               goto bad;
+           break;
+
+       case BOPTIONAL:
+           if (pe == NULLPE || CHKTAG(mod, p + 1, pe) == 0) {
+               if (ALLOC_MEM(p, parm))
+                    fix_mem(parm, p);
+               if (IF_USELECT(p)) {
+                   if (p -> pe_ucode >= 0 &&
+                       (mod -> md_ducode == NULLIFP ||
+                        (*mod->md_ducode)(parm, pe, p, 0) == NOTOK))
+                       goto bad;
+               }
+               else CLR_OPT_PRESENT(p, parm);
+               goto next;
+           }
+           if (IF_USELECT(p)) {
+               if (p -> pe_ucode >= 0 &&
+                   (mod -> md_ducode == NULLIFP ||
+                    (*mod->md_ducode)(parm, pe, p, 1) == NOTOK))
+                   goto bad;
+           }
+           else SET_OPT_PRESENT(p, parm);
+           p++;
+           continue;
+
+       case ETAG:
+           if (pr_type(1, pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case MEMALLOC:
+           if (*parm)
+               break;  /* already allocated */
+           if ((*(parm) = (char *) calloc(1, (unsigned ) p->pe_tag))==NULLCP)
+               return oom(mod, p);
+           break;
+
+       case SEQ_START:
+           if (pr_seq(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQOF_START:
+           if (pr_seqof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SET_START:
+           if (pr_set(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SETOF_START:
+           if (pr_setof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case IMP_OBJ:
+           p++;
+           if (p->pe_type == EXTOBJ) {
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *)0,
+                     (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                     goto bad;
+           } else if (p->pe_type == SEXTOBJ) {
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *)0,
+                         (char **) 0, (char **) &nparm) == NOTOK)
+                         goto bad;
+               } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *)0,
+                         (char **) 0, (char **) parm) == NOTOK)
+                     goto bad;
+           } else {
+               if (p->pe_type == SOBJECT) {
+                   if (p->pe_ucode > 0) {
+                       if (*parm == NULLCP)
+                           return inpm(mod, p);
+                       nparm = *parm + p->pe_ucode;
+                       if (pr_obj(0, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod)
+                               == NOTOK)
+                           goto bad;
+                   } else 
+                       if (pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)
+                               == NOTOK)
+                           goto bad;
+               } else if (pr_obj(0, pe, (char **) (*parm + p->pe_ucode),
+                       mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+                   goto bad;
+           }
+           break;
+
+       case SOBJECT:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_obj(1, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case OBJECT:
+           if (pr_obj(1, pe, (char **) (*parm + p->pe_ucode),
+                   mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SCHOICE_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_choice(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_choice(pe, parm, p, mod) == NOTOK)
+                   goto bad;
+           break;
+
+       case CHOICE_START:
+           if (pr_choice(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, p, pe, "pr_seq: missing EXTMOD");
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                     (char **) 0, &nparm) == NOTOK)
+                     goto bad;
+           } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                     (char **) 0, parm) == NOTOK)
+                     goto bad;
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, p, pe, "pr_seq: missing EXTMOD");
+
+           if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                 (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                 goto bad;
+           break;
+
+       default:
+           /* only called if we have a match */
+           if (pr_type(1, pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+       }
+
+       if (ISDTYPE(p) && pe != NULLPE)
+           pe = next_member(head, pe);
+next:
+       if (NEXT_TPE(p) == NULLTPE)
+           goto bad;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+
+/*
+ * Parse a set, calling appropriate routines to parse each sub type
+ */
+static int
+pr_set(head, parm, p, mod)
+PE      head;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+    int    *popt = NULL;       /* Pointer to optional field */
+    int     optcnt = 0;                /* Number of optionals bits so far */
+    char    *nparm;
+
+    if (p->pe_type != SET_START && p->pe_type != SSET_START)
+       return pepsylose (mod, p, NULLPE, "pr_seq: missing SET_START");
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    while (p->pe_type != PE_END) {
+       DLOG (psap_log, LLOG_DEBUG, ("pr_set type %d", p->pe_type));
+
+       if (ISDTYPE(p) && OPTIONAL(p)) {
+           switch (p->pe_type) {
+           case INTEGER:
+           case REALTYPE:
+           case BOOLEAN:
+           case T_NULL:
+               if ((pe = setpresent(head, p, mod)) == NULLPE) {
+                   optcnt++;
+                   goto next;
+               }
+               SETBIT(*popt, optcnt++);
+               break;
+
+
+           default:
+               if ((pe = setpresent(head, p, mod)) == NULLPE) {
+                   if (ALLOC_MEM(p, parm))
+                       fix_mem(parm, p);
+                   goto next;
+               }
+               break;
+           }
+       } else if (ISDTYPE(p) && (pe = setpresent(head, p, mod)) == NULLPE) {
+           if (DEFAULT(p)) {
+               if (setdval(p, FDFLT_B(p), parm, mod) == NOTOK)
+                   goto bad;
+               goto next;
+           } else
+               return pepsylose (mod, p, pe,
+                                 "pr_set:missing mandatory parameter");
+       }
+       switch (p->pe_type) {
+       case OPTL:
+           popt = (int *) (*parm + p->pe_ucode);
+           break;
+
+       case FREE_ONLY: /* the next entry(s) only for freeing routines 
+                        * so skip this and next entry
+                        */
+           break;
+       
+       case FFN_CALL:  /* call function to free - skip this here */
+           break;
+
+       case UCODE:
+           if (mod->md_ducode == NULLIFP
+           || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+               goto bad;
+           break;
+
+       case BOPTIONAL:
+           if ((pe = setpresent(head, p + 1, mod)) == NULLPE) {
+               if (ALLOC_MEM(p, parm))
+                    fix_mem(parm, p);
+               if (IF_USELECT(p)) {
+                   if (p -> pe_ucode >= 0 &&
+                       (mod -> md_ducode == NULLIFP ||
+                       (*mod->md_ducode)(parm, pe, p, 0) == NOTOK))
+                       goto bad;
+               }
+               else CLR_OPT_PRESENT(p, parm);
+               goto next;
+           }
+           if (IF_USELECT(p)) {
+               if (p -> pe_ucode >= 0 &&
+                   (mod -> md_ducode == NULLIFP ||
+                    (*mod->md_ducode)(parm, pe, p, 1) == NOTOK))
+                   goto bad;
+           }
+           else SET_OPT_PRESENT(p, parm);
+           p++;
+           continue;
+
+       case ETAG:
+           if (pr_type(1, pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case MEMALLOC:
+           if (*parm)
+               break;  /* already allocated */
+           if ((*(parm) = (char *) calloc(1, (unsigned ) p->pe_tag))==NULLCP)
+               return oom(mod, p);
+           break;
+
+       case SEQ_START:
+           if (pr_seq(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQOF_START:
+           if (pr_seqof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SET_START:
+           if (pr_set(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SETOF_START:
+           if (pr_setof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case IMP_OBJ:
+           p++;
+           if (p->pe_type == EXTOBJ) {
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *) 0,
+                     (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                     goto bad;
+           } else if (p->pe_type == SEXTOBJ) {
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *) 0,
+                         (char **) 0, (char **) &nparm) == NOTOK)
+                         goto bad;
+               } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *) 0,
+                         (char **) 0, (char **) parm) == NOTOK)
+                         goto bad;
+           } else {
+               if (p->pe_type == SOBJECT) {
+                   if (p->pe_ucode > 0) {
+                       if (*parm == NULLCP)
+                           return inpm(mod, p);
+                       nparm = *parm + p->pe_ucode;
+                       if (pr_obj(0, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod)
+                               == NOTOK)
+                           goto bad;
+                   } else if (pr_obj(0, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)
+                               == NOTOK)
+                           goto bad;
+               } else if (pr_obj(0, pe, (char **) (*parm + p->pe_ucode),
+                       mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+                   goto bad;
+           }
+           break;
+
+       case SOBJECT:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_obj(1, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod)== NOTOK)
+                   goto bad;
+           } else if (pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod)== NOTOK)
+                   goto bad;
+           break;
+
+       case OBJECT:
+           if (pr_obj(1, pe, (char **) (*parm + p->pe_ucode),
+                   mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SCHOICE_START:
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_choice(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+           } else if (pr_choice(pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case CHOICE_START:
+           if (pr_choice(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, p, pe, "pr_set: missing EXTMOD");
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                     (char **) 0, &nparm) == NOTOK)
+                     goto bad;
+           } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                     (char **) 0, parm) == NOTOK)
+                     goto bad;
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD) 
+               return pepsylose (mod, p, pe, "pr_set: missing EXTMOD");
+
+           if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                 (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                 goto bad;
+           break;
+
+       default:
+           if (pr_type(1, pe, parm, p, mod) == NOTOK)
+               goto bad;
+           break;
+       }
+
+next:
+       if (NEXT_TPE(p) == NULLTPE)
+           goto bad;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+
+}
+
+
+/*
+ * Parse a sequence of calling appropriate routines to parse each sub
+ * type
+ */
+static int
+pr_seqof(head, parm, p, mod)
+PE      head;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+    tpe    *start;             /* first entry in list */
+    int     dflt = 0;
+    char    *nparm;
+
+    if (p->pe_type != SEQOF_START && p->pe_type != SSEQOF_START)
+       return pepsylose (mod, p, head, "pr_seqof:missing SEQOF_START");
+
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    start = p;
+
+    pe = first_member(head);
+    while (pe != NULLPE) {
+       while (p->pe_type != PE_END) {
+
+           DLOG (psap_log, LLOG_DEBUG, ("pr_seqof type %d", p->pe_type));
+
+           if (ISDTYPE(p) && CHKTAG(mod, p, pe) == 0) {
+               if (DEFAULT(p)) {
+                   if (setdval(p, FDFLT_B(p), parm, mod) == NOTOK)
+                       goto bad;
+                   goto next;
+               } else if (OPTIONAL(p)) {
+                   if (ALLOC_MEM(p, parm))
+                       fix_mem(parm, p);
+                   goto next;
+               } else
+                   return pepsylose (mod, p, pe,
+                                     "pr_seqof:missing mandatory parameter");
+           }
+           switch (p->pe_type) {
+           case FREE_ONLY:     /* the next entry(s) only for freeing routines 
+                            * so skip this and next entry
+                            */
+               break;
+           
+           case FFN_CALL:      /* call function to free - skip this here */
+               break;
+
+           case UCODE:
+               if (mod->md_ducode == NULLIFP
+               || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+                   goto bad;
+               break;
+
+           case BOPTIONAL:
+               if (pe == NULLPE || CHKTAG(mod, p + 1, pe) == 0) {
+                   if (ALLOC_MEM(p, parm))
+                       fix_mem(parm, p);
+                   if (IF_USELECT(p)) {
+                       if (p -> pe_ucode >= 0 &&
+                           (mod -> md_ducode == NULLIFP ||
+                            (*mod->md_ducode)(parm, pe, p, 0) == NOTOK))
+                           goto bad;
+                   }
+                   else CLR_OPT_PRESENT(p, parm);
+                   goto next;
+               }
+               if (IF_USELECT(p)) {
+                   if (p -> pe_ucode >= 0 &&
+                       (mod -> md_ducode == NULLIFP ||
+                        (*mod->md_ducode)(parm, pe, p, 1) == NOTOK))
+                       goto bad;
+               }
+               else SET_OPT_PRESENT(p, parm);
+               p++;
+               continue;
+
+           case ETAG:
+               if (pr_type(1, pe, parm, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case MEMALLOC:
+               if (*parm)
+                   break;      /* already allocated */
+               if ((*(parm) = (char *) calloc(1, (unsigned ) p->pe_tag))
+                       == NULLCP)
+                   return oom(mod, p);
+               break;
+
+           case SCTRL:
+               parm = (char **) ((char *) *parm + p->pe_ucode);
+               break;
+
+           case SEQ_START:
+               if (pr_seq(pe, (char **) (*parm + p->pe_ucode), p, mod) ==NOTOK)
+               goto bad;
+               break;
+
+           case SEQOF_START:
+               if (pr_seqof(pe, (char **) (*parm + p->pe_ucode), p,mod)==NOTOK)
+                   goto bad;
+               break;
+
+           case SET_START:
+               if (pr_set(pe, (char **) (*parm + p->pe_ucode), p, mod) ==NOTOK)
+                   goto bad;
+               break;
+
+           case SETOF_START:
+               if (pr_setof(pe, (char **)(*parm + p->pe_ucode), p, mod)==NOTOK)
+                   goto bad;
+               break;
+
+           case SOBJECT:
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (pr_obj(1,pe, &nparm, mod->md_dtab[p->pe_tag]+1, mod)==NOTOK)
+                       goto bad;
+               } else if (pr_obj(1,pe, parm, mod->md_dtab[p->pe_tag]+1, mod)==NOTOK)
+                       goto bad;
+               break;
+
+           case OBJECT:
+               if (pr_obj(1, pe, (char **) (*parm + p->pe_ucode),
+                       mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case SCHOICE_START:
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (pr_choice(pe, &nparm, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case CHOICE_START:
+               if (pr_choice(pe, (char **)(*parm + p->pe_ucode), p,mod)==NOTOK)
+                   goto bad;
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p, pe, "pr_seqof: missing EXTMOD");
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                         (char **) 0, &nparm) == NOTOK)
+                         goto bad;
+               } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                         (char **) 0, parm) == NOTOK)
+                         goto bad;
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD) 
+                   return pepsylose (mod, p, pe, "pr_seqof: missing EXTMOD");
+
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                     (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                     goto bad;
+               break;
+
+           default:
+               if (pr_type(1, pe, parm, p, mod) == NOTOK)
+                   goto bad;
+               break;
+           }
+
+           if (ISDTYPE(p) && dflt == 0)
+               pe = next_member(head, pe);
+    next:
+           if (NEXT_TPE(p) == NULLTPE)
+               goto bad;
+       }
+       parm = (char **) (*parm + p->pe_ucode);
+       p = start;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse a setof, calling appropriate routines to parse each sub type
+ */
+static int
+pr_setof(head, parm, p, mod)
+PE      head;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+    tpe    *start;
+    char       *nparm;
+
+    if (p->pe_type != SETOF_START && p->pe_type != SSETOF_START)
+       return pepsylose(mod, p, head, "pr_setof: missing SETOF_START");
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    start = p;
+    pe = first_member(head);
+
+    for (pe = first_member(head); pe; pe = next_member(head, pe)) {
+       while (p->pe_type != PE_END) {
+           DLOG (psap_log, LLOG_DEBUG, ("pr_setof type %d", p->pe_type));
+
+           if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
+               if (DEFAULT(p)) {
+                   if (setdval(p, FDFLT_B(p), parm, mod) == NOTOK)
+                       goto bad;
+                   goto next;
+               } else
+                   return pepsylose (mod, p, pe,
+                                     "pr_setof:missing mandatory parameter");
+           }
+
+           switch (p->pe_type) {
+           case FREE_ONLY:     /* the next entry(s) only for freeing routines 
+                            * so skip this and next entry
+                            */
+               break;
+           
+           case FFN_CALL:      /* call function to free - skip this here */
+               break;
+
+           case UCODE:
+               if (mod->md_ducode == NULLIFP
+               || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+                   goto bad;
+               break;
+
+           case BOPTIONAL:
+               if ((pe = setpresent(head, p + 1, mod)) == NULLPE) {
+                   if (ALLOC_MEM(p, parm))
+                       fix_mem(parm, p);
+                   if (IF_USELECT(p)) {
+                       if (p -> pe_ucode >= 0 &&
+                           (mod -> md_ducode == NULLIFP ||
+                            (*mod->md_ducode)(parm, pe, p, 0) == NOTOK))
+                           goto bad;
+                   }
+                   else CLR_OPT_PRESENT(p, parm);
+                   goto next;
+               }
+               if (IF_USELECT(p)) {
+                   if (p -> pe_ucode >= 0 &&
+                       (mod -> md_ducode == NULLIFP ||
+                        (*mod->md_ducode)(parm, pe, p, 1) == NOTOK))
+                       goto bad;
+               }
+               else SET_OPT_PRESENT(p, parm);
+               p++;
+               continue;
+
+           case ETAG:
+               if (pr_type(1, pe->pe_cons, parm, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case MEMALLOC:
+               if (*parm)
+                   break;      /* already allocated */
+               if ((*(parm) = (char *) calloc(1, (unsigned )p->pe_tag))
+                       == NULLCP)
+                   return oom(mod, p);
+               break;
+
+           case SCTRL:
+               parm = (char **) (*parm + p->pe_ucode);
+               break;
+
+           case SEQ_START:
+               if (pr_seq(pe, (char **) (*parm + p->pe_ucode), p, mod) ==NOTOK)
+                   goto bad;
+               break;
+
+           case SEQOF_START:
+               if (pr_seqof(pe, (char **)(*parm + p->pe_ucode), p, mod)==NOTOK)
+                   goto bad;
+               break;
+
+           case SET_START:
+               if (pr_set(pe, (char **) (*parm + p->pe_ucode), p, mod) ==NOTOK)
+                   goto bad;
+               break;
+
+           case SETOF_START:
+               if (pr_setof(pe, (char **)(*parm + p->pe_ucode), p, mod)==NOTOK)
+                   goto bad;
+               break;
+
+           case SOBJECT:
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (pr_obj(1, pe, &nparm, mod->md_dtab[p->pe_tag]+1, mod)==NOTOK)
+                       goto bad;
+               } else if (pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag]+1, mod)==NOTOK)
+                       goto bad;
+               break;
+
+           case OBJECT:
+               if (pr_obj(1, pe, (char **) (*parm + p->pe_ucode),
+                       mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case SCHOICE_START:
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (pr_choice(pe, &nparm, p, mod) == NOTOK)
+                       goto bad;
+               } else if (pr_choice(pe, parm, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case CHOICE_START:
+               if (pr_choice(pe, (char **)(*parm + p->pe_ucode), p,mod)==NOTOK)
+                   goto bad;
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p, pe, "pr_setof: missing EXTMOD");
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI,
+                         (int *) 0, (char **) 0, &nparm) == NOTOK)
+                         goto bad;
+               } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI,
+                         (int *) 0, (char **) 0, parm) == NOTOK)
+                         goto bad;
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p, pe, "pr_setof: missing EXTMOD");
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI,
+                     (int *) 0, (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                     goto bad;
+               break;
+
+           default:
+               if (pr_type(1, pe, parm, p, mod) == NOTOK)
+                   goto bad;
+               break;
+           }
+
+    next:
+           if (NEXT_TPE(p) == NULLTPE)
+               goto bad;
+       }
+       parm = (char **) (*parm + p->pe_ucode);
+       p = start;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * parse a choice field. This means find which choice is taken
+ */
+static int
+pr_choice(head, parm, p, mod)
+PE      head;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    int    *poffset;
+    int     cnt;
+    tpe    *savep = NULLTPE;
+
+    if (p->pe_type != CHOICE_START && p->pe_type != SCHOICE_START)
+       return pepsylose (mod, p, head, "pr_choice:missing CHOICE_START");
+
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    if (p->pe_type == MEMALLOC) {
+           if (*parm == NULLCP) {
+               /* not already allocated */
+               if ((*(parm) = (char *) calloc(1,(unsigned )p->pe_tag))==NULLCP)
+                   return oom(mod, p);
+           }
+       p++;
+    }
+    if (p->pe_type == SCTRL) {
+       if (IF_USELECT(p)) {
+           savep = p;
+       } else if ((poffset = (int *) (*parm + p->pe_ucode)) == NULL)
+           goto bad;
+       p++;
+    }
+    for (cnt = 1; p->pe_type != PE_END; NEXT_TPE(p)) {
+       if (ISDTYPE(p)) {
+           if (ismatch(p, mod, head->pe_class, head->pe_id)) {
+               if (!savep && poffset)
+                   *poffset = cnt;
+               if (pr_etype(head, parm, p, mod) == NOTOK)
+                   goto bad;
+               if (savep) {
+                   if (savep -> pe_ucode >= 0  &&
+                       (mod -> md_ducode == NULLIFP ||
+                        (*mod -> md_ducode)(parm, head, savep, cnt) == NOTOK))
+                       goto bad;
+               }
+               NEXT_TPE(p);
+               if (p->pe_type == UCODE) {
+                   if (mod->md_ducode == NULLIFP
+                   || (*mod->md_ducode) (parm, head, p, 0) == NOTOK)
+                       return (NOTOK);
+               }
+               return (OK);
+           }
+           cnt++;
+       }
+    }
+    (void) pepsylose(mod, p, head, "pr_choice: no choice taken");
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse a single type for explicit tag If a basic type parse it, if
+ * a compound type call the appropriate parsing routine
+ */
+static int
+pr_etype(pe, parm, p, mod)
+PE      pe;
+char   **parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+{
+    int cnt;
+    char    *nparm;
+
+    switch (p->pe_type) {
+    case PE_END:
+    case PE_START:
+       return pepsylose (mod, p, pe, "pr_etype:illegal END/START");
+
+    case FREE_ONLY:    /* the next entry(s) only for freeing routines 
+                    * so skip this and next entry
+                    */
+       break;
+    
+    case FFN_CALL:     /* call function to free - skip this here */
+       break;
+
+    case UCODE:
+       if (mod->md_ducode == NULLIFP
+           || (*mod->md_ducode) (parm, pe, p, 0) == NOTOK)
+           goto bad;
+       break;
+
+    case BOPTIONAL:
+       return pepsylose (mod, p, pe, "pr_etype:illegal BOPTIONAL");
+       
+    case ETAG:
+       switch (p->pe_ucode) {
+
+       default:
+           p++;
+           if (pr_etype(pe->pe_cons, parm, p, mod) == NOTOK)
+               goto bad;
+       }
+       break;
+
+    case MEMALLOC:
+       if (*parm)
+           break;      /* already allocated */
+       if ((*(parm) = (char *) calloc(1, (unsigned ) p->pe_tag)) == NULLCP)
+           return oom(mod, p);
+       break;
+
+    case SEQ_START:
+       if (pr_seq(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSEQOF_START:
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (pr_seqof(pe, &nparm, p, mod) == NOTOK)
+               goto bad;
+       } else if (pr_seqof(pe, parm, p, mod) == NOTOK)
+               goto bad;
+       break;
+
+    case SEQOF_START:
+       if (pr_seqof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSEQ_START:
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (pr_seq(pe, &nparm, p, mod) == NOTOK)
+               goto bad;
+       } else if (pr_seq(pe, parm, p, mod) == NOTOK)
+               goto bad;
+       break;
+
+    case SET_START:
+       if (pr_set(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSET_START:
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (pr_set(pe, &nparm, p, mod) == NOTOK)
+               goto bad;
+       } else if (pr_set(pe, parm, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SETOF_START:
+       if (pr_setof(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSETOF_START:
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (pr_setof(pe, &nparm, p, mod) == NOTOK)
+               goto bad;
+       } else if (pr_setof(pe, parm, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case IMP_OBJ:
+       p++;
+       if (p->pe_type == EXTOBJ) {
+           if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *) 0,
+                 (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+                 goto bad;
+       } else if (p->pe_type == SEXTOBJ) {
+           if (p->pe_ucode > 0) {
+               if (*parm == NULLCP)
+                   return inpm(mod, p);
+               nparm = *parm + p->pe_ucode;
+               if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *) 0,
+                     (char **) 0, (char **) &nparm) == NOTOK)
+                     goto bad;
+           } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0|F_CI, (int *) 0,
+                     (char **) 0, (char **) parm) == NOTOK)
+                     goto bad;
+       } else {
+           if (p->pe_type == SOBJECT) {
+               if (p->pe_ucode > 0) {
+                   if (*parm == NULLCP)
+                       return inpm(mod, p);
+                   nparm = *parm + p->pe_ucode;
+                   if (pr_obj(0, pe, (char **)&nparm, mod->md_dtab[p->pe_tag]+1, mod)==NOTOK)
+                       goto bad;
+               } else if (pr_obj(0, pe, (char **)parm, mod->md_dtab[p->pe_tag]+1, mod)==NOTOK)
+                       goto bad;
+           } else if (pr_obj(0, pe, (char **) (*parm + p->pe_ucode),
+                   mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+               goto bad;
+       }
+       break;
+
+    case SOBJECT:
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (pr_obj(1, pe, &nparm, mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+               goto bad;
+       } else if (pr_obj(1, pe, parm, mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case OBJECT:
+       if (pr_obj(1, pe, (char **) (*parm + p->pe_ucode),
+               mod->md_dtab[p->pe_tag] + 1, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SCHOICE_START:
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (pr_choice(pe, &nparm, p, mod) == NOTOK)
+               goto bad;
+       } else if (pr_choice(pe, parm, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case CHOICE_START:
+       if (pr_choice(pe, (char **) (*parm + p->pe_ucode), p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SEXTOBJ:
+       if (p[1].pe_type != EXTMOD)
+           return pepsylose (mod, p, pe, "pr_etype: missing EXTMOD");
+       if (p->pe_ucode > 0) {
+           if (*parm == NULLCP)
+               return inpm(mod, p);
+           nparm = *parm + p->pe_ucode;
+           if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                 (char **) 0, &nparm) == NOTOK)
+                 goto bad;
+       } else if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+                 (char **) 0, parm) == NOTOK)
+             goto bad;
+       break;
+
+    case EXTOBJ:
+       if (p[1].pe_type != EXTMOD)
+           return pepsylose (mod, p, pe, "pr_etype: missing EXTMOD");
+
+       if (dec_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 1|F_CI, (int *) 0,
+             (char **) 0, (char **) (*parm + p->pe_ucode)) == NOTOK)
+             goto bad;
+       break;
+
+    case INTEGER:
+       if (pe != NULLPE) {
+           DLOG (psap_log, LLOG_DEBUG, ("pr_etype:integer %d", prim2num(pe)));
+
+           if (((*(integer *)(*parm + p->pe_ucode)) = prim2num(pe)) == NOTOK &&
+               pe->pe_errno != PE_ERR_NONE) 
+               return pepsylose (mod, p, pe, "pr_etype:bad integer %s",
+                                 pe_error(pe->pe_errno));
+       }
+       break;
+
+#ifdef PEPSY_REALS
+    case REALTYPE:
+       if (pe != NULLPE) {
+           DLOG (psap_log, LLOG_DEBUG, ("pr_etype:Real %g", prim2real(pe)));
+
+           if (((*(double *) (*parm + p->pe_ucode)) = prim2real(pe))
+               == NOTOK && pe->pe_errno != PE_ERR_NONE) 
+                 return pepsylose (mod, p, pe, "pr_etype:bad real %s",
+                                   pe_error(pe->pe_errno));
+       }
+       break;
+
+#endif
+
+    case BOOLEAN:
+       if (pe != NULLPE) {
+           int     i;
+
+           DLOG(psap_log, LLOG_DEBUG, ("pr_etype:boolean %d", prim2flag(pe)));
+
+           if ((i = prim2flag (pe)) == NOTOK)
+               return pepsylose (mod, p, pe, "pr_etype:bad integer %s",
+                                 pe_error(pe->pe_errno));
+           (*(char *) (*parm + p->pe_ucode)) = i & 0xff;
+       }
+       break;
+
+    case T_NULL:
+       break;
+
+    case ANY:
+       if (pe != NULLPE) {
+           (*(PE *) (*parm + p->pe_ucode) = pe)->pe_refcnt++;
+           if (pe->pe_errno != PE_ERR_NONE)
+               return pepsylose (mod, p, pe, "pr_etype:bad ANY %s",
+                                 pe_error(pe->pe_errno));
+       }
+       break;
+
+    case SANY:
+       if (pe != NULLPE) {
+           (*(PE *) (parm + p->pe_ucode) = pe) -> pe_refcnt++;
+           if (pe->pe_errno != PE_ERR_NONE)
+               return pepsylose (mod, p, pe, "pr_etype:bad ANY %s",
+                                 pe_error(pe->pe_errno));
+       }
+       break;
+
+    case SOCTETSTRING:
+       if (pe != NULLPE) {
+           if ((*((struct qbuf **) (parm + p->pe_ucode))
+                = prim2qb(pe)) == (struct qbuf *) NULL
+               && pe->pe_errno != PE_ERR_NONE)
+               return pepsylose (mod, p, pe, "pr_etype:bad octet string %s",
+                                 pe_error(pe->pe_errno));
+       }
+       break;
+
+    case OCTETSTRING:
+       if (pe != NULLPE) {
+           if ((*((struct qbuf **) (*parm + p->pe_ucode))
+                = prim2qb(pe)) == (struct qbuf *) NULL
+               && pe->pe_errno != PE_ERR_NONE)
+               return pepsylose (mod, p, pe, "pr_etype:bad octet string %s",
+                                 pe_error(pe->pe_errno));
+       }
+       break;
+
+    case T_STRING:
+       if ((*((char **) (*parm + p->pe_ucode)) = prim2str(pe, &cnt))
+           == NULLCP && pe->pe_errno != PE_ERR_NONE)
+             return pepsylose (mod, p, pe, "pr_type:bad octet string %s",
+                             pe_error(pe->pe_errno));
+       /* undocumented feature of prim2str that it adds a NULL char
+        * to the end of the string
+        */
+       break;
+
+    case OCTET_PTR:
+       if (p[1].pe_type != OCTET_LEN)
+           return pepsylose (mod, &p[1], NULLPE,"pr_etype: missing OCTET_PTR");
+       if ((*((char **) (*parm + p->pe_ucode)) =
+           prim2str(pe, (int *)(*parm + (p + 1)->pe_ucode)))
+           == NULLCP && pe->pe_errno != PE_ERR_NONE)
+             return pepsylose (mod, p, pe, "pr_etype:bad octet string %s",
+                             pe_error(pe->pe_errno));
+       break;
+
+       case BITSTR_PTR:
+           if (p[1].pe_type != BITSTR_LEN)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "pr_etype: missing BITSTR_PTR");
+           pe = prim2bit(pe);
+           if ((*((char **) (*parm + p->pe_ucode)) =
+               bitstr2strb(pe, (int *)(*parm + (p + 1)->pe_ucode)))
+               == NULLCP && pe->pe_errno != PE_ERR_NONE)
+                 return pepsylose (mod, p, pe, "pr_etype:bad bit string %s",
+                                 pe_error(pe->pe_errno));
+           break;
+
+    case SBITSTRING:
+       if (pe != NULLPE) {
+           if (((*(PE *) (parm + p->pe_ucode)) = prim2bit(pe_cpy(pe))) == NULLPE)
+               return pepsylose (mod, p, pe, "pr_etype:out of memory");
+       }
+       break;
+
+    case BITSTRING:
+       if (pe != NULLPE) {
+           if ((*((PE *) (*parm + p->pe_ucode)) = prim2bit(pe_cpy(pe))) == NULLPE)
+               return pepsylose (mod, p, pe, "pr_etype:out of memory");
+       }
+       break;
+
+    case SOBJID:
+       if ((*(OID *) (parm + p->pe_ucode) = oid_cpy(prim2oid(pe))) == NULLOID)
+           return pepsylose (mod, p, pe, "pr_etype:OID: out of memory");
+       break;
+
+    case OBJID:
+       if ((*(OID *) (*parm + p->pe_ucode) = oid_cpy(prim2oid(pe))) == NULLOID)
+           return pepsylose (mod, p, pe, "en_etype:OID: out of memory");
+       break;
+
+    case FN_CALL:
+       if ((FN_PTR(mod, p))(parm, pe) == NOTOK)
+           return pepsylose (mod, p, NULLPE, "pr_etype:FN_CALL:call failed");
+       break;
+
+    default:
+       return pepsylose(mod, p, pe,
+                        "pr_etype: %d not implemented", p->pe_type);
+    }
+
+    return (OK);
+bad:
+    return (NOTOK);
+}
+
+
+/*
+ * determine if the given field is present in the data This is simple
+ * if the field is a simple type with an obvious tag but in the case
+ * of an object or a CHOICE type the tag is not obvious. If the
+ * object is a CHOICE there are more than one possible tag that could
+ * match and in this case we must try to match each one of them.
+ */
+static PE
+setpresent(head, p, mod)
+PE      head;
+tpe    *p;
+modtyp *mod;
+{
+    PE      pe;
+    modtyp     *nmod;
+
+    while (!ISDTYPE(p) && p->pe_type != PE_END) {
+       p++;
+    }
+    if (!ISDTYPE(p) || p->pe_type == PE_END)
+       return (NULLPE);
+
+    switch (p->pe_type) {
+    case EXTOBJ:
+    case SEXTOBJ:
+       /* Needs to be changed for optional and default */
+       nmod = EXT2MOD(mod, (p + 1));
+       return (setpresent(head, p = nmod->md_dtab[p->pe_tag] + 1, nmod));
+
+    case OBJECT:
+    case SOBJECT:
+       /* Needs to be changed for optional and default */
+       return (setpresent(head, p = mod->md_dtab[p->pe_tag] + 1, mod));
+
+    case SCHOICE_START:
+    case CHOICE_START:
+       for (p++; p && p->pe_type != PE_END; p = NEXT_TPE(p)) {
+           if (!ISDTYPE(p))
+               continue;
+           if ((pe = setpresent(head, p, mod)))
+               return (pe);
+       }
+       return (NULLPE);
+
+    default:
+       return (set_find(head, CLASS(p), TAG(p)));
+    }
+}
+
+/*
+ * set the default value to that value in the structure
+ */
+static int
+setdval(typ, dflt, parm, mod)
+tpe    *typ, *dflt;
+char  **parm;
+modtyp *mod;
+{
+    char       *p;
+    integer    i;
+    int                no;     /* number of octets */
+    char       *nparm;
+
+again:
+    switch (typ->pe_type) {
+    case MEMALLOC:
+        if (*parm)
+            break;     /* already allocated */
+
+       if ((*(parm) = (char *) calloc(1, (unsigned ) typ->pe_tag)) == NULL) {
+           (void) pepsylose (mod, typ, NULLPE,
+                             "setdval:calloc failed on %d", typ->pe_tag);
+           return NOTOK;
+       }
+        /* fall through and do the same stuff as for ETAG */
+       
+    case ETAG:
+       typ++;
+       goto again;
+
+    case INTEGER:
+       *(integer *) (*parm + typ->pe_ucode) = IVAL(mod, dflt);
+       break;
+
+#ifdef PEPSY_REALS
+    case REALTYPE:
+       *(double *) (*parm + typ->pe_ucode) = RVAL(mod, dflt);
+       break;
+#endif
+
+    case BOOLEAN:
+       *(char *) (*parm + typ->pe_ucode) = IVAL(mod, dflt);
+       break;
+
+    case T_NULL:
+       /* Only one value */
+       break;
+
+    case SBITSTRING:
+       *(PE *) (parm + typ->pe_ucode) = strb2bitstr(PVAL(mod, dflt), (int )IVAL(mod, dflt), 0, 0);
+       break;
+
+    case BITSTRING:
+       *(PE *) (*parm + typ->pe_ucode) =
+          strb2bitstr(PVAL(mod, dflt), (int )IVAL(mod, dflt), 0, 0);
+       break;
+
+    case SOCTETSTRING:
+       *(struct qbuf **) (parm + typ->pe_ucode) = str2qb(PVAL(mod, dflt),
+           (int )IVAL(mod, dflt), 1);
+       break;
+
+    case OCTETSTRING:
+       *(struct qbuf **) (*parm + typ->pe_ucode) =
+          str2qb(PVAL(mod, dflt), (int )IVAL(mod, dflt), 1);
+       break;
+
+    case T_STRING:
+       *(char **) (*parm + typ->pe_ucode) = strdup(PVAL(mod, dflt));
+       break;
+
+    case OCTET_PTR:
+       if (typ[1].pe_type != OCTET_LEN)
+           return pepsylose (mod, typ, NULLPE, "setdval:missing OCTET_LEN");
+       i = IVAL(mod, dflt);
+       p = smalloc((int )i + 1);
+       bcopy(PVAL(mod, dflt), p, (int )i);
+       p[i] = '\0';
+       *(char **) (*parm + typ->pe_ucode) = p;
+       *(int *) (*parm + (typ + 1)->pe_ucode) = i;
+       break;
+
+    case BITSTR_PTR:
+       if (typ[1].pe_type != BITSTR_LEN)
+           return pepsylose (mod, typ, NULLPE, "setdval:missing BITSTR_LEN");
+       i = IVAL(mod, dflt);
+       no = (i + 7)/8; /* round up */
+       p = smalloc(no + 1);
+       bcopy(PVAL(mod, dflt), p, no);
+       p[no] = '\0';
+       *(char **) (*parm + typ->pe_ucode) = p;
+       *(int *) (*parm + (typ + 1)->pe_ucode) = i;
+       break;
+
+    case OBJECT:
+       if (setdval(mod->md_dtab[typ->pe_tag] + 1, dflt,
+                   (char **) (*parm + typ->pe_ucode), mod) == NOTOK)
+           return NOTOK;
+       break;
+
+    case SOBJECT:
+       if (typ->pe_ucode > 0) {
+           nparm = *parm + typ->pe_ucode;
+           if (setdval(mod->md_dtab[typ->pe_tag] + 1, dflt, &nparm, mod) == NOTOK)
+               return NOTOK;
+       } else if (setdval(mod->md_dtab[typ->pe_tag] + 1, dflt, parm, mod) == NOTOK)
+               return NOTOK;
+       break;
+
+    case IMP_OBJ:
+       typ++;
+
+    case ANY:
+    case SANY:
+    case SEXTOBJ:
+    case EXTOBJ:
+    case OBJID:
+    case SOBJID:
+    case SEQ_START:
+    case SET_START:
+    case -1:                   /* Just use the pepy method of null
+                                * pointers */
+       /*
+        * This is the posy/pepy hack way of doing things at the
+        * moment
+        */
+       *(char **) (*parm + typ->pe_ucode) = NULL;
+       break;
+
+    case FN_CALL:
+       if ((FN_PTR(mod, typ))(parm, NULLPE) == NOTOK)
+           return pepsylose (mod, typ, NULLPE,
+                             "setdval:FN_CALL:call failed");
+       break;
+
+    default:
+       /*
+        * dmp_tpe("setdval: type not implemented", typ, mod); - need
+        * mod
+        */
+       (void) pepsylose(mod, typ, NULLPE,
+                        "setdval: %d not implemented", typ->pe_type);
+       return NOTOK;
+    }
+    return OK;
+}
+/*
+ * fix up the allocation of memory. We have allocated memory for an
+ * optional object that is not present. ISODE routines get upset if
+ * this is present because it then believes the object is present and
+ * tries to process it ...
+ */
+static int
+fix_mem(parm, p)
+char  **parm;
+tpe    *p;
+{
+    if (p->pe_type != SOBJECT || p[-1].pe_type != MEMALLOC
+       || p[1].pe_type != PE_END)
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, ("fix_mem:inconsistency"));
+    if (*parm)
+       free(*parm);
+    *parm = NULL;
+}
diff --git a/src/isode/pepsy/dfns.c b/src/isode/pepsy/dfns.c
new file mode 100644 (file)
index 0000000..cf72afc
--- /dev/null
@@ -0,0 +1,248 @@
+/* dfns.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:53  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:07  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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((unsigned)strlen(s) + 1)) == NULL)
+       my_error("my_new_str: Out of memory");
+
+    (void) 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((unsigned)(strlen(s1) + strlen(s2) + 1))) == NULL)
+       my_error("my_strcat: Out of memory");
+
+    for (s = s1, t = s3; *s != '\0'; s++, t++)
+       *t = *s;
+    (void) 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 unsigned 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");
+    }
+    (void) strcpy(buf, s1);
+    (void) 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/src/isode/pepsy/doc/DESCRIPTION b/src/isode/pepsy/doc/DESCRIPTION
new file mode 100644 (file)
index 0000000..2f861f5
--- /dev/null
@@ -0,0 +1,1056 @@
+
+
+
+
+
+
+_\b1.  _\bO_\bv_\be_\br_\bv_\bi_\be_\bw _\bo_\bf _\bp_\be_\bp_\bs_\by _\bs_\by_\bs_\bt_\be_\bm
+
+     This  section  describes  how  the  various  parts  fit
+together  to  make  the  system  work.  The principle behind
+pepsy is fairly simple.  The ASN.1 is summarised  as  tables
+of integers.  These tables are read by driver routines which
+encode or decode data to or from the  internal  format  that
+ISODE  OSI implementation uses.  In ISODE specific functions
+are generated for each ASN.1 type defined  in  contrast  the
+pepsy  merely generates a new table of data which is far far
+smaller.
+
+     As there is a great deal  of  effort  invested  in  the
+ISODE  interface  to  the  encoding/decoding  routines pepsy
+automatically provides macros which map the  original  func-
+tions  into the appropriate function call of a driver.  This
+allows existing posy using code to switch to the pepsy  sys-
+tem  with  no  changes  to  the  code  provided  no function
+pointers are used to the  original  ISODE  functions.   Even
+when  there  are function pointers used the changes are very
+simple and take only a few hours to implement.
+
+_\b1._\b1.  _\bB_\br_\bi_\be_\bf _\bd_\be_\bs_\bc_\br_\bi_\bp_\bt_\bi_\bo_\bn _\bo_\bf _\bt_\bh_\be _\bu_\bs_\be _\bo_\bf _\bt_\bh_\be _\bp_\be_\bp_\bs_\by _\bs_\by_\bs_\bt_\be_\bm.
+
+_\b1._\b1._\b1.  _\bO_\bu_\bt_\bl_\bi_\bn_\be _\bo_\bf _\bt_\bh_\be _\bf_\bi_\bl_\be_\bs _\bp_\br_\bo_\bd_\bu_\bc_\be_\bd _\bu_\bn_\bd_\be_\br _\bt_\bh_\be  _\bp_\be_\bp_\bs_\by  _\bs_\by_\bs_\b-
+_\bt_\be_\bm.
+
+     The pepsy system consists  of  a  program  called  _\bp_\bo_\bs_\by
+which  translates ASN.1 modules into a set of tables, called
+_\bp_\bo_\bs_\by at the moment, and library of driver  routines,  called
+_\bl_\bi_\bb_\bp_\be_\bp_\bs_\by._\ba.   Running  this  _\bp_\bo_\bs_\by  program on the ASN.1 file
+will produce several files.  If the name of the ASN.1 module
+is MODULE the following files are generated:
+
+MODULE-types.h
+     which contains C structure definitions.   The  user  of
+     the  library  provides data as a linked list of these C
+     data structures and expects to receive data back  as  a
+     similar linked list.  These data structures are exactly
+     the same as those produced by the original  ISODE  _\bp_\bo_\bs_\by
+     so that existing software written for the old _\bp_\bo_\bs_\by pro-
+     gram needs no change.  For details on the C data struc-
+     tures types generated see the documentation of the ori-
+     ginal _\bp_\bo_\bs_\by program in volume 4 Chapter 5 of  the  ISODE
+     manuals.
+
+MODULE_tables.c
+     This file contains the tables generated by the new _\bp_\bo_\bs_\by
+     program.   These  tables  consist  of  three parts, the
+     first which contains the summary of ASN.1 types.   Each
+     type  is  summarised  as  an array of a primitive type,
+     struct pte, for encoding and decoding, and struct  ptpe
+     for  printing.   As implied there is one array for each
+     type for each of encoding,  decoding  and  printing  as
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 2 -
+
+
+     specified  when _\bp_\bo_\bs_\by is run.  The next part contains up
+     to three tables of pointers to these arrays.   Each  of
+     the three different types of arrays, encoding, decoding
+     and printing, has its own table of  pointers.   Finally
+     there is the module type definition which contains con-
+     tains pointers to these tables and  some  other  useful
+     information  about  the  module such as its name.  This
+     module type structure, which is typedefed to modtyp, is
+     the only piece of data which is global, all the rest of
+     the data is static and is only addressable via the mod-
+     typ  data  structure.  This  provides  a kind of object
+     oriented approach to handling the tables.  Once you are
+     passed a pointer to an ASN.1's modtyp structure you can
+     encode, decode and print any of its  types  by  calling
+     the   appropriate  libpepsy.a  routine  with  its  type
+     number.
+
+MODULE_pre_defs.h
+     This file contains #defines symbol of each of the ASN.1
+     types  to its type number, which is used when calling a
+     libpepsy.a routine.  Each symbol  is  _Ztype-nameMODULE
+     where _\bt_\by_\bp_\be-_\bn_\ba_\bm_\be is the name of the type with dashes (-)
+     turned into underscores (_) and _\bM_\bO_\bD_\bU_\bL_\bE is the  name  of
+     the  module.   For  example of the ASN.1 universal type
+     _\bG_\br_\ba_\bp_\bh_\bi_\bc_\bS_\bt_\br_\bi_\bn_\bg would  have  the  #define  symbol  _ZGra-
+     phicStringUNIV.  The __\bZ is prepended to try to make the
+     symbols unique.  This file  also  contains  and  extern
+     declaration for the modtyp data for its module.
+
+MODULE_defs.h
+     This file contains macros for  all the encoding, decod-
+     ing  and printing functions that the _\bp_\be_\bp_\by program would
+     have for these ASN.1 types.  This allows  much  of  the
+     code  that  uses  the routines generated by running the
+     old _\bp_\bo_\bs_\by program and taking its output and running _\bp_\be_\bp_\by
+     on  augmented ASN.1 output can be recompiled unchanged.
+     If the code used pointers  to  these  functions  it  is
+     necessary  to change it to pass around the type numbers
+     instead and to call  appropriately  call  a  libpepsy.a
+     library  routine  with the type number.  As pointers to
+     the printing routines in ISODE are passed as  arguments
+     a  #define  is  provided  to turn the argument into the
+     pair of arguments, type number and  pointer  to  modtyp
+     structure,  which  are  needed  to allow the diagnostic
+     printing code to work with no change  for  the  current
+     ISODE stack.  This file also contains a #include of the
+     _\bM_\bO_\bD_\bU_\bL_\bE__\bp_\br_\be__\bd_\be_\bf_\bs._\bh file.
+
+     As the _\bM_\bO_\bD_\bU_\bL_\bE-_\bt_\by_\bp_\be_\bs._\bh file #include's the _\bM_\bO_\bD_\bU_\bL_\bE__\bd_\be_\bf_\bs._\bh
+file  no  further  #includes  need  to be added to the files
+using the encoding/decoding/printing functions.  This  means
+that code written to use posy/pepy system may need no change
+at all and  the  only  effort  required  is  to  change  the
+Makefile  to use the pepsy system.  If there is code changes
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 3 -
+
+
+required it would most likely be because  function  pointers
+are  used  to reference the functions generated by posy.  If
+only the _\bp_\be_\bp_\by system was used, not posy then pepy, with code
+placed inside action statements then quite a large amount of
+work may be needed to change over to the new system, depend-
+ing on how large and complex the _\bp_\be_\bp_\by module is.
+
+_\b1._\b1._\b2.  _\bO_\bu_\bt_\bl_\bi_\bn_\be _\bo_\bf _\bt_\bh_\be _\bp_\be_\bp_\bs_\by _\bl_\bi_\bb_\br_\ba_\br_\by.
+
+enc.cThis contains the routines that encode data from the  C
+     data  structures into ISODE's PElement linked list data
+     structure which it uses for all presentation data.  The
+     most  important  function to pepsy users is enc_f which
+     called to encode a particular type.  It is  passed  the
+     type  number and a pointer to modtyp structure for that
+     module and then the rest of  the  arguments  which  are
+     passed  to  an  encode  function generated by _\bp_\bo_\bs_\by/_\bp_\be_\bp_\by
+     system.  See the documentation in Volume 4, "The Appli-
+     cations  Cookbook",  Section  6.4 called "Pepy Environ-
+     ment".  Most of these  latter  arguments  are  ignored,
+     only parm and pe, are used.
+
+     Contrary to what the  ISODE  documentation  says  these
+ignored  parameters  are  hardly ever used by existing code.
+We have not found a single case where used  for  encoding  a
+named type, which is all that the user can reference anyway,
+so we don't see  any  problems  with  ignoring  these  other
+parameters.   Hopefully  one  day  they  can  be thrown away
+entirely, until then they are actually passed the the encod-
+ing function.
+
+     The rest of the functions are mostly recursive routines
+which  encode a particular type of table entry.  For example
+SEQUENCE is encoded by en_seq which may call itself or  oth-
+ers  to  encode  the  types  from which it is built up.  The
+function en_type builds up a simple type and en_obj  encodes
+a  new  type (object) and so on with other functions.  There
+are a few utility routines in the file such  as  same  which
+determines  whether  the  value  is  the same as the default
+value also.
+
+dec.cThis file contains the decoding routines that translate
+     presentation data into C data structures defined in the
+     MODULE-types.h is like _\be_\bn_\bc._\bc.  It is very much like the
+     file _\be_\bn_\bc._\bc except the routines do the reverse tasks The
+     routines are structured in a very similar way.  We have
+     dec_f  which is called by the user to decode a type and
+     like enc_f takes the same  arguments  as  the  decoding
+     functions  generated  by  _\bp_\bo_\bs_\by  with two additions, the
+     type number and a pointer to the modtyp  structure  for
+     that  module.   Likewise  the  other functions are very
+     much like those of enc.c
+
+prnt.cThis  file  contains  the  routines  that  print   the
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 4 -
+
+
+     presentation data in a format similar to that generated
+     by  _\bp_\be_\bp_\by's  printing  functions.   It's  main  function
+     prnt_f  is  takes  the  same  arguments as the printing
+     function generated by _\bp_\be_\bp_\by as well as the now  familiar
+     type  number  and  modtyp  pointer.   The functions are
+     modeled on the decoding routines as it has similar  job
+     to.  The only difference is that instead of storing the
+     decoded data into a  C  data  structure  it  is  nicely
+     printed out.
+
+fr.c This file contains code to  free  the  data  structures
+     defined  in MODULE-types.h.  Likewise if the -f flag is
+     given when generating the types file it  also  includes
+     macros  in  the  types  file  which replace the freeing
+     functions generated by ISODE's _\bp_\bo_\bs_\by.  The function that
+     the  user calls us fre_obj which takes a pointer to the
+     data structure, its decoding table entry and a  pointer
+     to  the modtyp structure for the module. The freeing is
+     based on the decoding routines except instead of decod-
+     ing  all  it  does is free each part of the data struc-
+     ture, which might  involve  recursive  calls,  then  it
+     frees the data structure at the end.
+
+util.cThis contains the utility routines used by  more  than
+     one of the above files.  This is mostly diagnostic rou-
+     tines at the moment, more  general  routines  could  be
+     included  in  here.  If there is an error at the moment
+     which it can't recover from it just prints out  a  mes-
+     sage on standard error and calls exit.  Not perfect and
+     this is something that will need work.
+
+main.cThis contains code to perform a series of tests on the
+     _\bp_\be_\bp_\bs_\by  library  which  is a useful check to see whether
+     any of the routines has  been  broken  by  any  changes
+     made.   It  basically  loops  through a whole series of
+     test cases.  Each test case is encoded from some  built
+     in test data and then decoded and checked to see if the
+     data has changed in the transfer.  If  it  is  compiled
+     with  -_\bD_\bP_\bR_\bN_\bT=_\b1  the encoded data is also printed out to
+     check the printing  routines  which  generates  a  vast
+     amount  of  output.  Finally the free routines are used
+     to  free  the  allocated  data,  although  it  can  not
+     directly  check  the free routines to see if they work,
+     it can be used with a malloc tracing package  to  check
+     that the routines work.
+
+test_table.h
+     This contains the test cases that _\bm_\ba_\bi_\bn._\bc program  runs.
+     Each  entry in the table corresponds to a type.  One of
+     the fields is count of how many times that type  is  to
+     be tested to try out the different possibly data values
+     it might have.
+
+pep.h and pepdefs.h
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 5 -
+
+
+     These files contain the definition of  types  used  for
+     the  tables  that  drive the encoding/decoding/printing
+     routines.  All the constants used  in  that  table  are
+     defined  here  via  #defines.   The modtyp structure is
+     defined in _\bp_\be_\bp_\bd_\be_\bf_\bs._\bh.
+
+t1.py and t2.py
+     These are test ASN.1 modules that are  used  by  _\bm_\ba_\bi_\bn._\bc
+     routines  to  check  the _\bp_\be_\bp_\bs_\by library.  The file _\bt_\b1._\bp_\by
+     contains the majority of different types with a few  of
+     a  different module provided in _\bt_\b2._\bp_\by.  This allows the
+     testing of the code for handling ASN.1 external  refer-
+     ences,  i.e.  references  to  types  defined  in other,
+     external, modules.
+
+_\b1._\b1._\b3.  _\bN_\be_\bw _\bf_\bi_\bl_\be_\bs _\bi_\bn _\bt_\bh_\be _\bp_\be_\bp_\by _\bd_\bi_\br_\be_\bc_\bt_\bo_\br_\by
+
+etabs.c, dtabs.c and ptabs.c
+     These  files  contain  the   code   to   generate   the
+     encoding/decoding/printing tables.  The main routine in
+     _\be_\bt_\ba_\bb_\bs._\bc is tenc_typ which is called on each ASN.1  type
+     to  generate  an array of entries which describe how to
+     encode that type.  See the  details  section  for  more
+     information  about  how  the  table  entries  function.
+     Similarly _\bd_\bt_\ba_\bb_\bs._\bc contains the routine  tdec_typ  which
+     is  called  on each type to generate its decoding table
+     entries.   Likewise  tprnt_typ  routine  generates  the
+     arrays  of table entries for the printing tables.  This
+     function is in _\bp_\bt_\ba_\bb_\bs._\bc.
+
+dfns.cThis file contains miscellaneous string handling  rou-
+     tines  and hash table routines that don't really belong
+     anywhere else.  Some of the routines could  be  cleaned
+     up in that they tend not to free memory they use.
+
+mine.hThis  file  contains  the  definitions  for  the  hash
+     table(s)  that  are  used  to  keep  track of the ASN.1
+     types.  This could probably be done  with  out  a  hash
+     table,  should  anyone want to clean this up, feel wel-
+     come.  The lookup function is in _\bd_\bf_\bn_\bs._\bc.
+
+pass2.h
+     This file has most of the #defines for the  table  gen-
+     erating  program.  Most of the prefixes and suffixes of
+     function names and files names  are  defined  here  so,
+     hopefully,  the names can be changed by merely changing
+     the definition.  This contains most  of  the  important
+     definitions  needed  by the changes to the _\bp_\bo_\bs_\by program
+     needed to generate tables.
+
+posy.hThis contains the definition of a symbol which is  now
+     needed  outside  of  the  the main routine and the yacc
+     file.  By putting it here we can include  it  any  file
+     that  needs  to  know  it  with out putting in any that
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 6 -
+
+
+     doesn't need it and with out including  all  the  other
+     definitions  that  occur  in _\bp_\be_\bp_\by._\bh.  The structure and
+     meaning of the tables generated from the ASN.1 grammar
+
+     Each collection of ASN.1 grammar is  called  a  module.
+(See  ASN.1  )  Each ASN.1 module is completely specified in
+the program by a single C structure of type modtyp  and  the
+data  which  it  references.   See the _\bp_\be_\bp_\bd_\be_\bf_\bs._\bh file in the
+_\bp_\be_\bp_\bs_\by directory.  For each  ASN.1  module  there  are  three
+tables that are generated fromASN.1 grammar.  These initial-
+ised arrays which we call tables are  called  the  encoding,
+decoding  and  printing  tables.   Each  of  these tables is
+referenced through a different pointer of the modtyp  struc-
+ture.
+
+     Each of these pointers references an array of pointers,
+one  pointer for each ASN.1 type defined in the module.  The
+position of one of these pointers is the unique type  number
+we  give  to its corresponding type.  The pointer references
+an array of type tpe or ptpe, depending  whether  it  is  an
+entry  in  the  decoding/encoding  tables or printing tables
+respectively.  See _\bp_\be_\bp._\bh in the _\bp_\be_\bp_\bs_\by directory.  This array
+actually    contains    the    necessary    information   to
+encode/decode/print that ASN.1 type.  So  given  the  modtyp
+structure  of  an  ASN.1  module and its type number you can
+call a routine to encode, decode or print that type.
+
+     The rest of this document assumes a good  knowledge  of
+ASN.1  notation  so  go  read a copy if you haven't already.
+From here on I shall mention only tpe and this means tpe  in
+the  case  of  encoding  or decoding and ptpe in the case of
+printing, unless otherwise stated.  Each type is represented
+by  an  array of tpe (or ptpe for printing).  The basic ele-
+ment consists of four integer fields, the printing table  is
+the  same with an addition char pointer field which contains
+the name corresponding to that entry in the  ASN.1  grammar.
+The first specifies the type of the entry and determines how
+the rest are interpreted.  The possible types are listed  in
+_\bp_\be_\bp_\bs_\by/_\bp_\be_\bp._\bh.   Each  type  is  an array which starts with an
+entry of type PE_START and ends with  one  of  type  PE_END.
+Each  primitive type requires one entry to specify it, apart
+from possible PE_START and PE_END used to specify the  start
+and end of the type.  Constructed types are represented by a
+list of entries terminated by an entry of type  PE_END.   As
+ASN.1  types can be nested inside so will the representation
+in tpe entries be nested.  For example the ASN.1 type defin-
+ition:
+           Example1 ::=
+                   SEQUENCE {
+                       seq1 SEQUENCE {
+                                an-i INTEGER,
+                                an-ostring OCTET STRING
+                            },
+                       a-bool IMPLICIT [0] BOOLEAN
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 7 -
+
+
+                   }
+              Will generate an encoding array:
+static tpe et_Example1Test[] = {
+        { PE_START, 0, 0, 0 },
+        { SEQ_START, 0, 16, FL_UNIVERSAL },
+        { SEQ_START, OFFSET(struct type_Test_Example1, seq1), 16, FL_UNIVERSAL },
+        { INTEGER, OFFSET(struct element_Test_0, an__i), 2, FL_UNIVERSAL },
+        { OCTETSTRING, OFFSET(struct element_Test_0, an__ostring), 4, FL_UNIVERSAL },
+        { PE_END, 0, 0, 0 },
+        { BOOLEAN, OFFSET(struct type_Test_Example1, a__bool), 0, FL_CONTEXT },
+        { PE_END, 0, 0, 0 },
+        { PE_END, 0, 0, 0 }
+        };
+
+
+     Here the second last PE_END matches and closes off  the
+first  SEQ_START.  The entries which correspond to the other
+primative types are pretty obvious, with the  INTEGER  entry
+corresponding  to  the  primative  INTEGER.  For fields that
+generate data the general interpretation of the other  three
+fields is offset, tag and flags/class fields respectively.
+
+offsetThe second field gives the offset in a C  data  struc-
+     ture  needed  to reference the data that corresponds to
+     this table entry.  Each  ASN.1  type  has  C  structure
+     types  generated  as  described  in  the ISODE manuals,
+     volume 4 "The applications Cookbook" Section 5.2, "POSY
+     Environment".  As this offset may have to be determined
+     in a compiler dependent manner a C  preprocessor  macro
+     is used hide the actual details.
+
+tag  This is the tag associated with the ASN.1 type for that
+     entry.   Notice  that  in  the example the [0] IMPLICIT
+     which changes the tag associated with the BOOLEAN entry
+     actually  has the correct tag of 0 in the table.  Like-
+     wise  SEQUENCE  has  the  correct  tag  of  16  in  its
+     SEQ_START entry and so on for the others.
+
+flags/class
+     This contains  the  ASN.1  class  associated  with  the
+     entry's  type.   That  is  UNIVERSAL for all except the
+     BOOLEAN type which is CONTEXT class.  This  fourth  can
+     also contain flags that specify if the type is OPTIONAL
+     or DEFAULT.  There is plenty of room here as  there  is
+     only four possibly classes.
+
+     Now that you have some idea of  how  these  arrays  are
+arranged  for a type definition I will proceed to go through
+the possible type of entries and describe what they  do  and
+how  they  work.   These  values are defined in _\bp_\be_\bp_\bs_\by/_\bp_\be_\bp._\bh.
+Those entries with a value below TYPE_DATA are entries  that
+don't  correspond  to data to be encoded/decoded and are for
+other book keeping type purposes.
+
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 8 -
+
+
+PE_START and PE_END
+     As explained above PE_START starts the beginning  of  a
+     ASN.1  type's  array.   It probably isn't necessary but
+     the size of the tables is so small it isn't much of  an
+     over  head  to  keep  around for cosmetic reasons.  The
+     entry type PE_END is necessary to mark the end of  some
+     compound type as well as the end of ASN.1 data type.
+
+XOBJECT and UCODE
+     These  are  obsolete  types  and  probably  should   be
+     removed.  They were to allow C code written directly by
+     the user to be incorporated into the  encoding/decoding
+     but  it was found unnecessary.  Prehaps some brave soul
+     would like to use them in an  attempt  to  implement  a
+     similar  system  based  on  _\bp_\be_\bp_\by which is what we first
+     attempted to do until we found this to be much easier.
+
+MALLOCThis field only occurs in  the  decoding  tables.   It
+     specifies  how much space to malloc out for the current
+     C structure it is just inside of.  For instance in  the
+     example  above  the  decoding  table  has the following
+     entry:
+
+      { MALLOC, 0, sizeof (struct type_Test_Example1), 0 },
+
+     just after the first SEQ_START entry.  It tells  it  to
+     malloc  out  a  struct  type_Test_Example1 structure to
+     hold the data from the sequence when it is decoded.
+
+SCTRLThis entry is used in handling the ASN.1  CHOICE  type.
+     The  C type generated for ASN.1 CHOICE type is a struc-
+     ture with an offset field in it and a union of all  the
+     C  types present in the CHOICE.  Each ASN.1 type in the
+     CHOICE of types has a C type definition  generated  for
+     it.   The union is of all these types, which is quite a
+     logical way to implement a  CHOICE  type.   The  offset
+     field  specifies  which possibility of interpreting the
+     union should be used (which  _\bm_\be_\bm_\bb_\be_\br  should  selected).
+     As  such  it  needs to be read by the encoding routines
+     when encoding the data from the C data  structures  and
+     to  be set by the decoding routines when it is decoding
+     the data into the C data structures.  There is one such
+     entry  for each CHOICE type to specify where the offset
+     field is.
+
+CH_ACTAnother redundant entry type.  I think this  was  also
+     used  in  code to handle C statements or actions speci-
+     fied by the user.  It probably should be removed.
+
+OPTL This is used to handle the optionals field that is gen-
+     erated  by posy when optional types that are _\bn_\bo_\bt imple-
+     mented by pointers are present in the ASN.1 type.   For
+     example  if an ASN.1 type has an optional integer field
+     how does the encoding routine determine if the  integer
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 9 -
+
+
+     is  to  be  present or not?  If it was implemented as a
+     pointer it could use a NULL (zero) pointer to mean that
+     the  type was not present because NULL is guaranteed to
+     never occur as a legal pointer to a real  object.   But
+     all  the  possible  values for integer could be legally
+     passed  so  instead  for  these  types  which  are  not
+     pointers and are optional a bit map is allocated in the
+     structure.  Each non pointer optional type a  bit  from
+     the bit map is allocated.
+
+     If that bit is set the corresponding  type  is  present
+and it is not present if the bit is not set.  Each bit has a
+#define generated for it.  The bit map is merely an  integer
+field  called  "optionals"  limiting  maximum number of such
+optionals to 32 on Sun machines, 16  on  some  others.   (An
+array  of char as BSD fd_sets would have avoid all such lim-
+its, not that this limit is expected  to  be  exceeded  very
+often  !)  Like  the SCTRL entry this entry merely serves to
+specify where this field is so it can be test and set by the
+encoding and decoding routines respectively.
+
+ANY and CONS_ANY
+     The C type corresponding to the entry is a PE  pointer.
+     To  conform  with  _\bp_\be_\bp_\by the tag and class of this entry
+     are ignored, which may or may not be the most  sensible
+     thing.   The CONS_ANY is a redundant symbol which means
+     the same thing but is not used.  This should  be  clean
+     up and removed.
+
+INTEGER, BOOLEAN, BITSTRING, OCTETSTRING and OBJID
+     These are just as described in the first article.   See
+     the ISODE manual to find out what they are allocated as
+     a C data type to implement  them.   The  offset  fields
+     says  where  to find this data type with in the current
+     structure.
+
+SET_START, SETOF_START, SEQ_START and SEQOF_START
+     These compound entries differ from the  above  in  that
+     they group all the following entries together up to the
+     matching  PE_END.   The  entries  with   OF   in   them
+     correspond  to  the  ASN.1  types which have OF in them
+     e.g. SET OF.  Allowing the OF items to  have  an  arbi-
+     trary  number of entries is excessive flexibility, they
+     can only have one type by the ASN.1 grammar rules.  The
+     C data type corresponding to them is either a structure
+     if it is the first such type in the array or a  pointer
+     to a structure is isn't.  This complicates the process-
+     ing of these structures a little but not greatly.   The
+     OF types differ one other important way, they may occur
+     zero, one or more times, with no upper bound.  To  cope
+     with  this  the C data type is a linked list structure.
+     The pointer to the data structure determines whether or
+     not  there  is another occurrence of the type, if it is
+     NULL there isn't.  Thus each data  structure  has  this
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 10 -
+
+
+     pointer  to  the  next  occurrence,  the offset of this
+     pointer is placed in the PE_END field where it can con-
+     veniently  be  used to determine whether or not to make
+     another pass through the table entry.
+
+OBJECTWhen one  type  references  another  it  generates  an
+     OBJECT  entry.   This  specifies the type number of the
+     type which is present in  the  3rd  field  of  the  tpe
+     structure,  pe_tag.   The  2nd  field  still  gives the
+     offset in the C data structure  which  specifies  where
+     the  user's data for that type is to be found.  Usually
+     this a pointer to the C data structure for that type.
+
+T_NULLThis entry means the ASN.1 primative  type  NULL.   It
+     doesn't have any body and consequently has no offset as
+     it cannot carry data directly.   Only  its  absence  or
+     presence can mean anything so if it is optional it sets
+     or clears a bit in the bit map as described earlier for
+     OPTL entry.
+
+T_OIDThis use to be used for Object Identifiers and  now  is
+     unused, it should be got rid.
+
+OBJIDThis corresponds to the Object  Identifier  ASN.1  type
+     primitive.   It is implemented the same as other prima-
+     tive types like INTEGER and OCTET STRING.
+
+ETAG This entry gives the  explicit  tag  of  the  following
+     entry.  The usual fields which define class and tag are
+     the only ones which have meaning  in  this  entry.   By
+     concatenating successive ETAG entries it is possibly to
+     build up an limited number explicit tags, although this
+     hasn't been tested yet.
+
+IMP_OBJ
+     If a type has an implicit tag usually all we have to do
+     is  set  its  tag and class appropriately in its entry.
+     This works for all but one important case,  the  refer-
+     ence  of  another type.  This is messy because we can't
+     alter the definition of the type with out  wrecking  it
+     for  the  other  uses.   So  what we do for encoding is
+     build the type normally and then afterward it is  built
+     change  its  tag  and  class  to be the values we want.
+     Similarly for decoding we match the tag  and  class  up
+     and  then  decode the body of the type.  We can't use a
+     OBJECT entry for this because among other reasons there
+     3rd  field  is  already to store the type number.  (The
+     forth needs to be free to contain flags such as DEFAULT
+     and  OPTIONAL) So a new entry type is used, IMP_OBJ, to
+     hold the tag and class.  It  must  be  followed  by  an
+     OBJECT  entry  which is used to handle the type as nor-
+     mal, the IMP_OBJ entry gives the tag and  class  to  be
+     used.   Like  the  ETAG  entry  the IMP_OBJ affects the
+     entry that follows it.
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 11 -
+
+
+EXTOBJ and EXTMOD
+     These handle external type references.   This  is  just
+     like a normal (internal?) type reference except we must
+     now specify which module as well as  the  type.   Simi-
+     larly  because  there  are  no  more free fields in the
+     OBJECT type we need two entries to hold all the  infor-
+     mation  we need.  The EXTMOD occurs first and holds the
+     type number and the offset into the  C  data  structure
+     and  the  flags,  exactly  as for an OBJECT entry.  The
+     next entry, which must be an EXTMOD, contains a pointer
+     to  the modtyp structure for its module.  Like a normal
+     OBJECT entry to handle the case of an implicit  tag  an
+     IMP_OBJ  entry  would  occur  before  these two entries
+     which gives the class and tag.  Likewise it could  have
+     an  explicit tag in which the two entries would be pro-
+     ceeded by an ETAG entry.
+
+DFLT_F and DFLT_B
+     When a type has a default value, to handle decoding and
+     encoding properly you need to know its value.  As there
+     is no space to store the value in most entries we allo-
+     cate a whole entry to specify the value.  When encoding
+     it is convenient to have the default occur  before  the
+     entry it refers to.  This allows a single check to han-
+     dle all the default encoding.  All  it  has  to  do  is
+     check  whether  it is the same as the default value and
+     if so not bother encoding the next type.  On the  other
+     hand  when  decoding  it is more convenient to have the
+     entry after the one it refers to.  In this case we need
+     to  determine  that  it  is  missing  before we use the
+     default value to determine the value  to  pass  to  the
+     user.   To  handle  this we have entries of both types.
+     _\bD_\bF_\bL_\bT__\bF contains the default  value  for  the  following
+     entry  (F  =  Front)  and  DFLT_B contains that for the
+     entry before it (B = Back).   Consequently  DFLT_F  are
+     only used in the decoding tables and DFLT_B entries are
+     only used in the decoding (and printing tables).
+
+S-Types
+     These types are entries for the same ASN.1 type as  the
+     entry  type  formed  by removing the starting `S'.  The
+     above forms would do to handle ASN.1 but we  also  have
+     to  be  compatible with the C data structures generated
+     by _\bp_\bo_\bs_\by.  The implementors decided to  optimise  the  C
+     data  structures  generated  a  little means we have to
+     have all these S type entries.  If a type was a  single
+     field in most cases they produced a #define which elim-
+     inates the need to have a whole structure just for that
+     type.   In  all  the places where this type is used the
+     field of the C structure is changed from a  pointer  to
+     field  which holds the value directly in the structure.
+     See the ISODE reference given above for more details.
+
+     We handle this by generating the same tables that would
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 12 -
+
+
+be generated with out the optimisation, except the optimised
+types the S-type of entries instead of the normal ones.  For
+example  an optimised OCTET STRING would have the type field
+of its entry as SOCTETSTRING instead  of  OCTETSTRING.   The
+only  difference  in how S type and its corresponding normal
+are handle is how they find the C data  structure  for  that
+entry.   That  difference  is  that  there is no indirection
+through pointers.
+
+Flags field
+     Besides the encoding the class the pe_flags field  also
+     contains  a  few  possible  flags.   Mainly FL_OPTIONAL
+     which means the ASN.1 type corresponding to  this  flag
+     is  OPTIONAL.   Consequently  when  encoding  it has to
+     determine if the type is present in the user data  pos-
+     sibly  using  the  bit  map as described under the OPTL
+     entry.  Likewise when decoding it may have to set a bit
+     in  the  bit  map appropriately.  The other flag at the
+     moment is FL_DEFAULT which means the entry  corresponds
+     to  an ASN.1 DEFAULT type.  This bit is still needed as
+     not all types have DFLT_* entries implmented  for  them
+     at  the  moment.   In  particular compound value things
+     like SEQUENCE and SET can't have  thier  default  value
+     specified.   This  is  consistent  with  ISODE, if fact
+     implementing that may even break existing  ISODE  code.
+     This last flag FL_IMPLICIT is obsolete and not not used
+     any where.
+
+
+_\b1._\b2.  _\bW_\ba_\bl_\bk _\bt_\bh_\br_\bo_\bu_\bg_\bh _\bo_\bf _\bp_\be_\bp_\bs_\by _\bl_\bi_\bb_\br_\ba_\br_\by _\br_\bo_\bu_\bt_\bi_\bn_\be_\bs.
+
+     Here we walk through all the pepsy library routines  at
+least  briefly.   If any new routines are added or a routine
+changed this documentation is the most likely part that will
+need changing.  First we give some theory as to how the task
+have have been brocken  into  routines  then  describe  each
+function in detail.  We assume you are familiar with ISODE's
+PE data structure manipulation routines.  if  not  they  are
+documented  in  the  ISODE  manuals,  Volume one, chapter 5,
+"Encoding of Data-Structures" (It actually  covers  decoding
+as well).
+
+_\b1._\b2._\b1.  _\bO_\bv_\be_\br_\bv_\bi_\be_\bw _\bo_\bf _\bp_\be_\bp_\bs_\by _\bl_\bi_\bb_\br_\ba_\br_\by
+
+     Each seperate task is put into a  different  file.   So
+all  the  encoding stuff is in _\be_\bn_\bc._\bc, all the decoding stuff
+is in _\bd_\be_\bc._\bc, printing stuff in _\bp_\br_\bn_\bt._\bc and freeing  stuff  in
+_\bf_\br_\be._\bc.   Actually  it breaks down a little in practice, some
+of the routines for moving around the  tables  are  used  in
+both  _\be_\bn_\bc._\bc  and  _\bd_\be_\bc._\bc  for  example.  Probably they should
+defined in _\bu_\bt_\bi_\bl._\bc so that linking one of the files from  the
+library doesn't force linking any other except _\bu_\bt_\bi_\bl._\bo.
+
+     There is a common structure to each of the major  files
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 13 -
+
+
+as  well.   There  is a main routine which the user calls to
+obtain the services provided by that  file's  routines.   As
+all  the  files  revolve  about processing the table entries
+their structure  is  based  on  running  through  the  table
+entries.
+
+     We shall call each array  of  entries  a  table  or  an
+object.   There  is a routine, usually with a name ending in
+_obj, which is designed to process an object.   For  example
+en_obj is the routine called to generated an encoded object.
+Then there are routines to call on each compound  type  such
+as en_seq for encode a SEQUENCE.  Finally all the primitives
+are handled by a one function that ends in _type.  This lets
+each routine concentrate on handling the features particular
+to its type and call the appropriate routine to handle  each
+type it finds with in its compound type.
+
+     Most of these table processing routines have just three
+arguements: which are called parm, p, mod.  The parm is char
+* or char ** in the encoding and decoding  routines  respec-
+tively.   This points to the user's C structure that data to
+be encoded is taken from when encoding.  When decoding it is
+the address of a pointer which is made to point the C struc-
+ture filled with the decode data.   The  freeing,  which  is
+based  on  the  decoding  routines,  has a char ** while the
+printing routines don't look at the user's data and so don't
+have  such  a  pointer.   The  p points to the current table
+entry we are up to processing and the mod  arguement  points
+to  the  modtyp structure for the current module we are pro-
+cessing.
+
+     All these processing routines return a PE  type,  which
+is  defined  in ISODE's file _\bh/_\bp_\bs_\ba_\bp._\bh, and to return zero if
+they have an error, but not always.  In fact the error  han-
+dling  is needs some work and has not been tested very well.
+Generally it tries to print out the table entry where  some-
+thing went wrong and the name of the function it was in.  It
+then sometimes does an exit which may not be  very  pleasent
+for the user.
+
+_\b1._\b2._\b2.  _\bT_\bh_\be _\be_\bn_\bc_\bo_\bd_\bi_\bn_\bg _\br_\bo_\bu_\bt_\bi_\bn_\be_\bs - _\be_\bn_\bc._\bc
+
+enc_fThis is the the routine made available to the user  for
+     the  encoding  routines.   It  is  fairly  simple as it
+     leaves all the hard things up to other  routines.   All
+     it  does  is  use the type number and modtyp pointer to
+     get a pointer to the  table  for  encoding  that  type.
+     Then  it  calls  the  table or object encoding routine,
+     en_obj, on that object.  It first  does  a  consistency
+     check  of making sure the first entry in the table is a
+     PE_start.  Note that  it  returns  an  integer  (OK  or
+     NOTOK)  instead  of a PE pointer.  This is to be consi-
+     tent with ISODE functions.
+
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 14 -
+
+
+en_objWe loop through the entries until we come to  the  end
+     of the table and then we return the PE we have built up
+     from the user's data which is pointed to by  parm.   In
+     looping through each entry we call the appropriate rou-
+     tine to encode its data.  The default case  is  handled
+     by  calling  en_type which takes care of all the primi-
+     tive types.
+
+     The macro NEXT_TPE sets its arguement to point  to  the
+next type in the table, counting compound types as one type.
+Thus if NEXT_TPE is called on a SET_START it will  skip  all
+the  entries  up  to  and including the matching PE_END.  As
+many objects consist of one compound type and its components
+the  main loop will only be run through once.  Even when the
+object is not based on a compound type it will then  consist
+of  one  simple  type  which  is processed by en_type, again
+probably going through the loop only once.  In fact the only
+way  it can go through the loop more than once is to process
+entries that subsidary to the main type, e.g.  ETAG  entries
+and  things  like  that.   To  double check this is the case
+there is some code that looks for  the  processing  of  more
+than one data generating entry.
+
+     Much of that testing could probably be eliminated  with
+no  loss.   Similarly  prehaps the IMP_OBJ and ETAG could be
+handled by the default action of calling en_type.  As  these
+routines  have  evolved  after many changes there are things
+like that which really need to be looked at  closely  before
+trying.   The comment /*SUPRESS 288*/ means suppress warning
+288 to saber C debugging tool that we use.
+
+en_type
+     This is one of the longest functions as it has so  many
+     cases  to handle.  It again is structure as a loop over
+     the types until PE_END but it actually returns as  soon
+     as  it  has  encoded the next type.  We can now look at
+     the encoding of the primative ASN.1 types in detail.
+
+DFLT_FBecause we have arranged  that  for  encoding  tables,
+     that  we  precede  the entry with a DFLT_F entry we can
+     neatly handle all the default  cases.   All  we  do  is
+     check  if  the  parameter  passed  in the user data, in
+     parm, is the same as the default value specified in the
+     DFLT_F  entry.   The function same performs this check.
+     If it is the same don't encode  anything  just  return,
+     otherwise continue on and encode it.
+
+ETAG To handle explicit tags we merely allocate  a  PE  with
+     the right tag and call en_etype to encode its contents,
+     which are in the following entries.  The switch on  the
+     pe_ucode  field  use to make a difference but now it is
+     meaningless and should be cleaned up.
+
+SEQ_START, SEQOF_START, SET_START, SETOF_START
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 15 -
+
+
+     We merely call the appropriate  function  handle  them.
+     Note  one  _\bi_\bm_\bp_\bo_\br_\bt_\ba_\bn_\bt  difference  in  the  way they are
+     called here from that in enc_obj, the parm arguement is
+     used  as a base to index off and fetch a new pointer to
+     pass the next function.  This seemly bizarre action  is
+     quite  straight forward when seen written as it is nor-
+     mally in C, "parm->offset".  Where the field offset  is
+     a  pointer  which  has  an offset from the start of the
+     structure of p->pe_ucode bytes.
+
+     This is the magic of how we access  all  the  different
+fields  of the C data structures with the one piece of code.
+It is also prehaps the most critical dependency of the whole
+system on the implementation of the C language.  As the BGNU
+C compiler supports this feature then it is compilerable  on
+most machines.  But any porters should pay attention to this
+to ensure that thier  compiler  is  happy  generating  these
+offsets and compiling these casts properly.
+
+     The reason why this is  different  from  the  calls  in
+en_obj  is  that  this is not the first compound type in the
+table.  The first and only the first does not have an offset
+and  does  not  need  to be indirected through any pointers.
+All the compound types inside this type will have  as  their
+field  a  pointer which points to a structure.  From here on
+we shall say _\bi_\bn_\bd_\bi_\br_\be_\bc_\bt_\bi_\bo_\bn  to mean this adding  the  pe_ucode
+field to the pointer to the structure and using it to refer-
+ence a pointer.  Whether to use _\bi_\bn_\bd_\bi_\br_\be_\bc_\bt_\bi_\bo_\bn or not  is  very
+important  matter  that  really  needs  to  be understood to
+understand how the routines are structured.
+
+IMP_OBJ
+     Here we have to handle the case where we can encode the
+     object  then  have  to  change  its tag and class after
+     encoding.  At the end of this entry this is  done  very
+     simply by assigning the right values to the appropriate
+     fields after the object has  been  built.   This  means
+     that if the intermeadiate form is altered this piece of
+     code may have to be altered as well.  There seems to be
+     no better way of handling this.
+
+     The complication in handling this field is the handling
+of  all  the possible types of object.  If it is an external
+object we have to perform a call to enc_f with all the right
+arguements  where  a  normal  OBJECT,  the last else branch,
+requires a normal call to en_obj.  Note the case of  SOBJECT
+is the same as OBJECT _\be_\bx_\bc_\be_\bp_\bt _\bt_\bh_\be_\br_\be _\bi_\bs _\bn_\bo _\bi_\bn_\bd_\bi_\br_\be_\bc_\bt_\bi_\bo_\bn.
+
+SOBJECT and OBJECT
+     Here is the code that handles the two cases  sperately.
+     It  is  exactly as in the IMP_OBJ case except seperated
+     out.  Note the only difference between the two cases is
+     lack of indirection in the SOBJECT case.
+
+
+
+
+                      January 23, 1990
+
+
+
+
+
+                           - 16 -
+
+
+CHOICE_START
+     This is exactly  as  all  other  compound  types,  like
+     SEQ_START  and  OBJECT, we call the appropriate routine
+     with indirection.  From reading the ISODE manuals  that
+     the  ASN.1 CHOICE type is handled by a structure of its
+     own like the other compund types.
+
+EXTOBJ and SEXTOBJ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                      January 23, 1990
+
+
diff --git a/src/isode/pepsy/doc/Makefile b/src/isode/pepsy/doc/Makefile
new file mode 100644 (file)
index 0000000..33e7b01
--- /dev/null
@@ -0,0 +1,10 @@
+
+FILES = overview.ms tables.ms wt-pep.ms
+
+pepsy.info: $(FILES)
+       ditroff -ms $(FILES)
+
+DESCRIPTION: $(FILES)
+       -rm -f ../DESCRIPTION
+       nroff -ms $(FILES) > DESCRIPTION
+       ln DESCRIPTION ..
diff --git a/src/isode/pepsy/doc/overview.ms b/src/isode/pepsy/doc/overview.ms
new file mode 100644 (file)
index 0000000..ad0528f
--- /dev/null
@@ -0,0 +1,271 @@
+.NH 1
+Overview of pepsy system
+.XS
+Overview of pepsy system
+.XE
+.PP
+This section describes how the various parts fit together to make
+the system work.
+The principle behind pepsy is fairly simple.
+The \fBASN.1\fR is summarised as tables of integers.
+These tables are read by driver routines which encode or decode
+data to or from the internal format that \fBISODE\fR \fBOSI\fR implementation uses.
+In \fBISODE\fR specific functions are generated for each \fBASN.1\fR type
+defined in contrast the pepsy merely generates a new table of data which
+is far far smaller.
+.PP
+As there is a great deal of effort invested in the \fBISODE\fR interface to the
+encoding/decoding routines pepsy automatically provides macros which map
+the original functions into the appropriate function call of a driver.
+This allows existing posy using code to switch to the
+pepsy system with \fBno changes\fR
+to the code \fBprovided\fR no function pointers are used to the original
+\fBISODE\fR functions.
+Even when there are function pointers used the changes are very simple and
+take only a few hours to implement.
+.NH 2
+Brief description of the use of the pepsy system.
+.XS
+A Brief description of the use of the pepsy system.
+.XE
+.NH 3
+Outline of the files produced under the pepsy system.
+.XS
+Outline of the files produced under the pepsy system.
+.XE
+.PP
+The pepsy system consists of a program called \fIposy\fR
+which translates \fBASN.1\fR modules into a set of tables, called \fIposy\fR at the moment,
+and library of driver routines, called \fIlibpepsy.a\fR.
+Running this \fIposy\fR program on the \fBASN.1\fR file will produce several
+files.
+If the name of the \fBASN.1\fR module is \fBMODULE\fR the following files
+are generated:
+.I
+.IP MODULE-types.h
+.R
+which contains \fBC\fR structure definitions.
+The user of the library provides data as a linked list of
+these \fBC\fR data structures and expects to receive data back as a similar
+linked list.
+These data structures are exactly the same as those produced by the original
+\fBISODE\fR \fIposy\fR so that existing software written for the old \fIposy\fR
+program needs no change.
+For details on the \fBC\fR data structures types generated
+see the documentation of the original \fIposy\fR program in
+volume 4 Chapter 5 of the \fBISODE\fR manuals.
+.I
+.IP MODULE_tables.c 
+.R
+This file contains the tables generated by the new \fIposy\fR program.
+These tables consist of three parts, the first which contains the summary of
+\fBASN.1\fR types.
+Each type is summarised as an array of a primitive type, \fBstruct pte\fR,
+for encoding and decoding, and \fBstruct ptpe\fR for printing.
+As implied there is one array for each type for each of encoding, decoding and
+printing as specified when \fIposy\fR is run.
+The next part contains up to three tables of pointers to these arrays.
+Each of the three different types of arrays, encoding, decoding and printing,
+has its own table of pointers.
+Finally there is the module type definition which contains contains pointers
+to these tables and some other useful information about the module such as its
+name.
+This module type structure, which is \fBtypedef\fRed to \fBmodtyp\fR,
+is the only piece of data which is global, all the
+rest of the data is static and is only addressable via the \fBmodtyp\fR
+data structure. 
+This provides a kind of object oriented approach to handling the tables.
+Once you are passed a pointer to an \fBASN.1\fR's \fBmodtyp\fR structure
+you can encode, decode and print any of its types by calling the appropriate
+\fBlibpepsy.a\fR routine with its type number.
+.I
+.IP MODULE_pre_defs.h
+.R
+This file contains \fB#define\fRs symbol of each of the \fBASN.1\fR types
+to its type number, which is used when calling a \fBlibpepsy.a\fR routine.
+Each symbol is \fB_Ztype-nameMODULE\fR where \fItype-name\fR is the name of
+the type with dashes (\fB-\fR) turned into underscores (\fB_\fR) and
+\fIMODULE\fR is the name of the module.
+For example of the \fBASN.1\fR universal type \fIGraphicString\fR would
+have the \fB#define\fR symbol \fB_ZGraphicStringUNIV\fR.
+The \fI_Z\fR is prepended to try to make the symbols unique.
+This file also contains and extern declaration for the \fBmodtyp\fR data
+for its module.
+.I
+.IP MODULE_defs.h
+.R
+This file contains macros for  all the encoding, decoding and printing
+functions that the \fIpepy\fR program would have for these \fBASN.1\fR
+types.
+This allows much of the code that uses the routines generated by running
+the old \fIposy\fR program and taking its output and running \fIpepy\fR on
+augmented \fBASN.1\fR output can be recompiled unchanged.
+If the code used pointers to these functions it is necessary to change it
+to pass around the type numbers instead and to call appropriately call
+a \fBlibpepsy.a\fR library routine with the type number.
+As pointers to the printing routines in ISODE are passed as arguments
+a \fB#define\fR is provided to turn the argument into the pair of arguments,
+type number and pointer to \fBmodtyp\fR structure, which are needed to allow
+the diagnostic printing code to work with no change for
+the current \fBISODE\fR stack.
+This file also contains a \fB#include\fR of the \fIMODULE_pre_defs.h\fR file.
+.PP
+As the \fIMODULE-types.h\fR file \fB#include\fR's the \fIMODULE_defs.h\fR
+file no further \fB#include\fRs need to be added to the files using the
+encoding/decoding/printing functions.
+This means that code written to use posy/pepy system may need no change at all
+and the only effort required is to change the Makefile to use the pepsy
+system.
+If there is code changes required it would most likely be because function
+pointers are used to reference the functions generated by posy.
+If only the \fIpepy\fR system was used,
+not posy then pepy,
+with code placed inside action statements then quite a large amount of work
+may be needed to change over to the new system, depending on how large and
+complex the \fIpepy\fR module is.
+.NH 3
+Outline of the pepsy library.
+.XS
+Outline of the pepsy library.
+.XE
+.IP enc.c
+This contains the routines that encode data from the \fBC\fR data structures
+into \fBISODE\fR's \fBPElement\fR linked list data structure which it
+uses for all presentation data.
+The most important function to pepsy users is \fBenc_f\fR which called to
+encode a particular type.
+It is passed the type number and a pointer to \fBmodtyp\fR structure for that
+module and then the rest of the arguments which are passed to an encode
+function generated by \fIposy\fR/\fIpepy\fR system.
+See the documentation in Volume 4, "The Applications Cookbook",
+Section 6.4 called "Pepy Environment".
+Most of these latter arguments are ignored, only \fBparm\fR and \fBpe\fR,
+are used.
+.PP
+Contrary to what the \fBISODE\fR documentation says these ignored parameters
+are hardly ever used by existing code.
+We have not found a single case where used for encoding a named type,
+which is all that the user can reference anyway,
+so we don't see any problems with ignoring these other parameters.
+Hopefully one day they can be thrown away entirely, until then they are
+actually passed the the encoding function.
+.PP
+The rest of the functions are mostly recursive routines which encode a
+particular type of table entry.
+For example \fBSEQUENCE\fR is encoded by \fBen_seq\fR which may call itself
+or others to encode the types from which it is built up.
+The function \fBen_type\fR builds up a simple type and \fBen_obj\fR encodes
+a new type (object) and so on with other functions.
+There are a few utility routines in the file such as \fBsame\fR which
+determines whether the value is the same as the default value also.
+.IP dec.c 
+This file contains the decoding routines that translate
+presentation data into \fBC\fR data structures defined in
+the \fBMODULE-types.h\fR
+is like \fIenc.c\fR.
+It is very much like the file \fIenc.c\fR except the routines do the
+reverse tasks
+The routines are structured in a very similar way.
+We have \fBdec_f\fR which is called by the user to decode a type
+and like \fBenc_f\fR takes the same arguments as the decoding functions
+generated by \fIposy\fR with two additions, the type number and a pointer
+to the \fBmodtyp\fR structure for that module.
+Likewise the other functions are very much like those of enc.c
+.IP prnt.c
+This file contains the routines that print the presentation data in a format
+similar to that generated by \fIpepy\fR's printing functions.
+It's main function \fBprnt_f\fR is takes the same arguments as the printing
+function generated by \fIpepy\fR as well as the now familiar type number
+and \fBmodtyp\fR pointer.
+The functions are modeled on the decoding routines as it has similar job to.
+The only difference is that instead of storing the decoded data
+into a \fBC\fR data structure it is nicely printed out.
+.IP fr.c
+This file contains code to free the data structures
+defined in \fBMODULE-types.h\fR.
+Likewise if the \fB-f\fR flag is given when generating the types file it also
+includes macros in the types file which replace the freeing functions generated
+by ISODE's \fIposy\fR.
+The function that the user calls us \fBfre_obj\fR which takes a pointer to
+the data structure, its decoding table entry and a pointer
+to the \fBmodtyp\fR structure for the module. 
+The freeing is based on the decoding routines except instead of decoding all
+it does is free each part of the data structure, which might involve recursive
+calls, then it frees the data structure at the end.
+.IP util.c
+This contains the utility routines used by more than one of the above files.
+This is mostly diagnostic routines at the moment, more general routines could
+be included in here.
+If there is an error at the moment which it can't recover from it just prints
+out a message on standard error and calls \fBexit\fR.
+Not perfect and this is something that will need work.
+.IP main.c
+This contains code to perform a series of tests on the \fIpepsy\fR library
+which is a useful check to see whether any of the routines has been broken
+by any changes made.
+It basically loops through a whole series of test cases.
+Each test case is encoded from some built in test data and then decoded
+and checked to see if the data has changed in the transfer.
+If it is compiled with \fI-DPRNT=1\fR the encoded data is also printed
+out to check the printing routines which generates a vast amount of output.
+Finally the free routines are used to free the allocated data, although it
+can not directly check the free routines to see if they work, it can be used
+with a malloc tracing package to check that the routines work.
+.IP test_table.h
+This contains the test cases that \fImain.c\fR program runs.
+Each entry in the table corresponds to a type.
+One of the fields is count of how many times that type is to be tested
+to try out the different possibly data values it might have.
+.IP "pep.h and pepdefs.h"
+These files contain the definition of types used for the tables that drive the
+encoding/decoding/printing routines.
+All the constants used in that table are defined here via \fB#define\fRs.
+The \fBmodtyp\fR structure is defined in \fIpepdefs.h\fR.
+.IP "t1.py and t2.py"
+These are test \fBASN.1\fR modules that are used by \fImain.c\fR routines
+to check the \fIpepsy\fR library.
+The file \fIt1.py\fR contains the majority of different types with
+a few of a different module provided in \fIt2.py\fR.
+This allows the testing of the code for handling \fBASN.1\fR
+external references, i.e. references to types defined in other, external,
+modules.
+.NH 3
+New files in the pepy directory
+.XS
+New files in the pepy directory
+.XE
+.IP "etabs.c, dtabs.c and ptabs.c"
+These files contain the code to generate the encoding/decoding/printing tables.
+The main routine in \fIetabs.c\fR is \fBtenc_typ\fR which is called
+on each \fBASN.1\fR type
+to generate an array of entries which describe how to encode that type.
+See the details section for more information about how the
+table entries function.
+Similarly \fIdtabs.c\fR contains the routine \fBtdec_typ\fR which is
+called on each type to generate its decoding table entries.
+Likewise \fBtprnt_typ\fR routine generates the arrays of table entries for
+the printing tables.
+This function is in \fIptabs.c\fR.
+.IP "dfns.c"
+This file contains miscellaneous string handling routines and hash table
+routines that don't really belong anywhere else.
+Some of the routines could be cleaned up in that they tend not to free memory
+they use.
+.IP mine.h
+This file contains the definitions for the hash table(s) that are used to keep
+track of the \fBASN.1\fR types.
+This could probably be done with out a hash table, should anyone want to
+clean this up, feel welcome.
+The lookup function is in \fIdfns.c\fR.
+.IP pass2.h
+This file has most of the \fB#define\fRs for the table generating program.
+Most of the prefixes and suffixes of function names and files names are defined
+here so, hopefully, the names can be changed by merely changing the definition.
+This contains most of the important definitions needed by the changes
+to the \fIposy\fR program needed to generate tables.
+.IP posy.h
+This contains the definition of a symbol which is now needed outside of the
+the main routine and the yacc file.
+By putting it here we can include it any file that needs to know it with out
+putting in any that doesn't need it and with out including all the other
+definitions that occur in \fIpepy.h\fR.
diff --git a/src/isode/pepsy/doc/tables.ms b/src/isode/pepsy/doc/tables.ms
new file mode 100644 (file)
index 0000000..8f5b3f6
--- /dev/null
@@ -0,0 +1,353 @@
+.NS 2
+The structure and meaning of the tables generated from the ASN.1 grammar
+.XS
+The structure and meaning of the tables generated from the ASN.1 grammar
+.XE
+.PP
+Each collection of \fBASN.1\fR grammar is called a module.
+(See 
+.[
+ASN.1
+.]
+)
+Each \fBASN.1\fR module is completely specified in the program by a
+single \fBC\fR structure of type \fBmodtyp\fR and the data which it references.
+See the \fIpepdefs.h\fR file in the \fIpepsy\fR directory.
+For each \fBASN.1\fR module
+there are three tables that are generated from\fBASN.1\fR grammar.
+These initialised arrays which we call tables are
+called the encoding, decoding and printing tables.
+Each of these tables is referenced through a different pointer
+of the \fBmodtyp\fR structure.
+.PP
+Each of these pointers references an array of pointers,
+one pointer for each \fBASN.1\fR type defined in the module.
+The position of one of these pointers is the unique type number we give to
+its corresponding type.
+The pointer references an array of type \fBtpe\fR or \fBptpe\fR, depending
+whether it is an entry in the decoding/encoding tables or printing tables
+respectively.
+See \fIpep.h\fR in the \fIpepsy\fR directory.
+This array actually contains the necessary information to encode/decode/print
+that \fBASN.1\fR type.
+So given the \fBmodtyp\fR structure of an \fBASN.1\fR module and its
+type number you can call a routine to encode, decode or print that type.
+.PP
+The rest of this document assumes a good knowledge of \fBASN.1\fR notation
+so go read a copy if you haven't already.
+From here on I shall mention only \fBtpe\fR and this means \fBtpe\fR in the
+case of encoding or decoding and \fBptpe\fR in the case of printing, unless
+otherwise stated.
+Each type is represented by an array of \fBtpe\fR (or \fBptpe\fR for printing).
+The basic element consists of four integer fields,
+the printing table is the same with an addition \fBchar\fR pointer field which
+contains the name corresponding to that entry in the \fBASN.1\fR grammar.
+The first specifies the type of the entry and determines how the
+rest are interpreted.
+The possible types are listed in \fIpepsy/pep.h\fR.
+Each type is an array which starts with an entry of type \fBPE_START\fR
+and ends with one of type \fBPE_END\fR.
+Each primitive type requires one entry to specify it,
+apart from possible \fBPE_START\fR and \fBPE_END\fR used to specify the start
+and end of the type.
+Constructed types are represented by a list of entries terminated by an
+entry of type \fBPE_END\fR.
+As \fBASN.1\fR types can be nested inside so will the
+representation in \fBtpe\fR entries be nested.
+For example the \fBASN.1\fR type definition:
+.nf
+           Example1 ::=
+                   SEQUENCE {
+                       seq1 SEQUENCE {
+                                an-i INTEGER,
+                                an-ostring OCTET STRING
+                            },
+                       a-bool IMPLICIT [0] BOOLEAN
+                   }
+.fi
+.ce 1
+Will generate an encoding array:
+.nf
+static tpe et_Example1Test[] = {
+       { PE_START, 0, 0, 0 },
+       { SEQ_START, 0, 16, FL_UNIVERSAL },
+       { SEQ_START, OFFSET(struct type_Test_Example1, seq1), 16, FL_UNIVERSAL },
+       { INTEGER, OFFSET(struct element_Test_0, an__i), 2, FL_UNIVERSAL },
+       { OCTETSTRING, OFFSET(struct element_Test_0, an__ostring), 4, FL_UNIVERSAL },
+       { PE_END, 0, 0, 0 },
+       { BOOLEAN, OFFSET(struct type_Test_Example1, a__bool), 0, FL_CONTEXT },
+       { PE_END, 0, 0, 0 },
+       { PE_END, 0, 0, 0 }
+       };
+
+.fi
+.PP
+Here the second last \fBPE_END\fR matches and closes off the
+first \fBSEQ_START\fR.
+The entries which correspond to the other primative types are pretty
+obvious, with the INTEGER entry corresponding to the primative INTEGER.
+For fields that generate data the general interpretation of the other three
+fields is offset, tag and flags/class fields respectively.
+.IP offset
+The second field gives the offset in a \fBC\fR data structure
+needed to reference the data that corresponds to this table entry.
+Each \fBASN.1\fR type has \fBC\fR structure types generated as described in
+the 
+.[
+ISODE
+.]
+manuals, volume 4 "The applications Cookbook" Section 5.2,
+"POSY Environment".
+As this offset may have to be determined in a compiler dependent manner
+a \fBC\fR preprocessor macro is used hide the actual details.
+.IP tag
+This is the tag associated with the \fBASN.1\fR type for that entry.
+Notice that in the example the [0] IMPLICIT which changes the tag
+associated with the BOOLEAN entry actually has the correct tag of 0 in the
+table.
+Likewise SEQUENCE has the correct tag of 16 in its \fBSEQ_START\fR entry
+and so on for the others.
+.IP flags/class
+This contains the \fBASN.1\fR class associated with the entry's type.
+That is UNIVERSAL for all except the BOOLEAN type which is CONTEXT class.
+This fourth can also contain flags that specify if the type is OPTIONAL
+or DEFAULT.
+There is plenty of room here as there is only four possibly classes.
+.PP
+Now that you have some idea of how these arrays are arranged for a type
+definition I will proceed to go through the possible type of
+entries and describe what they do and how they work.
+These values are defined in \fIpepsy/pep.h\fR.
+Those entries with a value below \fBTYPE_DATA\fR are entries that
+don't correspond to data to be encoded/decoded and are for other book keeping
+type purposes.
+.IP "PE_START and PE_END"
+As explained above \fBPE_START\fR starts the beginning of a \fBASN.1\fR type's
+array.
+It probably isn't necessary but the size of the tables is so small it isn't
+much of an over head to keep around for cosmetic reasons.
+The entry type \fBPE_END\fR is necessary to mark the end of some
+compound type as well as the end of \fBASN.1\fR data type.
+.IP "XOBJECT and UCODE"
+These are obsolete types and probably should be removed.
+They were to allow \fBC\fR code written directly by the user to be incorporated
+into the encoding/decoding but it was found unnecessary.
+Prehaps some brave soul would like to use them in an attempt to implement
+a similar system based on \fIpepy\fR which is what we first attempted to
+do until we found this to be much easier.
+.IP MALLOC
+This field only occurs in the decoding tables.
+It specifies how much space to malloc out for the current \fBC\fR structure
+it is just inside of.
+For instance in the example above the decoding table has the following entry:
+.DS C
+{ MALLOC, 0, sizeof (struct type_Test_Example1), 0 },
+.DE
+just after the first \fBSEQ_START\fR entry.
+It tells it to \fBmalloc\fR out a \fBstruct type_Test_Example1\fR structure
+to hold the data from the sequence when it is decoded.
+.IP SCTRL
+This entry is used in handling the \fBASN.1\fR CHOICE type.
+The \fBC\fR type generated for \fBASN.1\fR CHOICE type is a structure with
+an offset field in it and a
+union of all the \fBC\fR types present in the CHOICE.
+Each \fBASN.1\fR type in the CHOICE of types has a \fBC\fR type definition
+generated for it.
+The union is of all these types, which is quite a logical way to implement
+a CHOICE type.
+The offset field specifies which possibility of interpreting the union
+should be used (which \fImember\fR should selected).
+As such it needs to be read by the encoding routines
+when encoding the data from the \fBC\fR data structures
+and to be set by the decoding routines when it is decoding the data into
+the \fBC\fR data structures.
+There is one such entry for each \fBCHOICE\fR type to specify where the
+offset field is.
+.IP CH_ACT
+Another redundant entry type.
+I think this was also used in code to handle \fBC\fR statements or
+actions specified by the user.
+It probably should be removed.
+.IP OPTL
+This is used to handle the optionals field that is generated by
+\fBposy\fR when optional types that are \fInot\fR implemented by pointers
+are present in the \fBASN.1\fR type.
+For example if an \fBASN.1\fR type has an optional integer field how
+does the encoding routine determine if the integer is to be
+present or not?
+If it was implemented as a pointer it could use a \fBNULL\fR (zero) pointer
+to mean that the type was not present because
+NULL is guaranteed to never occur as a legal pointer to a real object.
+But all the possible values for integer could be legally passed so
+instead for these types which are not pointers and are optional
+a bit map is allocated in the structure.
+Each non pointer optional type a bit from the bit map is
+allocated.
+.PP
+If that bit is set the corresponding type is present and it is not
+present if the bit is not set.
+Each bit has a \fB#define\fR generated for it.
+The bit map is merely an integer field called "\fBoptionals\fR" limiting
+maximum number of such optionals to 32 on Sun machines, 16 on some others.
+(An array of \fBchar\fR as BSD fd_sets would have avoid all such limits,
+not that this limit is expected to be exceeded very often !)
+Like the \fBSCTRL\fR entry this entry merely serves to specify where
+this field is so it can be test and set by the encoding and decoding routines
+respectively.
+.IP "ANY and CONS_ANY"
+The \fBC\fR type corresponding to the entry is a \fBPE\fR pointer.
+To conform with \fIpepy\fR the tag and class of this entry are ignored,
+which may or may not be the most sensible thing.
+The \fBCONS_ANY\fR is a redundant symbol which means the same thing but
+is not used.
+This should be clean up and removed.
+.IP "INTEGER, BOOLEAN, BITSTRING, OCTETSTRING and OBJID"
+These are just as described in the first article.
+See the ISODE manual to find out what they are allocated as a \fBC\fR data
+type to implement them.
+The offset fields says where to find this data type with in the current
+structure.
+.IP "SET_START, SETOF_START, SEQ_START and SEQOF_START"
+These compound entries differ from the above in that they group all
+the following entries together up to the matching \fBPE_END\fR.
+The entries with \fBOF\fR in them correspond to the \fBASN.1\fR types
+which have \fBOF\fR in them
+e.g. \fBSET OF\fR.
+Allowing the \fBOF\fR items to have an arbitrary number of entries is
+excessive flexibility, they can only have one type by the \fBASN.1\fR grammar
+rules.
+The \fBC\fR data type corresponding to them is either a structure if
+it is the first such type in the array or a pointer to a structure
+is isn't.
+This complicates the processing of these structures a little but not greatly.
+The \fBOF\fR types differ one other important way,
+they may occur zero, one or more times, with no upper bound.
+To cope with this the \fBC\fR data type is a linked list structure.
+The pointer to the data structure determines whether or not there is another
+occurrence of the type, if it is NULL there isn't.
+Thus each data structure has this pointer to the next occurrence, the offset of
+this pointer is placed in the \fBPE_END\fR field where it can conveniently
+be used to determine whether or not to make another pass through the
+table entry. 
+.IP OBJECT
+When one type references another it generates an \fBOBJECT\fR entry.
+This specifies the type number of the type
+which is present in the 3rd field of the \fBtpe\fR structure,
+\fBpe_tag\fR.
+The 2nd field still gives the offset in the \fBC\fR data structure
+which specifies where the user's data for that type is to be found.
+Usually this a pointer to the \fBC\fR data structure for that type.
+.IP T_NULL
+This entry means the \fBASN.1\fR primative type \fBNULL\fR.
+It doesn't have any body and consequently has no offset as it cannot
+carry data directly.
+Only its absence or presence can mean anything so if it is optional it sets or
+clears a bit in the bit map as described earlier for \fBOPTL\fR entry.
+.IP T_OID
+This use to be used for Object Identifiers and now is unused,
+it should be got rid.
+.IP OBJID
+This corresponds to the Object Identifier \fBASN.1\fR type primitive.
+It is implemented the same as other primative types like \fBINTEGER\fR
+and \fBOCTET STRING\fR.
+.IP ETAG
+This entry gives the explicit tag of the following entry.
+The usual fields which define class and tag are the only ones which have
+meaning in this entry.
+By concatenating successive \fBETAG\fR entries it is possibly to build up
+an limited number explicit tags, although this hasn't been tested yet.
+.IP IMP_OBJ
+If a type has an implicit tag usually all we have to do is set its tag
+and class appropriately in its entry.
+This works for all but one important case, the reference of another type.
+This is messy because we can't alter the definition of the type with out
+wrecking it for the other uses.
+So what we do for encoding is build the type normally
+and then afterward it is built
+change its tag and class to be the values we want.
+Similarly for decoding we match the tag and class up and then decode the body
+of the type.
+We can't use a \fBOBJECT\fR entry for this because among other
+reasons there 3rd field is already to store the type number.
+(The forth needs to be free to contain flags such as \fBDEFAULT\fR
+and \fBOPTIONAL\fR)
+So a new entry type is used, \fBIMP_OBJ\fR, to hold the tag and class.
+It must be followed by an \fBOBJECT\fR entry which is used to handle the type
+as normal, the \fBIMP_OBJ\fR entry gives the tag and class to be used.
+Like the \fBETAG\fR entry the \fBIMP_OBJ\fR affects the entry that follows it.
+.IP "EXTOBJ and EXTMOD"
+These handle external type references.
+This is just like a normal (internal?) type reference except we must now
+specify which module as well as the type.
+Similarly because there are no more free fields in the \fBOBJECT\fR type
+we need two entries to hold all the information we need.
+The \fBEXTMOD\fR occurs first and holds the type number and the offset
+into the \fBC\fR data structure and the flags, exactly as for an \fBOBJECT\fR
+entry.
+The next entry, which must be an \fBEXTMOD\fR, contains a pointer to
+the \fBmodtyp\fR structure for its module.
+Like a normal \fBOBJECT\fR entry to handle the case of an implicit tag
+an \fBIMP_OBJ\fR entry would occur before these two entries which gives
+the class and tag.
+Likewise it could have an explicit tag in which the two entries
+would be proceeded by an \fBETAG\fR entry.
+.IP "DFLT_F and DFLT_B"
+When a type has a default value, to handle decoding and encoding properly you
+need to know its value.
+As there is no space to store the value in most entries we allocate a whole
+entry to specify the value.
+When encoding it is convenient to have the default occur before the entry it
+refers to.
+This allows a single check to handle all the default encoding.
+All it has to do is check whether it is the same as the default value and if so
+not bother encoding the next type.
+On the other hand when decoding it is more convenient to have
+the entry after the
+one it refers to.
+In this case we need to determine that it is missing before we use the default
+value to determine the value to pass to the user.
+To handle this we have entries of both types.
+.B DFLT_F
+contains the default value for the following entry (F = Front)
+and \fBDFLT_B\fR contains that for the entry before it (B = Back).
+Consequently \fBDFLT_F\fR are only used in the decoding tables
+and \fBDFLT_B\fR entries are only used in the decoding (and printing tables).
+.IP S-Types
+These types are entries for the same \fBASN.1\fR type as the entry type
+formed by removing the starting `S'.
+The above forms would do to handle \fBASN.1\fR but we also have to be
+compatible with the \fBC\fR data structures generated by \fIposy\fR.
+The implementors decided to optimise the \fBC\fR data structures generated
+a little means we have to have all these \fBS\fR type entries.
+If a type was a single field in most cases they produced a \fB#define\fR
+which eliminates the need to have a whole structure just for that type.
+In all the places where this type is used the field of the \fBC\fR structure
+is changed from a pointer to field which holds the value directly in the
+structure.
+See the \fBISODE\fR reference given above for more details.
+.PP
+We handle this by generating the same tables that would be generated
+with out the optimisation, except the optimised types the S-type of entries
+instead of the normal ones.
+For example an optimised \fBOCTET STRING\fR would have
+the type field of its entry as \fBSOCTETSTRING\fR instead of \fBOCTETSTRING\fR.
+The only difference in how \fBS\fR type and its corresponding normal are handle
+is how they find the \fBC\fR data structure for that entry.
+That difference is that there is no indirection through pointers.
+.IP "Flags field"
+Besides the encoding the class the \fBpe_flags\fR field
+also contains a few possible flags.
+Mainly \fBFL_OPTIONAL\fR which means the \fBASN.1\fR type
+corresponding to this flag is OPTIONAL.
+Consequently when encoding it has to determine if the type is present in the
+user data possibly using the bit map as described under the \fBOPTL\fR entry.
+Likewise when decoding it may have to set a bit in the bit map appropriately.
+The other flag at the moment is \fBFL_DEFAULT\fR which means the entry
+corresponds to an \fBASN.1\fR DEFAULT type.
+This bit is still needed as not all types have \fBDFLT_*\fR entries implmented
+for them at the moment.
+In particular compound value things like SEQUENCE and SET can't have thier
+default value specified.
+This is consistent with \fBISODE\fR, if fact implementing that may even
+break existing \fBISODE\fR code.
+This last flag \fBFL_IMPLICIT\fR is obsolete and not not used any where.
diff --git a/src/isode/pepsy/doc/wt-pep.ms b/src/isode/pepsy/doc/wt-pep.ms
new file mode 100644 (file)
index 0000000..8045bd9
--- /dev/null
@@ -0,0 +1,201 @@
+\" Walk through of the pepsy library routines
+.NH 2
+Walk through of pepsy library routines.
+.XS
+Walk through of pepsy library routines.
+.XE
+.PP
+Here we walk through all the pepsy library routines at least briefly.
+If any new routines are added or a routine changed this documentation
+is the most likely part that will need changing.
+First we give some theory as to how the task have have been brocken
+into routines then describe each function in detail.
+We assume you are familiar with \fBISODE\fR's \fBPE\fR data
+structure manipulation routines.
+if not they are documented in the \fBISODE\fR manuals, Volume one, chapter 5,
+"Encoding of Data-Structures" (It actually covers decoding as well).
+.NH 3
+Overview of pepsy library
+.XS
+Overview of pepsy library
+.XE
+.PP
+Each seperate task is put into a different file.
+So all the encoding stuff is in \fIenc.c\fR, all the decoding stuff is
+in \fIdec.c\fR, printing stuff in \fIprnt.c\fR and freeing stuff in \fIfre.c\fR.
+Actually it breaks down a little in practice, some of the routines for
+moving around the tables are used in both \fIenc.c\fR and \fIdec.c\fR
+for example.
+Probably they should defined in \fIutil.c\fR so that linking one of the files
+from the library doesn't force linking any other except \fIutil.o\fR.
+.PP
+There is a common structure to each of the major files as well.
+There is a main routine which the user calls to obtain the services
+provided by that file's routines.
+As all the files revolve about processing the table entries their
+structure is based on running through the table entries.
+.PP
+We shall call each array of entries a table or an object.
+There is a routine, usually with a name ending in _obj, which is designed
+to process an object.
+For example \fBen_obj\fR is the routine called to generated an encoded
+object.
+Then there are routines to call on each compound type
+such as \fBen_seq\fR for encode a SEQUENCE.
+Finally all the primitives are handled by a one function that ends in _type.
+This lets each routine concentrate on handling the features particular to
+its type and call the appropriate routine to handle each type it finds
+with in its compound type.
+.PP
+Most of these table processing routines have just three arguements:
+which are called \fBparm\fR, \fBp\fR, \fBmod\fR.
+The \fBparm\fR is char * or char ** in the encoding and decoding routines
+respectively.
+This points to the user's \fBC\fR structure that data to be encoded
+is taken from when encoding.
+When decoding it is the address of a pointer which is made to point
+the \fBC\fR structure filled with the decode data.
+The freeing, which is based on the decoding routines, has a char **
+while the printing routines don't look at the user's data and so don't
+have such a pointer.
+The \fBp\fR points to the current table entry we are up to processing and
+the \fBmod\fR arguement points to the \fBmodtyp\fR structure for the current
+module we are processing.
+.PP
+All these processing routines return a \fBPE\fR type,
+which is defined in \fBISODE\fR's file \fIh/psap.h\fR, and to return zero
+if they have an error, but not always.
+In fact the error handling is needs some work and has not
+been tested very well.
+Generally it tries to print out the table entry where something went wrong and
+the name of the function it was in.
+It then sometimes does an exit which may not be very pleasent for the
+user.
+.NH 3
+The encoding routines - enc.c
+.XS
+The encoding routines - enc.c
+.XE
+.IP enc_f
+This is the the routine made available to the user for the encoding routines.
+It is fairly simple as it leaves all the hard things up to other routines.
+All it does is use the type number and \fBmodtyp\fR pointer to get
+a pointer to the table for encoding that type.
+Then it calls the table or object encoding routine, \fBen_obj\fR,
+on that object.
+It first does a consistency check of making sure the first entry in the table 
+is a \fBPE_start\fR.
+Note that it returns an integer (OK or NOTOK) instead of a \fBPE\fR pointer.
+This is to be consitent with \fBISODE\fR functions.
+.IP en_obj
+We loop through the entries until we come to the end of the table and then we
+return the \fBPE\fR we have built up from the user's data which is pointed
+to by \fBparm\fR.
+In looping through each entry we call the appropriate routine to encode its
+data.
+The default case is handled by calling \fBen_type\fR which takes care of
+all the primitive types.
+.PP
+The macro \fBNEXT_TPE\fR sets its arguement to point to the next type
+in the table, counting compound types as one type.
+Thus if \fBNEXT_TPE\fR is called on a \fBSET_START\fR it will skip all the
+entries up to and including the matching \fBPE_END\fR.
+As many objects consist of one compound type and its components the main
+loop will only be run through once.
+Even when the object is not based on a compound type it will then consist of
+one simple type which is processed by \fBen_type\fR, again probably
+going through the loop only once.
+In fact the only way it can go through the loop more than once
+is to process entries that subsidary to the main type, e.g. \fBETAG\fB entries
+and things like that.
+To double check this is the case there is some code that looks for
+the processing of more than one data generating entry.
+.PP
+Much of that testing could probably be eliminated with no loss.
+Similarly prehaps the \fBIMP_OBJ\fR and \fBETAG\fR could be handled by the
+default action of calling \fBen_type\fR.
+As these routines have evolved after many changes there are things like
+that which really need to be looked at closely before trying.
+The comment /*SUPRESS 288*/ means suppress warning 288 to saber C debugging
+tool that we use.
+.IP en_type
+This is one of the longest functions as it has so many cases to handle.
+It again is structure as a loop over the types until \fBPE_END\fR but it
+actually returns as soon as it has encoded the next type.
+We can now look at the encoding of the primative \fBASN.1\fR types in detail.
+.IP DFLT_F
+Because we have arranged that for encoding tables, that we precede
+the entry with a \fBDFLT_F\fR entry we can neatly handle all the default
+cases.
+All we do is check if the parameter passed in the user data, in \fBparm\fR,
+is the same as the default value specified in the \fBDFLT_F\fR entry.
+The function \fBsame\fR performs this check.
+If it is the same don't encode anything just return, otherwise continue on
+and encode it.
+.IP ETAG
+To handle explicit tags we merely allocate a \fBPE\fR with the right tag
+and call \fBen_etype\fR to encode its contents, which are in the following
+entries.
+The switch on the \fBpe_ucode\fR field use to make a difference
+but now it is meaningless and should be cleaned up.
+.IP "SEQ_START, SEQOF_START, SET_START, SETOF_START"
+We merely call the appropriate function handle them.
+Note one \fIimportant\fR difference in the way they are called here from that
+in \fBenc_obj\fR, the parm arguement is used as a base to index off and
+fetch a new pointer to pass the next function.
+This seemly bizarre action is quite straight forward when seen written as
+it is normally in \fBC\fR, "\fBparm->offset\fR".
+Where the field \fBoffset\fR is a pointer which has an offset from the start
+of the structure of \fBp->pe_ucode\fR bytes.
+.PP
+This is the magic of how we access all the different fields
+of the \fBC\fR data structures with the one piece of code.
+It is also prehaps the most critical dependency of the whole system
+on the implementation of the \fBC\fR language.
+As the \BGNU\fR \fBC\fR compiler supports this feature then it is
+compilerable on most machines.
+But any porters should pay attention to this to ensure that thier compiler
+is happy generating these offsets and compiling these casts properly.
+.PP
+The reason why this is different from the calls in \fBen_obj\fR is that
+this is not the first compound type in the table.
+The first and only the first does not have an offset and does not need to be
+indirected through any pointers.
+All the compound types inside this type will have
+as their field a pointer which points to a structure.
+From here on we shall say \fIindirection\fR  to mean this
+adding the \fBpe_ucode\fR field
+to the pointer to the structure and using it to reference a pointer.
+Whether to use \fIindirection\fR or not is very important matter
+that really needs to be understood to understand how the routines are
+structured.
+.IP IMP_OBJ
+Here we have to handle the case where we can encode the object then have to
+change its tag and class after encoding.
+At the end of this entry this is done very simply by assigning the
+right values to the appropriate fields after the object has been built.
+This means that if the intermeadiate form is altered this piece of code
+may have to be altered as well.
+There seems to be no better way of handling this.
+.PP
+The complication in handling this field is the handling of all the possible
+types of object.
+If it is an external object we have to perform a call to \fBenc_f\fR with
+all the right arguements
+where a normal OBJECT, the last else branch, requires a normal call
+to \fBen_obj\fR.
+Note the case of \fBSOBJECT\fR is the same
+as \fBOBJECT\fR \fIexcept there is no indirection\fR.
+.IP "SOBJECT and OBJECT"
+Here is the code that handles the two cases sperately.
+It is exactly as in the \fBIMP_OBJ\fR case except seperated out.
+Note the only difference between the two cases is lack of indirection in
+the \fBSOBJECT\fR case.
+.IP CHOICE_START
+This is exactly as all other compound types,
+like \fBSEQ_START\fR and \fBOBJECT\fR, we call the appropriate routine with
+indirection.
+From reading the \fBISODE\fR manuals that the \fBASN.1\fR CHOICE type
+is handled by a structure of its own like the other compund types.
+.IP "EXTOBJ and SEXTOBJ"
+
diff --git a/src/isode/pepsy/dtabs.c b/src/isode/pepsy/dtabs.c
new file mode 100644 (file)
index 0000000..2f738f9
--- /dev/null
@@ -0,0 +1,812 @@
+/* dtabs.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:28  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:55  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:09  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "pepsydefs.h"
+#include "pass2.h"
+#include "mine.h"
+#include <ctype.h>
+
+
+extern char *c_tag(), *c_class();
+extern char *ec_tag(), *ec_class();
+extern char *strip_last();
+extern char *str_yp_code[];
+extern char *get_val(), *get_comp(), *strp2name();
+extern s_table *lookup_list(), *get_offset();
+extern YP tdec_loop();
+
+extern char *concat();
+extern char *my_strcat();
+extern char    *rm_indirect();
+extern char    *getfield();
+extern char    *setfield();
+extern char    *modsym ();
+extern int     gen_sentry();
+
+/* extern int explicit; */
+
+#define WORDSIZE       20
+
+/*
+ * table encode a type. generate tables for the encoding of a type
+ */
+tdec_typ(fp, yp, id, type)
+FILE   *fp;
+YP      yp;
+char   *id;
+char   *type;
+{
+    char   *t, *f;
+    char   *p1;
+    YP      y;
+    YAL        yal;
+
+    if (yp->yp_code < 0 || yp->yp_code > YP_REAL)
+       ferrd(1, "tdec_typ: unimplemented type %d\n", yp->yp_code);
+
+    if (yp == NULL) {
+       ferr(0, "tdec_typ:NULL arguement\n");
+       return;
+    }
+
+    if (type)
+       t = type;
+    else if (yp->yp_param_type) {
+       char *t1;
+       /* we have a [[ P type ]] specification */
+       if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+           fprintf(stderr,
+           "\ntdec_typ:SETLIST can't extract direct type from %s\n",
+               yp->yp_param_type);
+           exit(1);
+       }
+       t = strdup(t1);
+    } else
+       t = my_strcat("struct ", modsym(mymodule, id, "type"));
+
+    if (yal = yp->yp_bef_alist) {
+       yal->yal_type = t;
+       if (yal->yal_dec)
+           gen_act(fp, yp->yp_bef_alist->yal_dec);
+    }
+    if (yal = yp->yp_aft_alist) {
+       yal->yal_type = t;
+    }
+    if (yal = yp->yp_control_act)
+       yal -> yal_type = t;
+
+    if (yal = yp->yp_optional_act)
+       yal -> yal_type = t;
+
+    if (type == NULLCP) {
+       switch (yp->yp_code) {
+           /*
+            * These generate MEMALLOC entries inside *_START ..
+            * PE_END fields for historical reasons. One day we might
+            * fix this to be all done the same way.
+            */
+       case YP_SEQLIST:
+       case YP_SEQTYPE:
+       case YP_SETLIST:
+       case YP_SETTYPE:
+       case YP_CHOICE:
+           break;
+
+       default:
+           if (yp->yp_varexp == NULL)
+               break;          /* S* type entry - doesn't need a
+                                * malloc */
+
+           (void) fprintf(fp, "\t{ MEMALLOC, 0, sizeof (%s), 0 },\n", t);
+           break;
+       }
+    }
+
+
+    if ((yp->yp_flags & YP_PARMVAL) && yp->yp_parm) {
+       if ((f = getfield(yp->yp_parm)) == NULLCP) {
+           fprintf(stderr, "\ntdec_typ: can't extract field from %s\n",
+               yp->yp_parm);
+           exit(1);
+       }
+       f = strdup(f);
+    } else
+       f = yp->yp_varexp;
+
+    if ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+       == (YP_OPTIONAL|YP_OPTCONTROL)) {
+       char *f1;
+       char *bitno;
+
+       if (yp -> yp_optional_act && yp -> yp_optional_act -> yal_dec) {
+           (void) fprintf (fp, "\t{ BOPTIONAL, %d, 0, FL_USELECT},\n",
+                           control_act(yp -> yp_optional_act -> yal_dec));
+       }
+       else {
+           if ((f1 = getfldbit(yp->yp_optcontrol, &bitno)) == NULLCP) {
+               fprintf(stderr,
+                       "\ntdec_typ:BOPTIONAL: can't extract field from %s\n",
+                       yp->yp_optcontrol);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ BOPTIONAL, AOFFSET(%s, %s), %s, 0},\n", t,
+                          f1, bitno);
+       }
+    }
+
+    if (yp->yp_flags & YP_TAG && !(yp->yp_flags & YP_IMPLICIT)) {
+       (void) fprintf(fp, "\t{ ETAG, 0, ");
+       (void) fprintf(fp, "%s, %s },\n", ec_tag(yp), ec_class(yp));
+    }
+
+    if (yp->yp_yfn && yp->yp_yfn->yfn_dec) {
+
+       gen_fn(fp, yp, yp->yp_yfn->yfn_dec);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+
+       if (gen_freefn(fp, yp)) {
+           if (yp->yp_aft_alist && yp->yp_aft_alist->yal_dec)
+               gen_act(fp, yp->yp_aft_alist->yal_dec);
+           return;
+       }
+    }
+
+    switch (yp->yp_code) {
+
+    case YP_UNDF:
+       ferr(1, "tdec_typ:Undefined type\n");
+
+    case YP_BOOL:
+       if (yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tdec_typ:BOOL: must specify a field for boolean\n");
+       p1 = "BOOLEAN";
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f)))
+           break;
+       ferr(1, "tdec_typ:BOOL: couldn't determine type\n");
+
+       /* This needs to be fixed up in the action generating area */
+    case YP_INTLIST:
+
+    case YP_INT:
+
+    case YP_ENUMLIST:
+       if (yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tdec_typ:INT: must specify a field for an integer\n");
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) {
+           p1 = "INTEGER";
+           break;
+       }
+       ferr(1, "tdec_typ:INT: couldn't determine type\n");
+       break;
+
+    case YP_REAL:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (noindirect(f))
+           ferr(1, "tdec_typ:REAL: must specify a field for a REAL\n");
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "REALTYPE";
+           break;
+       }
+       ferr(1, "tdec_typ:REAL: couldn't determine type\n");
+       break;
+
+
+    case YP_BIT:
+    case YP_BITLIST:
+       if (yp->yp_strexp && yp->yp_intexp) {
+           if (yp->yp_strexp)
+               f = setfield(yp->yp_strexp);
+           if (noindirect(f))
+               ferr(1, "tdec_typ:BIT: must specify a [[ x ... ]] value\n");
+           p1 = "BITSTR_PTR";
+           prnte(fp, t, f, yp, p1);
+           if (yp->yp_intexp)
+               f = setfield(yp->yp_intexp);
+           if (noindirect(f))
+               ferr(1, "tdec_typ:BIT: must specify a [[ x ... ]] value\n");
+           p1 = "BITSTR_LEN";
+           break;
+       }
+       if (yp->yp_strexp == NULLCP && yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) {
+           p1 = "BITSTRING";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SBITSTRING, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_OCT:
+       if (yp->yp_strexp) {
+           switch (yp->yp_prfexp) {
+           case 'q': /* [[ q parm->qbufptr ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   p1 = "SOCTETSTRING";
+               else
+                   p1 = "OCTETSTRING";
+               break;
+
+           case 's': /* [[ s ptr ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   ferr(1, "tdec_typ:OCTET: must specify a field [[ s .. ]]\n");
+               p1 = "T_STRING";
+               break;
+               
+           case 'o': /* [[ o ptr $ length ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   ferr(1, "tdec_typ:OCTET: must specify a field [[ o .. ]]\n");
+               p1 = "OCTET_PTR";
+               prnte(fp, t, f, yp, p1);
+               if (yp->yp_intexp)
+                   f = setfield(yp->yp_intexp);
+               if (noindirect(f))
+                   ferr(1, "tdec_typ:OCTET: must specify a field [[ o .. $ .. ]]\n");
+               p1 = "OCTET_LEN";
+               break;
+
+           default:
+              fprintf(stderr,"\ntdec_typ: Unknown Octet string specifier %c\n",
+                  yp->yp_prfexp);
+               exit(1);
+           }
+           break;
+       }
+       if (f) {
+           p1 = "OCTETSTRING";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SOCTETSTRING, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_OID:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "OBJID";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SOBJID, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_SEQ:
+    case YP_SET:
+    case YP_ANY:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "ANY";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SANY, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_NULL:
+       p1 = "T_NULL";
+       t = NULL;
+       break;
+
+    case YP_IDEFINED:
+       p1 = NULL;
+
+       if ((yp->yp_flags & YP_PARMVAL) && yp->yp_prfexp)
+               ferr(1,
+    "\n[[ ? reference ]] [[ p reference ]] is illegal\n\t only one allowed\n");
+
+       if (yp->yp_prfexp) { /* [[ ? parm->field ]] - complex to process */
+           gen_identry(fp, t, f, yp, gen_ventry);
+
+           if (yp->yp_flags & YP_DEFAULT)
+               gdflt(fp, yp, G_DEC);
+
+           break;
+       }
+
+       {
+           /* Predefined Universal Type */
+           struct univ_typ *p, *univtyp();
+
+           if ((p = univtyp(yp->yp_identifier))) {
+               if (p->univ_flags & UNF_EXTMOD) {
+                   yp->yp_module = p->univ_mod;
+                   goto do_obj;
+               }
+               if (f == NULL || noindirect(f)) {/* No offset type */
+                   if (yp->yp_flags & YP_TAG
+                       && yp->yp_flags & YP_IMPLICIT)
+                               prstfield(fp, p->univ_tab, t, f,
+                                int2tstr(yp->yp_tag->yt_value->yv_number),
+                                c_flags(yp, yp->yp_tag->yt_class));
+                   else
+                        prstfield(fp, p->univ_tab, t, f,
+                                 int2tstr((int)p->univ_id),
+                                 c_flags(yp, p->univ_class));
+                   goto out;
+               }
+               if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
+                        prtfield(fp, p->univ_tab, t, f,
+                            int2tstr(yp->yp_tag->yt_value->yv_number),
+                            c_flags(yp, yp->yp_tag->yt_class));
+               else
+                    prtfield(fp, p->univ_tab, t, f,
+                            int2tstr((int)p->univ_id),
+                            c_flags(yp, p->univ_class));
+               goto out;
+           }
+       }
+do_obj:
+       if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
+           (void) fprintf(fp, "\t{ IMP_OBJ, 0, %s, %s },\n", c_tag(yp), c_class(yp));
+       if (yp->yp_module == NULL
+           || strcmp(yp->yp_module, mymodule) == 0) {
+           if (f == NULL || noindirect(f))
+                  prstfield(fp, "OBJECT", t, f,
+                      concat("_Z", proc_name(yp->yp_identifier, 0)),
+                      c_class(yp));
+           else
+                  prtfield(fp, "OBJECT", t, f,
+                      concat("_Z", proc_name(yp->yp_identifier, 0)),
+                      c_class(yp));
+
+       } else {
+           if (f == NULL || noindirect(f))
+                  prstfield(fp, "EXTOBJ", t, f,
+                      concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)),
+                        c_class(yp));
+           else
+                  prtfield(fp, "EXTOBJ", t, f,
+                      concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)),
+                        c_class(yp));
+           (void) fprintf(fp, "\t{ EXTMOD, %d, 0, 0 },\n",
+                   gen_modref(yp->yp_module));
+       }
+    out:
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       break;
+
+    case YP_SEQLIST:
+       p1 = NULL;
+       /* support for -h flag */
+       if (yp->yp_varexp == NULL && type != NULL)
+           ferr(1, "tdec_typ:YP_SEQLIST:NULL varexp pointer\n");
+       prcte(fp, type, t, f, yp, "SEQ_START");
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntdec_typ:SEQLIST can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tdec_typ:YP_SEQLIST:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (!type || !noindirect(f))
+               genmalloc(fp, yp);
+
+           if (optfield(y)) {
+               (void) fprintf(fp,
+                       "\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
+                       yp->yp_structname);
+           }
+           tdec_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       break;
+
+    case YP_SETLIST:
+       p1 = NULL;
+       /* support for -h flag */
+       p1 = NULL;
+       if (yp->yp_varexp == NULL && type != NULL)
+           ferr(1, "tdec_typ:YP_SETLIST:NULL varexp pointer\n");
+       prcte(fp, type, t, f, yp, "SET_START");
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntdec_typ:SETLIST can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tdec_typ:YP_SETLIST:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (!type || !noindirect(f))
+               genmalloc(fp, yp);
+
+           if (optfield(y)) {
+               (void) fprintf(fp,
+                       "\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
+                       yp->yp_structname);
+           }
+           tdec_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       break;
+
+    case YP_SEQTYPE:           /* What is the difference ?? */
+       p1 = NULL;
+       prcte(fp, type, t, f, yp, "SEQOF_START");
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntdec_typ:SEQTYPE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tdec_typ:YP_SEQTYPE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (!type || !noindirect(f))
+               genmalloc(fp, yp);
+
+           tdec_loop(fp, y, id, yp->yp_structname);
+       }
+       if (yp->yp_flags & YP_CONTROLLED) {
+           char *f1;
+
+           if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+               fprintf(stderr, "\ntdec_typ:SEQ OF: can't extract field from %s\n",
+                   yp->yp_control);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
+                   yp->yp_structname, f1);
+       } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
+                   yp->yp_structname);
+       else
+           (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       break;
+
+    case YP_SETTYPE:
+       p1 = NULL;
+       prcte(fp, type, t, f, yp, "SETOF_START");
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+
+       if (y = yp->yp_type) {
+           char *t1;
+
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntdec_typ:SETTYPE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tdec_typ:YP_SETTYPE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (!type || !noindirect(f))
+               genmalloc(fp, yp);
+
+           tdec_loop(fp, y, id, yp->yp_structname);
+       }
+       if (yp->yp_flags & YP_CONTROLLED) {
+           char *f1;
+
+           if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+               fprintf(stderr, "\ntdec_typ:SET OF: can't extract field from %s\n",
+                   yp->yp_control);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
+                   yp->yp_structname, f1);
+       } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
+                   yp->yp_structname);
+       else
+           (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       break;
+
+    case YP_CHOICE:
+       p1 = NULL;
+       /* support for -h flag */
+       if (hflag && (y = yp->yp_type) && !y->yp_next) {
+           tdec_typ(fp, y, id, yp->yp_structname);
+           break;
+       }
+       if (type == NULL || type && noindirect(f))
+           prstfield(fp, "CHOICE_START", t, f, NULLCP, c_class(yp));
+       else
+           prtfield(fp, "CHOICE_START", t, type ? f : NULLCP,
+                    NULLCP, c_class(yp));
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntdec_typ:CHOICE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tdec_typ:YP_CHOICE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (!type || !noindirect(f))
+               genmalloc(fp, yp);
+
+
+           if (yp -> yp_control_act && yp->yp_control_act->yal_dec) {
+               (void) fprintf (fp, "\t{ SCTRL, %d, 0, FL_USELECT },\n",
+                               control_act(yp->yp_control_act -> yal_dec));
+           }
+           else if (yp->yp_flags & YP_CONTROLLED) {
+               char *f1;
+
+               if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+                   fprintf(stderr, "\ntdec_typ:CHOICE: can't extract field from %s\n",
+                           yp->yp_control);
+                   exit(1);
+               }
+               (void) fprintf(fp, "\t{ SCTRL, OFFSET(%s, %s), 0, 0 },\n",
+                              yp->yp_structname, f1);
+           } else if (yp->yp_structname != NULL)
+               (void) fprintf(fp,"\t{ SCTRL, OFFSET(%s, offset), 0, 0 },\n",
+                              yp->yp_structname);
+           else
+               ferr(1, "\nCHOICE missing SCTRL\n");
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                           "\ntdec_typ:CHOICE can't extract direct type from %s\n",
+                           yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tdec_typ:YP_CHOICE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           tdec_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       break;
+
+    default:
+       ferrd(1, "tdec_typ: yp_code = %d  not implemented\n", yp->yp_code);
+    }
+
+    if (p1 != NULL) {
+       prnte(fp, t, f, yp, p1);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+    }
+
+    if (yp->yp_aft_alist && yp->yp_aft_alist->yal_dec)
+       gen_act(fp, yp->yp_aft_alist->yal_dec);
+
+}
+
+/*
+ * generate tables for encoding a contructed type
+ */
+YP 
+tdec_loop(fp, yp, id, type)
+FILE   *fp;
+YP      yp;
+char   *id;
+char   *type;
+{
+    for (; yp != NULL; yp = yp->yp_next) {
+       tdec_typ(fp, yp, id, type);
+    }
+}
+/*
+ * Generate a malloc of for the given object
+ */
+genmalloc(fp, yp)
+FILE   *fp;
+YP      yp;
+{
+    if (hasdatstr(yp))
+       (void) fprintf(fp, "\t{ MEMALLOC, 0, sizeof (%s), 0 },\n",
+           yp->yp_structname);
+}
+/*
+ * Has Data Structure,
+ * determine if this type needs a data structure allocated to it - calls
+ * itself recursively to handle the cases of pulled up types
+ * returns non zero if it does need a type allocated for it
+ */
+hasdatstr(yp)
+YP      yp;
+{
+    YP     y;
+    YP yp1;
+    struct univ_typ    *p;
+
+   switch (yp -> yp_code) {
+       case YP_BIT: 
+       case YP_BITLIST: 
+       case YP_SEQ: 
+       case YP_SET: 
+       case YP_ANY: 
+       case YP_OCT: 
+       case YP_OID: 
+           break;
+
+       case YP_IDEFINED: 
+
+       yp1 = lkup(yp);
+
+       if (yp1->yp_code == YP_IDEFINED) {
+           if ((p = univtyp(yp1->yp_identifier)) == NULL
+             || p->univ_type <= YP_UNDF) {
+                   return (1); /* we can't tell unless we know what this is */
+                   /* ferr(0, "\tcomptag:treated as implicit\n"); */
+               }
+               if (p->univ_flags & UNF_HASDATA)
+                   return (1);
+               return (0);
+       } else
+           return (hasdatstr(yp1));
+
+       case YP_SEQLIST: 
+       case YP_SETLIST: 
+       case YP_CHOICE: 
+           if (hflag && (y = yp -> yp_type) && !y -> yp_next) {
+               return (hasdatstr(y));
+           }
+           /* else fall */
+
+       default: 
+           return (1);
+    }
+    return (0);
+}
+
+int control_act (act)
+Action act;
+{
+    register char *p;
+
+    for (p = act -> a_data; *p; p++)
+       if (!isspace (*p) && *p == '0')
+           return -1;
+    return act -> a_num;
+}
+
+/*
+ * generate an entry for the freeing routines
+ * if there is a freeing function just call that
+ * if not specify the type and offset so the free routines know how to free it
+ * return non zero if we don't want the normal decoding entry to be
+ * generated after us for freeing purposes.
+ */
+gen_freefn(fp, yp)
+FILE   *fp;
+YP     yp;
+{
+    char       *fn;
+
+    if (yp->yp_yfn && (fn = yp->yp_yfn->yfn_fre)) {
+       (void) fprintf(fp, "\t{ FFN_CALL, %d, 0, 0, },\n", addptr(fn));
+       return (1);     /* don't free as per normal */
+    }
+
+    (void) fprintf(fp, "\t{ FREE_ONLY, 0, 0, 0, },\n");
+    return (0);
+    
+}
+
diff --git a/src/isode/pepsy/enc.c b/src/isode/pepsy/enc.c
new file mode 100644 (file)
index 0000000..0a93af7
--- /dev/null
@@ -0,0 +1,1573 @@
+/* enc.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:30  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:18:57  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:11  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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       "pepsy-driver.h"
+#include       "psap.h"
+#include       "pepsy.h"
+#include       "tailor.h"
+
+#ifndef        PEPYPARM
+#define PEPYPARM       char *
+#endif
+
+
+extern tpe *next_tpe(), *fdflt_f();
+char   *idname(), *clname();
+
+#define NEXT_TPE(p) (p = next_tpe(p))
+#define CHKTAG(mod, p, pe)     ismatch(p, mod, pe->pe_class, pe->pe_id)
+
+static char oomsg[] = "Out of memory";
+#define oom(a,b)       pepsylose ((a), (b), NULLPE, oomsg);
+#define RET_OK(rpe, pe)                *(rpe) = (pe), (OK)
+
+static int en_obj ();
+static int en_type();
+static int en_seq();
+static int en_set();
+static int en_seqof();
+static int en_setof();
+static int en_choice();
+static int en_etype();
+
+/*
+ * encode the specified type of the specified module into the given
+ * pe
+ */
+enc_f(typ, mod, pe, explicit, len, buf, parm)
+/* ARGSUSED */
+int     typ;                   /* which type it is */
+modtyp *mod;                   /* Module it is from */
+register PE *pe;
+int     explicit;
+int     len;
+char   *buf;
+char   *parm;
+{
+    register tpe *p;
+
+    if (typ < 0 || typ >= mod->md_nentries) {
+       (void) pepsylose (mod, NULLTPE, NULLPE, "enc_f:Illegal typ %d", typ);
+       return NOTOK;
+    }
+
+    p = mod->md_etab[typ];
+    if (p->pe_type != PE_START) {
+       return (pepsylose (mod, NULLTPE, NULLPE, "enc_f: missing PE_START"));
+    }
+    p++;
+
+    return (en_obj(parm, p, mod, pe));
+}
+
+/*
+ * Encode an object. If the object is a simple type it may have a
+ * compressed type reference. If it is a compound type it will not
+ * have an offset. This is very important as it means we cannot just
+ * use en_type to handle this which must always assume the field can
+ * have an offset.
+ */
+static int
+en_obj(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    PE      pe = NULLPE;       /* for pepsylose calls */
+    int     cnt = 0;
+    tpe    *tmp;
+
+    DLOG (psap_log, LLOG_DEBUG, ("en_obj: type %d", p->pe_type));
+
+    *rpe = NULLPE;     /* default case */
+
+    while (p->pe_type != PE_END) {
+
+       switch (p->pe_type) {
+       case PE_END:
+       case PE_START:
+           return (pepsylose (mod, p, pe, "en_obj:END/START type"));
+
+       /*
+        * This allows Functions to be called at the very end of the 
+        * encoding -- With the encoded data - very messy
+        */
+       case UCODE:
+           if (mod->md_eucode == NULLIFP
+           || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       default:
+           if (en_type(parm, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+       }
+       if (ISDTYPE(p) && cnt++ > 0)
+           return pepsylose (mod, p, NULLPE, "en_obj:compound type found");
+
+       if (ISDTYPE(p)) {
+           if (pe == NULLPE)
+               return pepsylose (mod, p, NULLPE,
+                                 "en_obj: missing mandatory value");
+       }
+       /* make sure any final UCODEs get run
+       if (ISDTYPE(p) && pe != NULLPE)
+           return (RET_OK(rpe, pe));
+        */
+
+       if (NEXT_TPE(p) == NULLTPE)
+           goto bad;
+    }
+
+    return (RET_OK(rpe, pe));
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Encode a single type. If a basic type encode it, if a compound
+ * type call the appropriate encoding routine
+ */
+static int
+en_type(parm, p, mod, rpe)
+register PEPYPARM parm;
+register tpe    *p;
+register modtyp *mod;                  /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    PE      pe = NULLPE;
+    int     cnt = 0;
+    int     i;                 /* Integer for encoding type */
+    tpe    *tmp;
+    char   *cp;
+
+    DLOG (psap_log, LLOG_DEBUG, ("Encoding the type %d", p->pe_type));
+
+    *rpe = NULLPE;
+    while (p->pe_type != PE_END) {
+
+       switch (p->pe_type) {
+       case PE_END:
+       case PE_START:
+           return (pepsylose (mod, p, pe, "en_type:END/START type"));
+
+       case DFLT_F:
+           tmp = p;
+           p = FDFLT_F(p);
+           if ((i = same(p, tmp, parm, mod)) == NOTOK)
+               return (NOTOK); /* Error */
+           if (i)
+               return (RET_OK(rpe, NULLPE));/* don't encode it */
+           p = tmp + 1;
+           continue;
+
+       case BOPTIONAL:
+           if (IF_USELECT(p)) {
+               if (mod -> md_eucode == NULLIFP)
+                   goto bad;
+               if ((*mod->md_eucode) (parm, &pe, p) == 0)
+                   return (RET_OK(rpe,NULLPE)); /* don't encode it */
+           } else if (!OPT_PRESENT(p, parm))
+               return (RET_OK(rpe, NULLPE));/* don't encode it */
+           p++; /* encode it */
+           continue;
+
+       case UCODE:
+           if (mod->md_eucode == NULLIFP
+           || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       case ETAG:
+           if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
+               return oom (mod, p);
+
+           switch (p->pe_ucode) {
+
+           default:
+               p++;
+               if (en_etype(parm, p, mod, &pe->pe_cons) == NOTOK)
+                   goto bad;
+           }
+           break;
+
+       case SEQ_START:
+           if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQOF_START:
+           if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SET_START:
+           if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SETOF_START:
+           if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SSEQ_START:
+           if (en_seq(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SSEQOF_START:
+           if (en_seqof(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SSET_START:
+           if (en_set(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SSETOF_START:
+           if (en_setof(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case IMP_OBJ:
+           tmp = p++;
+           if (p->pe_type == EXTOBJ) {
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                     0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
+                     return (NOTOK);
+           } else if (p->pe_type == SEXTOBJ) {
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                     0, (char *)0, (parm + p->pe_ucode)) == NOTOK)
+                     return (NOTOK);
+           } else if (p->pe_type == SOBJECT) {
+               if (en_obj((char *) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1, mod, &pe)
+                 == NOTOK)
+                    goto bad;;
+           } else
+               if (en_obj(*(char **) (parm + p->pe_ucode),
+                       mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                   goto bad;
+
+           pe->pe_class = CLASS(tmp);
+           pe->pe_id = TAG(tmp);
+           break;
+
+       case SOBJECT:
+           if (en_obj((char *) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1, mod, &pe)
+             == NOTOK)
+               goto bad;
+           break;
+
+       case OBJECT:
+           if (en_obj(*(char **) (parm + p->pe_ucode),
+             mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case CHOICE_START:
+           if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) ==NOTOK)
+               goto bad;
+           break;
+
+       case SCHOICE_START:
+           if (en_choice(parm + p->pe_ucode, p, mod, &pe) ==NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_seq: missing EXTMOD");
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                 (char *) (parm + p->pe_ucode)) == NOTOK)
+                 return (NOTOK);
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_seq: missing EXTMOD");
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                 *(char **) (parm + p->pe_ucode)) == NOTOK)
+                 return (NOTOK);
+           break;
+
+       case INTEGER:
+           DLOG (psap_log, LLOG_DEBUG,
+               ("en_type:INTEGER offset is %d, value is %d",
+                               p->pe_ucode, *(integer *)(parm + p->pe_ucode)));
+
+           if ((pe = num2prim(*(integer *) (parm + p->pe_ucode),
+                              CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+#ifdef PEPSY_REALS
+       case REALTYPE:
+           DLOG (psap_log, LLOG_DEBUG, ("en_type:REAL: offset %d value %g",
+                                        p->pe_ucode,
+                                        *(double *) (parm + p->pe_ucode)));
+
+           if ((pe = real2prim(*(double *) (parm + p->pe_ucode),
+                              CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+#endif
+       case BOOLEAN:
+           DLOG (psap_log, LLOG_DEBUG, ("en_type:BOOLEAN:offset %d value %d",
+                                        p->pe_ucode,
+                                        *(char *) (parm + p->pe_ucode)));
+           if ((pe = flag2prim(*(char *) (parm + p->pe_ucode),
+                               CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case T_NULL:
+           DLOG (psap_log, LLOG_DEBUG, ("en_type:NULL:offset %d",p->pe_ucode));
+
+           if ((pe = pe_alloc(CLASS(p), PE_FORM_PRIM,
+                              TAG(p))) == NULLPE)
+               return oom(mod,p);
+
+           break;
+
+       case SANY:
+           (pe = (PE) (parm + p->pe_ucode))->pe_refcnt++;
+           break;
+
+       case ANY:
+           if ((parm + p->pe_ucode) == 0 || *(PE *) (parm + p->pe_ucode) == 0)
+#if ROSAP_HACK
+               /* hack for ROSAP. expects this strangeness */
+               pe = pe_alloc(PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL);
+#else
+               pe = NULLPE;
+#endif
+           else
+               (pe = *(PE *) (parm + p->pe_ucode))->pe_refcnt++;
+           break;
+
+       case SOCTETSTRING:
+           if ((pe = qb2prim((struct qbuf *) (parm + p->pe_ucode), CLASS(p), TAG(p)))
+               == NULLPE)
+               return oom(mod, p)
+           break;
+
+       case OCTETSTRING:
+           if ((pe = qb2prim(*(struct qbuf **) (parm + p->pe_ucode),
+                             CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case T_STRING:
+           if (*(char **) (parm + p->pe_ucode) == NULLCP)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:T_STRING missing pointer");
+           if ((pe = str2prim(*(char **) (parm + p->pe_ucode),
+                             strlen(*(char **) (parm + p->pe_ucode)),
+                             CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case OCTET_PTR:
+           if (p[1].pe_type != OCTET_LEN)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:missing OCTET_LEN");
+
+           if (*(char **) (parm + p->pe_ucode) == NULLCP)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:OCTET_PTR  missing pointer");
+
+           if (*(int *) (parm + (p + 1)->pe_ucode) < 0)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:OCTET_LEN negative length");
+
+           if ((pe = str2prim(*(char **) (parm + p->pe_ucode),
+                             *(int *) (parm + (p + 1)->pe_ucode),
+                             CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case BITSTR_PTR:
+           if (p[1].pe_type != BITSTR_LEN)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:missing BITSTR_LEN");
+
+           if (*(char **) (parm + p->pe_ucode) == NULLCP)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:BITSTR_PTR  missing pointer");
+
+           if (*(int *) (parm + (p + 1)->pe_ucode) < 0)
+               return pepsylose (mod, &p[1], NULLPE,
+                                 "en_type:BITSTR_LEN negative length");
+
+           if ((pe = strb2bitstr(*(char **) (parm + p->pe_ucode),
+                             *(int *) (parm + (p + 1)->pe_ucode),
+                             CLASS(p), TAG(p))) == NULLPE
+               || (pe = bit2prim(pe)) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case SBITSTRING:
+           if ((cp = bitstr2strb((PE) (parm + p->pe_ucode), &i)) == NULL)
+               return oom(mod, p);
+           if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           free(cp);
+           if ((pe = bit2prim(pe)) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case BITSTRING:
+           if ((cp = bitstr2strb(*(PE *) (parm + p->pe_ucode), &i))
+               == NULL)
+               return oom(mod, p);
+
+           if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+
+           free(cp);
+           if ((pe = bit2prim(pe)) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case SOBJID:
+           if ((pe = obj2prim((OID) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case OBJID:
+           if ((pe = obj2prim(*(OID *) (parm + p->pe_ucode), CLASS(p), TAG(p)))
+               == NULLPE)
+               return oom(mod, p);
+           break;
+
+       case FN_CALL:
+           if ((FN_PTR(mod, p))(parm, &pe) == NOTOK)
+               return pepsylose (mod, p, NULLPE,
+                                 "en_type:FN_CALL:call failed");
+           if (STAG(p) >= 0) {
+               pe->pe_class = CLASS(p);
+               pe->pe_id = TAG(p);
+           }
+           break;
+
+       default:
+           return pepsylose (mod, p, NULLPE, "en_type: type not implemented");
+       }
+       if (ISDTYPE(p) && cnt++ > 0)
+           return pepsylose (mod, p, NULLPE, "en_type:compound type found");
+
+       if (ISDTYPE(p)) {
+           if (pe == NULLPE)
+               return pepsylose (mod, p, NULLPE,
+                                 "en_type: missing mandatory value");
+       }
+       if (ISDTYPE(p) && pe != NULLPE)
+           return (RET_OK(rpe, pe));
+       if (NEXT_TPE(p) == NULLTPE)
+           goto bad;
+    }
+
+    return (RET_OK(rpe, pe));
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Build a sequence, calling appropriate routines to build each sub
+ * type
+ */
+static int
+en_seq(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    PE      head;
+    PE      pe = NULLPE;
+    tpe    *tmp;               /* first entry in list */
+    int    *popt = NULL;       /* Pointer to optional field */
+    int     optcnt = 0;                /* Number of optionals bits so far */
+    int            val;
+
+    if (p->pe_type != SEQ_START && p->pe_type != SSEQ_START)
+           return (pepsylose (mod, p, pe, "en_seq: missing SEQ_START\n"));
+
+    if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
+       return oom (mod, p);
+    p++;
+
+    while (p->pe_type != PE_END) {
+
+       DLOG (psap_log, LLOG_DEBUG, ("en_seq type%d", p->pe_type));
+
+       if (ISDTYPE(p) && OPTIONAL(p)) {
+           switch (p->pe_type) {
+           case INTEGER:
+           case REALTYPE:
+           case BOOLEAN:
+           case T_NULL:
+               if (!TESTBIT(*popt, optcnt++))
+                   goto next;  /* Missing so skip */
+               break;
+
+           case FN_CALL:
+               if ((val = hasdata(parm, p, mod, popt, &optcnt)) == NOTOK)
+                   goto bad;
+               if (val == 0)
+                   goto next;
+               break;
+
+           case ETAG:
+               if ((val = hasdata(parm, p + 1, mod, popt, &optcnt)) == NOTOK)
+                   goto bad;
+               if (val == 0)
+                   goto next;
+               break;
+
+           case IMP_OBJ:
+               if (p[1].pe_type == SOBJECT && parm == NULL
+                   || *((char **) (parm + p[1].pe_ucode)) == NULL)
+                   goto next;
+               break;
+
+           case SOBJECT:
+               if (((char *) parm) == NULL)
+                   goto next;
+               break;
+
+           default:
+               if (*((char **) (parm + p->pe_ucode)) == NULL)
+                   goto next;
+               break;
+           }
+       }
+       switch (p->pe_type) {
+       case OPTL:
+           popt = (int *) (parm + p->pe_ucode);
+           break;
+
+       case UCODE:
+           if (mod->md_eucode == NULLIFP
+           || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       case ETAG:
+           if (en_type(parm, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQ_START:
+           if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQOF_START:
+           if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SET_START:
+           if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SETOF_START:
+           if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case IMP_OBJ:
+           tmp = p++;
+           if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                     0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
+                     return (NOTOK);
+           } else if (p->pe_type == SOBJECT) {
+               if (en_obj((char *) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1, mod,
+                     &pe) == NOTOK)
+                   goto bad;
+           } else
+               if (en_obj(*(char **) (parm + p->pe_ucode),
+                       mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                   goto bad;
+           pe->pe_class = CLASS(tmp);
+           pe->pe_id = TAG(tmp);
+           break;
+
+       case SOBJECT:
+           if (en_obj((char *) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1, mod, &pe)
+                   == NOTOK)
+               goto bad;
+           break;
+
+       case OBJECT:
+           if (en_obj(*(char **) (parm + p->pe_ucode),
+                   mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case CHOICE_START:
+           if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SCHOICE_START:
+           if (en_choice((char *) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, &p[1], NULLPE, "en_seq: missing EXTMOD");
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                 (char *) (parm + p->pe_ucode)) == NOTOK)
+                 return (NOTOK);
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, &p[1], NULLPE, "en_seq: missing EXTMOD");
+
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                 *(char **) (parm + p->pe_ucode)) == NOTOK)
+                 return (NOTOK);
+           break;
+
+       default:
+           if (en_type(parm, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+       }
+
+       if ((ISDTYPE(p) || p->pe_type == BOPTIONAL) && pe != NULLPE) {
+           if (seq_add(head, pe, -1) == NOTOK)
+               return pepsylose (mod, p, NULLPE, "en_seq bad sequence: %s",
+                      pe_error(pe->pe_errno));
+       }
+next:
+       if (NEXT_TPE(p) == NULLTPE)
+           return (NOTOK);
+    }
+
+    return (RET_OK(rpe, head));
+
+bad:
+    return (NOTOK);
+}
+
+
+/*
+ * Parse a set, calling appropriate routines to parse each sub type
+ */
+static int
+en_set(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    PE      head;
+    PE      pe = NULLPE;
+    tpe    *tmp;
+    int    *popt = NULL;       /* Pointer to optional field */
+    int     optcnt = 0;                /* Number of optionals bits so far */
+    int            val;
+
+    if (p->pe_type != SET_START && p->pe_type != SSET_START)
+       return pepsylose (mod, p, pe, "en_set: missing SET_START");
+
+    if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
+       return oom(mod, p);
+
+    p++;
+    while (p->pe_type != PE_END) {
+
+       DLOG (psap_log, LLOG_DEBUG, ("en_set type %d", p->pe_type));
+
+       if (ISDTYPE(p) && OPTIONAL(p)) {
+           switch (p->pe_type) {
+           case INTEGER:
+           case REALTYPE:
+           case BOOLEAN:
+           case T_NULL:
+               if (!TESTBIT(*popt, optcnt++))
+                   goto next;  /* Missing so skip */
+               break;
+
+           case FN_CALL:
+               if ((val = hasdata(parm, p, mod, popt, &optcnt)) == NOTOK)
+                   goto bad;
+               if (val == 0)
+                   goto next;
+               break;
+
+           case ETAG:
+               if ((val = hasdata(parm, p + 1, mod, popt, &optcnt)) == NOTOK)
+                   goto bad;
+               if (val == 0)
+                   goto next;
+               break;
+
+           case IMP_OBJ:
+               if (p[1].pe_type == SOBJECT && parm == NULL
+                   || *((char **) (parm + p[1].pe_ucode)) == NULL)
+                   goto next;
+               break;
+
+           case SOBJECT:
+               if (((char *) (parm + p->pe_ucode)) == NULL)
+                   goto next;
+               break;
+
+           default:
+               if (*((char **) (parm + p->pe_ucode)) == NULL)
+                   goto next;
+               break;
+           }
+       }
+       switch (p->pe_type) {
+       case OPTL:
+           popt = (int *) (parm + p->pe_ucode);
+           break;
+
+       case UCODE:
+           if (mod->md_eucode == NULLIFP
+           || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       case ETAG:
+           if (en_type(parm, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQ_START:
+           if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQOF_START:
+           if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SET_START:
+           if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SETOF_START:
+           if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case IMP_OBJ:
+           tmp = p++;
+           if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                     0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
+                     return (NOTOK);
+           } else if (p->pe_type == SOBJECT) {
+               if (en_obj((char *) parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod,
+                       &pe) == NOTOK)
+                   goto bad;
+           } else
+               if (en_obj(*(char **) (parm + p->pe_ucode),
+                       mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                   goto bad;
+           pe->pe_class = CLASS(tmp);
+           pe->pe_id = TAG(tmp);
+           break;
+
+       case SOBJECT:
+           if (en_obj(parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case OBJECT:
+           if (en_obj(*(char **) (parm + p->pe_ucode),
+                   mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case CHOICE_START:
+           if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) ==NOTOK)
+               goto bad;
+           break;
+
+
+       case SCHOICE_START:
+           if (en_choice((char *) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD)
+               return pepsylose (mod, p, NULLPE, "en_set: missing EXTMOD");
+
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                 parm + p->pe_ucode) == NOTOK)
+                 return (NOTOK);
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD) 
+               return pepsylose (mod, p, NULLPE, "en_set: missing EXTMOD");
+
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                 *(char **) (parm + p->pe_ucode)) == NOTOK)
+                 return (NOTOK);
+           break;
+
+       default:
+           if (en_type(parm, p, mod, &pe) == NOTOK)
+               goto bad;
+           break;
+       }
+
+       if ((ISDTYPE(p) || p->pe_type == BOPTIONAL) && pe != NULLPE) {
+           if (set_add(head, pe) == NOTOK)
+               return pepsylose (mod, p, NULLPE, "en_set bad set: %s",
+                                 pe_error(pe->pe_errno));
+       }
+next:
+       NEXT_TPE(p);
+    }
+
+    return (RET_OK(rpe, head));
+
+bad:
+    return (NOTOK);
+}
+
+
+/*
+ * Parse a sequence of calling appropriate routines to parse each sub
+ * type
+ */
+static int
+en_seqof(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    PE      head;
+    PE      pe = NULLPE;
+    tpe    *start;             /* first entry in list */
+    tpe    *tmp;
+
+    if (p->pe_type != SEQOF_START && p->pe_type != SSEQOF_START)
+       return pepsylose (mod, p, NULLPE, "en_seqof: missing SEQOF_START");
+
+    if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
+       return oom(mod, p);
+
+    start = p;
+    while ((char *) parm != NULL) {
+       p++;
+       while (p->pe_type != PE_END) {
+
+           DLOG (psap_log, LLOG_DEBUG, ("en_seqof type%d", p->pe_type));
+
+           switch (p->pe_type) {
+           case UCODE:
+               if (mod->md_eucode == NULLIFP
+               || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+                   goto bad;
+               break;
+
+           case ETAG:
+               if (en_type(parm, p, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+
+           case SEQ_START:
+               if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
+                   goto bad;
+               break;
+
+           case SEQOF_START:
+               if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
+                       == NOTOK)
+                   goto bad;
+               break;
+
+           case SET_START:
+               if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
+                   goto bad;
+               break;
+
+           case SETOF_START:
+               if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
+                       == NOTOK)
+                   goto bad;
+               break;
+
+           case IMP_OBJ:
+               tmp = p++;
+               if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
+                   if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                      0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
+                      return (NOTOK);
+               } else if (p->pe_type == SOBJECT) {
+                   if (en_obj((char *) (parm + p->pe_ucode), mod->md_etab[p->pe_tag] + 1,
+                           mod, &pe) == NOTOK)
+                       goto bad;
+               } else if (en_obj(*(char **) (parm + p->pe_ucode),
+                           mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                       goto bad;
+               pe->pe_class = CLASS(tmp);
+               pe->pe_id = TAG(tmp);
+               break;
+
+           case SOBJECT:
+               if (en_obj(parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod, &pe) ==NOTOK)
+                   goto bad;
+               break;
+
+           case OBJECT:
+               if (en_obj(*(char **) (parm + p->pe_ucode),
+                       mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+
+           case CHOICE_START:
+               if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe)
+                       == NOTOK)
+                   goto bad;
+               break;
+
+
+           case SCHOICE_START:
+               if (en_choice((char *) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p+1, NULLPE,
+                                     "en_seqof: missing EXTMOD");
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                     parm + p->pe_ucode) == NOTOK)
+                     return (NOTOK);
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD) 
+                   return pepsylose (mod, p+1, NULLPE,
+                                     "en_seqof: missing EXTMOD");
+
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                     *(char **) (parm + p->pe_ucode)) == NOTOK)
+                     return (NOTOK);
+               break;
+
+           default:
+               if (en_type(parm, p, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+           }
+           if (ISDTYPE(p) && pe != NULLPE) {
+               if (seq_add(head, pe, -1) == NOTOK)
+                   return pepsylose (mod, p, NULLPE,
+                                     "en_seqof bad sequence: %s",
+                                     pe_error(pe->pe_errno));
+           }
+           if (NEXT_TPE(p) == NULLTPE)
+               goto bad;
+       }
+       parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
+       p = start;
+    }
+
+    return (RET_OK(rpe, head));
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse a setof, calling appropriate routines to parse each sub type
+ */
+static int
+en_setof(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    PE      head;
+    PE      pe = NULLPE, last = NULLPE;
+    tpe    *start;
+    tpe    *tmp;
+
+    if (p->pe_type != SETOF_START && p->pe_type != SSETOF_START)
+       return pepsylose (mod, p, NULLPE, "en_setof: missing SETOF_START");
+
+    if ((head = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
+       return oom(mod,p);
+
+    start = p;
+    while ((char *) parm != NULL) {
+       p++;
+       while (p->pe_type != PE_END) {
+           DLOG (psap_log, LLOG_DEBUG, ("en_setof type%d",
+                                        p->pe_type));
+
+           switch (p->pe_type) {
+           case UCODE:
+               if (mod->md_eucode == NULLIFP
+               || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+                   goto bad;
+               break;
+
+           case ETAG:
+               if (en_type(parm, p, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+
+           case SEQ_START:
+               if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
+                   goto bad;
+               break;
+
+           case SEQOF_START:
+               if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
+                       == NOTOK)
+                   goto bad;
+               break;
+
+           case SET_START:
+               if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe)==NOTOK)
+                   goto bad;
+               break;
+
+           case SETOF_START:
+               if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe)
+                       == NOTOK)
+                   goto bad;
+               break;
+
+           case IMP_OBJ:
+               tmp = p++;
+               if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
+                   if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                      0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
+                      return (NOTOK);
+               } else if (p->pe_type == SOBJECT) {
+                   if (en_obj((char *) parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1,
+                           mod, &pe) == NOTOK)
+                       goto bad;
+               } else
+                   if (en_obj(*(char **) (parm + p->pe_ucode),
+                           mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                       goto bad;
+               pe->pe_class = CLASS(tmp);
+               pe->pe_id = TAG(tmp);
+               break;
+
+           case SOBJECT:
+               if (en_obj(parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod, &pe) ==NOTOK)
+                   goto bad;
+               break;
+
+           case OBJECT:
+               if (en_obj(*(char **) (parm + p->pe_ucode),
+                       mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+
+           case CHOICE_START:
+               if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe)
+                       == NOTOK)
+                   goto bad;
+               break;
+
+
+           case SCHOICE_START:
+               if (en_choice((char *) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p + 1, NULLPE,
+                                     "en_setof: missing EXTMOD");
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                     parm + p->pe_ucode) == NOTOK)
+                     return (NOTOK);
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD)
+                   return pepsylose (mod, p + 1, NULLPE,
+                                     "en_setof: missing EXTMOD");
+
+               if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+                     *(char **) (parm + p->pe_ucode)) == NOTOK)
+                     return (NOTOK);
+               break;
+
+           default:
+               if (en_type(parm, p, mod, &pe) == NOTOK)
+                   goto bad;
+               break;
+           }
+
+           if (ISDTYPE(p) && pe != NULLPE) {
+               if (set_addon(head, last, pe) == NOTOK)
+                   return pepsylose (mod, p, NULLPE, "en_setof bad set: %s",
+                                     pe_error(pe->pe_errno));
+               else
+                   last = pe;
+           }
+
+           if (NEXT_TPE(p) == NULLTPE)
+               goto bad;;
+       }
+       parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
+       p = start;
+    }
+
+    return (RET_OK(rpe, head));
+
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * encode a choice field. This means find which choice is taken and
+ * call en_type to encode it
+ */
+static int
+en_choice(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    int     cnt;
+
+    if (p->pe_type != CHOICE_START && p->pe_type != SCHOICE_START)
+       return pepsylose (mod, p, NULLPE, "en_choice:missing CHOICE_START");
+    p++;
+    if (p->pe_type != SCTRL)
+       return pepsylose (mod, p, NULLPE, "en_choice:missing SCTRL");
+
+    if (IF_USELECT(p)) {
+       if (mod->md_eucode == NULLIFP ||
+           (cnt = (*mod -> md_eucode) (parm, &rpe, p)) == NOTOK)
+           return pepsylose (mod, p, NULLPE, "choice selection failed");
+    }
+    else
+       cnt = *(int *) (parm + p->pe_ucode);
+
+    DLOG (psap_log, LLOG_DEBUG, ("cnt %d", cnt));
+
+    if (cnt != 0)
+       cnt--;
+    if (cnt < 0)
+       return pepsylose (mod, p, NULLPE, "en_choice:offset %d negative", cnt);
+
+    for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
+       if (cnt == 0 && p->pe_type == UCODE) {
+               if (mod->md_eucode == NULLIFP
+               || (*mod->md_eucode) (parm, &rpe, p) == NOTOK)
+                   return (NOTOK);
+       }
+       if (ISDTYPE(p)) {
+           if (cnt == 0) {
+               if (en_etype(parm, p, mod, rpe) == NOTOK)
+                   return (NOTOK);
+               return (OK);
+           }
+           cnt--;
+       }
+    }
+
+    return pepsylose (mod, p, NULLPE, "en_choice: no choice taken");
+}
+
+
+/*
+ * check to see if the object is present or not
+ */
+static int
+chkobj(mod, p, head)
+modtyp *mod;
+tpe    *p;
+PE      head;
+{
+
+    for (; p->pe_type != PE_END; NEXT_TPE(p)) {
+       if (!ISDTYPE(p))
+           continue;
+
+       if (p->pe_type == OBJECT) {
+           if (chkobj(mod, p, head))
+               return (1);
+       } else if (CHKTAG(mod, p, head))
+           return (1);
+
+       if (OPTIONAL(p) || DEFAULT(p))
+           continue;
+
+       return (0);
+    }
+    return (0);
+}
+
+/*
+ * Encode a single type for an explicit tag field If a basic type
+ * encode it, if a compound type call the appropriate encoding
+ * routine. Similar to en_type except we do the indirection on the
+ * ucode field
+ */
+static int
+en_etype(parm, p, mod, rpe)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+PE     *rpe;           /* Return value PE */
+{
+    tpe    *tmp;
+    PE      pe = NULLPE;
+
+    switch (p->pe_type) {
+    case PE_END:
+    case PE_START:
+       return (pepsylose (mod, p, pe, "en_etype:END/START type"));
+
+    case UCODE:
+       if (mod->md_eucode == NULLIFP
+       || (*mod->md_eucode) (parm, &pe, p) == NOTOK)
+           goto bad;
+       break;
+
+    case ETAG:
+       if ((pe = pe_alloc(CLASS(p), PE_FORM_CONS, TAG(p))) == NULLPE)
+           return oom(mod, p);
+       switch (p->pe_ucode) {
+       default:
+           p++;
+           if (en_etype(parm, p, mod, &pe->pe_cons) == NOTOK)
+               goto bad;
+       }
+       break;
+
+    case SEQ_START:
+       if (en_seq(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SEQOF_START:
+       if (en_seqof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SET_START:
+       if (en_set(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SETOF_START:
+       if (en_setof(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SSEQ_START:
+       if (en_seq(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SSEQOF_START:
+       if (en_seqof(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SSET_START:
+       if (en_set(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SSETOF_START:
+       if (en_setof(parm + p->pe_ucode, p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case IMP_OBJ:
+       tmp = p++;
+       if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
+           if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1,
+                 0, (char *)0, *(char **) (parm + p->pe_ucode)) == NOTOK)
+                 return (NOTOK);
+       } else if (p->pe_type == SOBJECT) {
+           if (en_obj((char *) parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod, &pe)
+                   == NOTOK)
+               goto bad;
+       } else
+           if (en_obj(*(char **) (parm + p->pe_ucode),
+                   mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+               goto bad;
+       pe->pe_class = CLASS(tmp);
+       pe->pe_id = TAG(tmp);
+       break;
+
+    case SOBJECT:
+       if (en_obj(parm + p->pe_ucode, mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case OBJECT:
+       if (en_obj(*(char **) (parm + p->pe_ucode),
+               mod->md_etab[p->pe_tag] + 1, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case CHOICE_START:
+       if (en_choice(*(char **) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+           goto bad;
+       break;
+
+    case SCHOICE_START:
+        if (en_choice((char *) (parm + p->pe_ucode), p, mod, &pe) == NOTOK)
+          goto bad;
+      break;
+
+    case INTEGER:
+       DLOG (psap_log, LLOG_DEBUG, ("offset %d value %d",
+                                    p->pe_ucode,
+                                    *(integer *) (parm + p->pe_ucode)));
+       if ((pe = num2prim(*(integer *) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
+           return oom (mod, p);
+
+       break;
+
+#ifdef PEPSY_REALS
+    case REALTYPE:
+       DLOG (psap_log,  LLOG_DEBUG, ("offset %d value %g",
+                                     p->pe_ucode,
+                                     *(double *) (parm + p->pe_ucode)));
+           if ((pe = real2prim(*(double *) (parm + p->pe_ucode),
+                              CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           break;
+
+#endif
+    case BOOLEAN:
+       DLOG (psap_log, LLOG_DEBUG, ("offset %d value %d",
+                                    p->pe_ucode,
+                                    *(char *) (parm + p->pe_ucode)));
+
+       if ((pe = flag2prim(*(char *) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case T_NULL:
+       DLOG (psap_log, LLOG_DEBUG, ("offset %d", p->pe_ucode));
+       if ((pe = pe_alloc(CLASS(p), PE_FORM_PRIM, TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case SANY:
+       (pe = (PE) (parm + p->pe_ucode))->pe_refcnt++;
+       break;
+
+    case ANY:
+       if ((parm + p->pe_ucode) == 0 || *(PE *) (parm + p->pe_ucode) == 0)
+#if ROSAP_HACK
+           /* hack for ROSAP. expects this strangeness */
+           pe = pe_alloc(PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL);
+#else
+           pe = NULLPE;
+#endif
+       else
+           (pe = *(PE *) (parm + p->pe_ucode))->pe_refcnt++;
+       break;
+
+    case SEXTOBJ:
+       if (p[1].pe_type != EXTMOD)
+           return pepsylose (mod, p+1, NULLPE, "en_etype: missing EXTMOD");
+       if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+           parm + p->pe_ucode) == NOTOK)
+           return (NOTOK);
+       break;
+
+    case EXTOBJ:
+       if (p[1].pe_type != EXTMOD)
+           return pepsylose (mod, p+1, NULLPE, "en_etype: missing EXTMOD");
+       if (enc_f(p->pe_tag, EXT2MOD(mod, (p + 1)), &pe, 1, 0, (char *)0,
+             *(char **) (parm + p->pe_ucode)) == NOTOK)
+             return (NOTOK);
+       break;
+
+    case SOCTETSTRING:
+       if ((pe = qb2prim((struct qbuf *) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case SBITSTRING:
+       {
+           char   *cp;
+           int     i;
+
+           if ((cp = bitstr2strb((PE) (parm + p->pe_ucode), &i)) == NULL)
+               return oom(mod, p);
+           if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           free(cp);
+           if ((pe = bit2prim (pe)) == NULLPE)
+               return oom(mod, p);
+       }
+       break;
+
+    case OCTETSTRING:
+       if ((pe = qb2prim(*(struct qbuf **) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case T_STRING:
+       if (*(char **) (parm + p->pe_ucode) == NULLCP)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype:T_STRING missing pointer");
+
+       if ((pe = str2prim(*(char **) (parm + p->pe_ucode),
+                         strlen(*(char **) (parm + p->pe_ucode)),
+                         CLASS(p), TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case OCTET_PTR:
+       if (p[1].pe_type != OCTET_LEN)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype: missing OCTET_LEN");
+
+       if (*(char **) (parm + p->pe_ucode) == NULLCP)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype:OCTET_PTR missing pointer");
+
+       if (*(int *) (parm + (p + 1)->pe_ucode) < 0)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype:OCTET_LEN negative length");
+
+       if ((pe = str2prim(*(char **) (parm + p->pe_ucode),
+                         *(int *) (parm + (p + 1)->pe_ucode),
+                         CLASS(p), TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case BITSTR_PTR:
+       if (p[1].pe_type != BITSTR_LEN)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype:missing BITSTR_LEN");
+
+       if (*(char **) (parm + p->pe_ucode) == NULLCP)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype:BITSTR_PTR  missing pointer");
+
+       if (*(int *) (parm + (p + 1)->pe_ucode) < 0)
+           return pepsylose (mod, &p[1], NULLPE,
+                             "en_etype:BITSTR_LEN negative length");
+
+       if ((pe = strb2bitstr(*(char **) (parm + p->pe_ucode),
+                         *(int *) (parm + (p + 1)->pe_ucode),
+                         CLASS(p), TAG(p))) == NULLPE
+           || (pe = bit2prim(pe)) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case BITSTRING:
+       {
+           char   *cp;
+           int     i;
+
+           if ((cp = bitstr2strb(*(PE *) (parm + p->pe_ucode), &i)) == NULL)
+               return oom(mod, p);
+           if ((pe = strb2bitstr(cp, i, CLASS(p), TAG(p))) == NULLPE)
+               return oom(mod, p);
+           free(cp);
+           if ((pe = bit2prim(pe)) == NULLPE)
+               return oom(mod, p);
+       }
+       break;
+
+    case SOBJID:
+       if ((pe = obj2prim((OID) (parm + p->pe_ucode), CLASS(p), TAG(p))) == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case OBJID:
+       if ((pe = obj2prim(*(OID *) (parm + p->pe_ucode), CLASS(p), TAG(p)))
+           == NULLPE)
+           return oom(mod, p);
+       break;
+
+    case FN_CALL:
+       if ((FN_PTR(mod, p))(parm, &pe) == NOTOK)
+           return pepsylose (mod, p, NULLPE,
+                             "en_etype:FN_CALL:call failed");
+       if (STAG(p) >= 0) {
+           pe->pe_class = CLASS(p);
+           pe->pe_id = TAG(p);
+       }
+       break;
+
+    default:
+       return pepsylose (mod, p, NULLPE, "en_etype: type not implemented");
+    }
+    return (RET_OK(rpe, pe));
+
+bad:
+    return (NOTOK);
+}
diff --git a/src/isode/pepsy/etabs.c b/src/isode/pepsy/etabs.c
new file mode 100644 (file)
index 0000000..806e5ac
--- /dev/null
@@ -0,0 +1,2284 @@
+/* etabs.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:33  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:19:00  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:14  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:55  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include "pepsydefs.h"
+#include "sym.h"
+#include "pass2.h"
+#include "mine.h"
+
+s_table *head;
+
+extern s_table *lookup_list(), *proc_def();
+
+extern char *c_tag(), *c_class();
+extern char *ec_tag(), *ec_class();
+extern char *strip_last();
+extern char *get_val(), *get_comp(), *get_string();
+extern s_table *get_offset();
+extern char *my_strcat(), *strp2name();
+extern char *my_new_str();
+extern char *mymodule;
+extern char *modsym();
+extern char *concat();
+extern char *genlabel();
+extern char *notidtoid();
+extern char *code2name();
+extern char *yp2name();
+extern YV calc_yv();
+extern SY syfind();
+static s_table *en_ptr;
+extern s_table *ptr;
+extern char    *rm_indirect();
+extern char    *getfield();
+extern char    *setfield();
+
+static int cons_type = 0;
+/* int     explicit; */
+
+s_table *save_ptr;
+
+extern YT gen_etag();
+
+#define WORDSIZE       20
+#define MAXNAME                256     /* maximum size of a identifier */
+
+#ifdef DEBUG
+char   *str_yp_code[] = {
+    "Undefined", "Boolean", "Integer", "Named number list", "Bitstring",
+    "Named Bitstring list", "Octet String", "Null", "Sequence",
+    "Sequence of", "Sequence list", "Set", "Set of", "Set list",
+    "Choice", "Any", "Object Identifier",
+    "", "", "", "", "", "", "", "",
+    "", "", "", "", "", "", "", "Identifier",
+
+};
+
+#endif
+
+/*
+ * table encode a type. generate tables for the encoding of a type
+ */
+tenc_typ(fp, yp, id, type)
+FILE   *fp;
+YP      yp;
+char   *id;
+char   *type;
+{
+
+    char   *t, *f;
+    char   *p1;
+    YP      y;
+    YAL                yal;
+
+
+    if (yp->yp_code < 0 || yp->yp_code > YP_REAL)
+       ferrd(1, "tenc_typ: unimplemented type %d\n", yp->yp_code);
+
+    if (yp == NULL) {
+       ferr(0, "tenc_typ:NULL argument\n");
+       return;
+    }
+
+    /* Preserve the type of the containing object */
+    if (type)
+       t = type;
+    else if (yp->yp_param_type) {
+       char *t1;
+       /* we have a [[ P type ]] specification */
+       if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+           fprintf(stderr,
+           "\ntenc_typ:SETLIST can't extract direct type from %s\n",
+               yp->yp_param_type);
+           exit(1);
+       }
+       t = strdup(t1);
+    } else
+       t = my_strcat("struct ", modsym(mymodule, id, "type"));
+
+    if (yal = yp->yp_bef_alist) {
+       yal->yal_type = t;
+       if (yal->yal_enc)
+           gen_act(fp, yp->yp_bef_alist->yal_enc);
+    }
+    if (yal = yp->yp_aft_alist) {
+       yal->yal_type = t;
+    }
+    if (yal = yp->yp_control_act)
+       yal -> yal_type = t;
+
+    if (yal = yp->yp_optional_act)
+       yal -> yal_type = t;
+
+    if (yp->yp_flags & YP_DEFAULT)
+       gdflt(fp, yp, G_ENC);
+
+    if ((yp->yp_flags & YP_PARMVAL) && yp->yp_parm) {
+       if ((f = getfield(yp->yp_parm)) == NULLCP) {
+           fprintf(stderr, "\ntenc_typ: can't extract field from %s\n",
+               yp->yp_parm);
+           exit(1);
+       }
+       f = strdup(f);
+    } else
+       f = yp->yp_varexp;
+
+    if ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+       == (YP_OPTIONAL|YP_OPTCONTROL)) {
+       char    *f1;
+       char    *bitno;
+
+       if (yp -> yp_optional_act && yp -> yp_optional_act -> yal_enc) {
+           fprintf (fp, "\t{ BOPTIONAL, %d, 0, FL_USELECT},\n",
+                    yp -> yp_optional_act -> yal_enc -> a_num);
+       }
+       else {
+           if ((f1 = getfldbit(yp->yp_optcontrol, &bitno)) == NULLCP) {
+               fprintf(stderr,
+                       "\ntenc_typ:BOPTIONAL: can't extract field from %s\n",
+                       yp->yp_optcontrol);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ BOPTIONAL, AOFFSET(%s, %s), %s, 0},\n",
+                          t, f1, bitno);
+       }
+    }
+
+    /* handle explicit tags - one day may have to change this if anyone
+     * ever defines a type with more than one explicit tag
+     */
+    if (yp->yp_flags & YP_TAG && !(yp->yp_flags & YP_IMPLICIT)) {
+       (void) fprintf(fp, "\t{ ETAG, 0, ");
+       (void) fprintf(fp, "%s, %s },\n", ec_tag(yp), ec_class(yp));
+    }
+
+    if (yp->yp_yfn && yp->yp_yfn->yfn_enc) {
+       gen_fn(fp, yp, yp->yp_yfn->yfn_enc);
+
+       if (yp->yp_aft_alist && yp->yp_aft_alist->yal_enc)
+           gen_act(fp, yp->yp_aft_alist->yal_enc);
+
+       return;
+    }
+
+    switch (yp->yp_code) {
+
+    case YP_UNDF:
+       ferr(1, "tenc_typ:Undefined type\n");
+
+    case YP_BOOL:
+       p1 = "BOOLEAN";
+       if (yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tenc_typ:BOOL: must specify a field [[ b .. ]]\n");
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f)))
+           break;
+       ferr(1, "tenc_typ:BOOL: couldn't determine type\n");
+
+    case YP_INTLIST:
+
+    case YP_INT:
+
+    case YP_ENUMLIST:
+       if (yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tenc_typ:INT: must specify a field [[ i .. ]]\n");
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) {
+           p1 = "INTEGER";
+           break;
+       }
+       ferr(1, "tenc_typ:INT: couldn't determine type\n");
+       break;
+
+    case YP_REAL:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (noindirect(f))
+           ferr(1, "tenc_typ:REAL: must specify a field [[ r .. ]]\n");
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "REALTYPE";
+           break;
+       }
+       ferr(1, "tenc_typ:REAL: couldn't determine type\n");
+       break;
+
+    case YP_BIT:
+    case YP_BITLIST:
+       if (yp->yp_strexp && yp->yp_intexp) {
+           if (yp->yp_strexp)
+               f = setfield(yp->yp_strexp);
+           if (noindirect(f))
+               ferr(1, "tenc_typ:BIT: must specify a field [[ x .. ]]\n");
+           p1 = "BITSTR_PTR";
+           prnte(fp, t, f, yp, p1);
+           if (yp->yp_intexp)
+               f = setfield(yp->yp_intexp);
+           if (noindirect(f))
+               ferr(1, "tenc_typ:BIT: must specify a field [[ x .. ]]\n");
+           p1 = "BITSTR_LEN";
+           break;
+       }
+       if (yp->yp_strexp == NULLCP && yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f))) {
+           p1 = "BITSTRING";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SBITSTRING, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_OCT:
+       if (yp->yp_strexp) {
+           switch (yp->yp_prfexp) {
+           case 'q': /* [[ q parm->qbufptr ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   p1 = "SOCTETSTRING";
+               else
+                   p1 = "OCTETSTRING";
+               break;
+
+           case 's': /* [[ s ptr ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   ferr(1, "tenc_typ:OCT: must specify a field [[ s .. ]]\n");
+               p1 = "T_STRING";
+               break;
+               
+           case 'o': /* [[ o ptr $ length ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   ferr(1, "tenc_typ:OCT: must specify a field [[ s .. ]]\n");
+               p1 = "OCTET_PTR";
+               prnte(fp, t, f, yp, p1);
+               if (yp->yp_intexp)
+                   f = setfield(yp->yp_intexp);
+               if (noindirect(f))
+                   ferr(1, "tenc_typ:OCT: must specify a field [[ s .. ]]\n");
+               p1 = "OCTET_LEN";
+               break;
+
+           default:
+              fprintf(stderr,"\ntenc_typ: Unknown Octet string specifier %c\n",
+                  yp->yp_prfexp);
+               exit(1);
+           }
+           break;
+       }
+
+       if (f && !noindirect(f)) {
+           p1 = "OCTETSTRING";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SOCTETSTRING, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_OID:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "OBJID";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SOBJID, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+
+    case YP_SEQ:
+    case YP_SET:
+    case YP_ANY:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "ANY";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SANY, 0, %s, %s },\n",
+               c_tag(yp), c_class(yp));
+       break;
+
+    case YP_NULL:
+       p1 = "T_NULL";
+       t = NULL;
+       break;
+
+    case YP_IDEFINED:
+       p1 = NULL;
+       if ((yp->yp_flags & YP_PARMVAL) && yp->yp_prfexp)
+               ferr(1,
+    "\n[[ ? reference ]] [[ p reference ]] is illegal\n\t only one allowed\n");
+
+       if (yp->yp_prfexp) { /* [[ ? parm->field ]] - complex to process */
+           gen_identry(fp, t, f, yp, gen_ventry);
+           break;
+       }
+
+       {
+           /* Predefined Universal Type */
+           struct univ_typ *p, *univtyp();
+
+           if ((p = univtyp(yp->yp_identifier))) {
+               if (p->univ_flags & UNF_EXTMOD) {
+                   yp->yp_module = p->univ_mod;
+                   goto do_obj;
+               }
+               if (f == NULL || noindirect(f)) {/* No offset type */
+                   if (yp->yp_flags & YP_TAG
+                       && yp->yp_flags & YP_IMPLICIT)
+                               prstfield(fp, p->univ_tab, t, f,
+                               int2tstr(yp->yp_tag->yt_value->yv_number),
+                               c_flags(yp, yp->yp_tag->yt_class));
+                       /*
+                       (void) fprintf(fp, "\t{ S%s, 0, %d, %s },\n",
+                               p->univ_tab,
+                               yp->yp_tag->yt_value->yv_number,
+                               c_flags(yp, yp->yp_tag->yt_class));
+                        */
+                   else
+                       prstfield(fp, p->univ_tab, t, f,
+                                 int2tstr((int)p->univ_id),
+                                 c_flags(yp, p->univ_class));
+                       /*
+                       (void) fprintf(fp, "\t{ S%s, 0, %d, %s },\n",
+                               p->univ_tab, p->univ_id,
+                               c_flags(yp, p->univ_class));
+                        */
+                   break;
+               }
+               if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
+                       prtfield(fp, p->univ_tab, t, f,
+                           int2tstr(yp->yp_tag->yt_value->yv_number),
+                           c_flags(yp, yp->yp_tag->yt_class));
+                   /*
+                   (void) fprintf(fp, "\t{ %s, OFFSET(%s, %s), %d, %s },\n",
+                           p->univ_tab, t, f,
+                           yp->yp_tag->yt_value->yv_number,
+                           c_flags(yp, yp->yp_tag->yt_class));
+                    */
+               else
+                   prtfield(fp, p->univ_tab, t, f, int2tstr((int)p->univ_id),
+                           c_flags(yp, p->univ_class));
+                   /*
+                   (void) fprintf(fp, "\t{ %s, OFFSET(%s, %s), %d, %s },\n",
+                           p->univ_tab, t, f, p->univ_id,
+                           c_flags(yp, p->univ_class));
+                    */
+               break;
+           }
+       }
+do_obj:
+       if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
+           (void) fprintf(fp, "\t{ IMP_OBJ, 0, %s, %s },\n", c_tag(yp), c_class(yp));
+       if (yp->yp_module == NULL
+           || strcmp(yp->yp_module, mymodule) == 0) {
+           if (f == NULL || noindirect(f)) {   /* No offset type */
+                 prstfield(fp, "OBJECT", t, f,
+                     concat("_Z", proc_name(yp->yp_identifier, 0)),
+                     c_class(yp));
+               /*
+               (void) fprintf(fp, "\t{ SOBJECT, 0, _Z%s, %s },\n",
+                     proc_name(yp->yp_identifier, 0), c_class(yp));
+                */
+           } else
+                 prtfield(fp, "OBJECT", t, f,
+                     concat("_Z", proc_name(yp->yp_identifier, 0)),
+                     c_class(yp));
+               /*
+               (void) fprintf(fp,
+                       "\t{ OBJECT, OFFSET(%s, %s), _Z%s, %s },\n",
+               t, f, proc_name(yp->yp_identifier, 0), c_class(yp));
+               */
+       } else {
+           if (f == NULL || noindirect(f)) {   /* No offset type */
+                 prstfield(fp, "EXTOBJ", t, f,
+                     concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)),
+                       c_class(yp));
+               /*
+               (void) fprintf(fp, "\t{ SEXTOBJ, 0, _Z%s, %s },\n",
+                       strp2name(yp->yp_identifier, yp->yp_module),
+                       c_class(yp));
+                */
+           } else
+                 prtfield(fp, "EXTOBJ", t, f,
+                     concat("_Z", strp2name(yp->yp_identifier, yp->yp_module)),
+                       c_class(yp));
+               /*
+               (void) fprintf(fp,
+                       "\t{ EXTOBJ, OFFSET(%s, %s), _Z%s, %s },\n",
+                 t, f, strp2name(yp->yp_identifier, yp->yp_module),
+                       c_class(yp));
+                */
+
+           (void) fprintf(fp, "\t{ EXTMOD, %d, 0, 0 },\n",
+                   gen_modref(yp->yp_module));
+       }
+       break;
+
+    case YP_SEQLIST:
+       p1 = NULL;
+       /* support for -h flag */
+       cons_type++;
+       save_ptr = en_ptr;
+       if (yp->yp_varexp == NULL && type != NULL)
+           ferr(1, "tenc_typ:YP_SEQLIST:NULL varexp pointer\n");
+       prcte(fp, type, t, f, yp, "SEQ_START");
+       if (y = yp->yp_type) {
+           char *t1;
+
+           /* compute the type of data */
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntenc_typ:SEQLIST: can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tenc_typ:YP_SEQLIST:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (optfield(y)) {
+               (void) fprintf(fp,
+                       "\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
+                       yp->yp_structname);
+           }
+           tenc_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       en_ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_SETLIST:
+       p1 = NULL;
+       /* support for -h flag */
+       cons_type++;
+       if (yp->yp_varexp == NULL && type != NULL)
+           ferr(1, "tenc_typ:YP_SETLIST:NULL varexp pointer\n");
+       prcte(fp, type, t, f, yp, "SET_START");
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntenc_typ:SETLIST can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tenc_typ:YP_SETLIST:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           if (optfield(y)) {
+               (void) fprintf(fp,
+                       "\t{ OPTL, OFFSET(%s, optionals), 0, 0 },\n",
+                       yp->yp_structname);
+           }
+           tenc_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       en_ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_SEQTYPE:
+       p1 = NULL;
+       cons_type++;
+       save_ptr = en_ptr;
+       prcte(fp, type, t, f, yp, "SEQOF_START");
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntenc_typ:SETLIST can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tenc_typ:YP_SEQTYPE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           tenc_loop(fp, y, id, yp->yp_structname);
+       }
+       if (yp->yp_flags & YP_CONTROLLED) {
+           char *f1;
+
+           if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+               fprintf(stderr, "\ntenc_typ:SEQ OF: can't extract field from %s\n",
+                   yp->yp_control);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
+                   yp->yp_structname, f1);
+       } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
+                   yp->yp_structname);
+       else
+           (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       en_ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_SETTYPE:
+       p1 = NULL;
+       cons_type++;
+       save_ptr = en_ptr;
+       prcte(fp, type, t, f, yp, "SETOF_START");
+
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntenc_typ:SETTYPE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tenc_typ:YP_SETTYPE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           tenc_loop(fp, y, id, yp->yp_structname);
+       }
+       if (yp->yp_flags & YP_CONTROLLED) {
+           char *f1;
+
+           if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+               fprintf(stderr, "\ntenc_typ:SET OF: can't extract field from %s\n",
+                   yp->yp_control);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
+                   yp->yp_structname, f1);
+       } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, next), 0, 0 },\n",
+                   yp->yp_structname);
+       else
+           (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       en_ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_CHOICE:
+       p1 = NULL;
+       /* support for -h flag */
+       if (hflag && (y = yp->yp_type) && !y->yp_next) {
+           tenc_typ(fp, y, id, yp->yp_structname);
+           break;
+       }
+       cons_type++;
+       save_ptr = en_ptr;
+       if (type == NULL || type && noindirect(f))
+           prstfield(fp, "CHOICE_START", t, f, NULLCP, c_class(yp));
+       else
+           prtfield(fp, "CHOICE_START", t, type ? f : NULLCP, NULLCP, c_class(yp));
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntenc_typ:CHOICE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tenc_typ:YP_CHOICE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+
+           if (yp -> yp_control_act && yp->yp_control_act->yal_enc) {
+               (void) fprintf (fp, "\t{ SCTRL, %d, 0, FL_USELECT },\n",
+                               yp -> yp_control_act -> yal_enc -> a_num);
+           }
+           else if (yp->yp_flags & YP_CONTROLLED) {
+               char *f1;
+
+               if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+                   fprintf(stderr, "\ntenc_typ:CHOICE: can't extract field from %s\n",
+                       yp->yp_control);
+                   exit(1);
+               }
+               (void) fprintf(fp, "\t{ SCTRL, OFFSET(%s, %s), 0, 0 },\n",
+                       yp->yp_structname, f1);
+           } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp, "\t{ SCTRL, OFFSET(%s, offset), 0, 0 },\n",
+                   yp->yp_structname);
+           else
+               ferr(1, "\nCHOICE missing SCTRL\n");
+           tenc_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0 },\n");
+       en_ptr = save_ptr;
+       cons_type--;
+       break;
+
+    default:
+       ferrd(1, "tenc_typ: yp_code = %d  not implemented\n", yp->yp_code);
+    }
+
+    if (p1 != NULL)
+       prnte(fp, t, f, yp, p1);
+
+    if (yp->yp_aft_alist && yp->yp_aft_alist->yal_enc)
+       gen_act(fp, yp->yp_aft_alist->yal_enc);
+
+}
+
+static int fflags[] = {
+    0, 1, 2, 2, 3, 3, 4, 5, 16, 16, 16, 17, 17, 17,
+0, -1, 6, 0, 10, 9};
+
+/*
+ * calculate the tag string of the given type and return it
+ */
+char   *
+c_tag(yp)
+YP      yp;
+{
+    static char buf[WORDSIZE];
+    int     i;
+
+    if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) {
+       i = yp->yp_tag->yt_value->yv_number;
+    } else {
+       if (yp->yp_code < 0 || yp->yp_code > YP_REAL
+           || yp->yp_code == YP_CHOICE)
+           i = 0;
+       else
+           i = fflags[yp->yp_code];
+       /* Choice now legal argument - to allow prte_* routines to work */
+       if (i == 0 && yp->yp_code != YP_CHOICE)
+           ferrd (1, "c_tag:Unknown Tag %d", yp->yp_code);
+    }
+
+    (void) sprintf(buf, "%d", i);
+
+    return (buf);
+}
+
+/*
+ * calculate the tag string of the explicit tag and return it
+ */
+char   *
+ec_tag(yp)
+YP      yp;
+{
+    static char buf[WORDSIZE];
+    int     i;
+
+    if (!(yp->yp_flags & YP_TAG) || yp->yp_flags & YP_IMPLICIT)
+       ferr(1, "ec_tag:internal error:called with out explicit tag\n");
+
+    i = yp->yp_tag->yt_value->yv_number;
+
+    (void) sprintf(buf, "%d", i);
+
+    return (buf);
+}
+
+/*
+ * produce a string that represents the class/flags field for a given
+ * yp entry taking the class to be that given in cl
+ */
+char   *
+c_flags(yp, cl)
+YP      yp;
+PElementClass cl;
+{
+    char   *p1;
+    static char buf[STRSIZE];
+
+    switch (yp->yp_code) {
+    case YP_IDEFINED:
+    case YP_CHOICE:
+       if (yp->yp_flags & YP_TAG)
+           break;
+       if (yp->yp_flags & YP_OPTIONAL
+           && ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+               != (YP_OPTIONAL|YP_OPTCONTROL))) {
+           p1 = "FL_OPTIONAL";
+       } else if (yp->yp_flags & YP_DEFAULT) {
+           p1 = "FL_DEFAULT";
+       } else
+           p1 = "0";
+       return (p1);
+
+    default:
+       break;
+    }
+    p1 = class2str(cl);
+    if (yp->yp_flags & YP_OPTIONAL
+           && ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+               != (YP_OPTIONAL|YP_OPTCONTROL))) {
+       (void) strncpy(buf, p1, STRSIZE);
+       p1 = strncat(buf, "|FL_OPTIONAL", STRSIZE);
+    } else if (yp->yp_flags & YP_DEFAULT) {
+       (void) strncpy(buf, p1, STRSIZE);
+       p1 = strncat(buf, "|FL_DEFAULT", STRSIZE);
+    }
+    return (p1);
+}
+/*
+ * turn the class number into its corresponding string
+ */
+char   *
+class2str(cl)
+PElementClass  cl;
+{
+    register char *p1;
+
+    switch (cl) {
+    case PE_CLASS_UNIV:
+       p1 = "FL_UNIVERSAL";
+       break;
+
+    case PE_CLASS_APPL:
+       p1 = "FL_APPLICATION";
+       break;
+
+    case PE_CLASS_PRIV:
+       p1 = "FL_PRIVATE";
+       break;
+
+    case PE_CLASS_CONT:
+       p1 = "FL_CONTEXT";
+       break;
+
+    default:
+       ferrd(1, "class2str: illegal class found %d\n", (int)cl);
+
+    }
+    return (p1);
+}
+
+/*
+ * calculate a string specifying the class for the given type and
+ * return it
+ */
+char   *
+c_class(yp)
+YP      yp;
+{
+    int     i;
+
+    if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) {
+       i = yp->yp_tag->yt_class;
+    } else {
+       i = PE_CLASS_UNIV;
+    }
+    return (c_flags(yp, (PElementClass)i));
+
+}
+/*
+ * calculate a string specifying the class for the explicit tag and
+ * return it
+ */
+char   *
+ec_class(yp)
+YP      yp;
+{
+    int     i;
+    char   *p1;
+    static char buf[STRSIZE];
+
+    if (!(yp->yp_flags & YP_TAG) || yp->yp_flags & YP_IMPLICIT)
+       ferr(1, "ec_class:internal error:called with out explicit tag\n");
+    switch (yp->yp_code) {
+    case YP_IDEFINED:
+    case YP_CHOICE:
+       if (yp->yp_flags & YP_TAG)
+           break;
+       if (yp->yp_flags & YP_OPTIONAL
+           && ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+               != (YP_OPTIONAL|YP_OPTCONTROL))) {
+           p1 = "FL_OPTIONAL";
+       } else if (yp->yp_flags & YP_DEFAULT) {
+           p1 = "FL_DEFAULT";
+       } else
+           p1 = "0";
+       return (p1);
+
+    default:
+       break;
+    }
+
+    i = yp->yp_tag->yt_class;
+
+    switch (i) {
+    case PE_CLASS_UNIV:
+       p1 = "FL_UNIVERSAL";
+       break;
+
+    case PE_CLASS_APPL:
+       p1 = "FL_APPLICATION";
+       break;
+
+    case PE_CLASS_PRIV:
+       p1 = "FL_PRIVATE";
+       break;
+
+    case PE_CLASS_CONT:
+       p1 = "FL_CONTEXT";
+       break;
+
+    default:
+       ferrd(1, "c_class: illegal class found %d\n", i);
+
+    }
+    if ((yp->yp_flags & YP_OPTIONAL) 
+           && ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+               != (YP_OPTIONAL|YP_OPTCONTROL))) {
+       (void) strncpy(buf, p1, STRSIZE);
+       p1 = strncat(buf, "|FL_OPTIONAL", STRSIZE);
+    } else if (yp->yp_flags & YP_DEFAULT) {
+       (void) strncpy(buf, p1, STRSIZE);
+       p1 = strncat(buf, "|FL_DEFAULT", STRSIZE);
+    }
+    return (p1);
+}
+
+/*
+ * generate tables for encoding a contructed type
+ */
+tenc_loop(fp, yp, id, type)
+FILE   *fp;
+YP      yp;
+char   *id;
+char   *type;
+{
+    for (; yp != NULL; yp = yp->yp_next) {
+       tenc_typ(fp, yp, id, type);
+    }
+}
+
+/*
+ * Print the string and exit if argument greater than zero
+ */
+ferr(i, s)
+int     i;
+char   *s;
+{
+    (void) fprintf(stderr, "%s", s);
+    if (i > 0)
+       exit(i);
+}
+
+/*
+ * Print the integer and exit if argument greater than zero
+ */
+ferrd(i, s, d)
+int     i;
+char   *s;
+int     d;
+{
+    (void) fprintf(stderr, s, d);
+    if (i > 0)
+       exit(i);
+}
+
+/*
+ * Print the string and exit if argument greater than zero
+ */
+ferrs(i, s, d)
+int     i;
+char   *s;
+char   *d;
+{
+    (void) fprintf(stderr, s, d);
+    if (i > 0)
+       exit(i);
+}
+
+/*
+ * return a copy of the string s minus its last character
+ */
+char   *
+strip_last(s)
+char   *s;
+{
+    char   *t, *r;
+
+    if (s) {
+       t = new_string(s);
+       for (r = t; *r != '\0'; r++);
+       ;
+       *--r = '\0';
+       return t;
+    } else
+       return NULL;
+}
+
+/*
+ * add the declaration specified by the strings type and id to the
+ * start of the declaration list
+ */
+add_list(type, id)
+char   *type, *id;
+{
+
+    s_table *prev;
+
+    if ((prev = (s_table *) malloc(sizeof(s_table))) == NULL)
+       ferr(1, "add_list: Out of memory\n");
+    prev->type = type;
+    prev->name = id;
+    prev->parent = NULL;
+    prev->defined = 0;
+    prev->next = head;
+    head = prev;
+}
+
+/*
+ * print the declaration list
+ */
+print_list()
+{
+    s_table *prev;
+
+    for (prev = head; prev != NULL; prev = prev->next) {
+       (void) printf("type is %s\n", prev->type);
+       (void) printf("name is %s\n", prev->name);
+       (void) printf("\n");
+    }
+}
+
+/*
+ * parse the declaration in the string s returning the type in v1 and
+ * the name in v2
+ */
+parse_decl(s, v1, v2)
+char  **s, **v1, **v2;
+{
+    char   *t;
+
+    for (t = *s; *t != '\0' && !(isalnum(*t) || *t == '_'); t++);
+
+    *s = t;
+    if (*t != '\0') {
+       for (; *t != '*'; t++);
+       *t = '\0';
+       *v1 = my_strcat(*s, "*");
+       Printf(3, ("the type is %s\n", *v1));
+       if (*++t == '*')
+           t++;
+       for (*s = t; isalnum(*t) || *t == '_'; t++);
+       if (*t != '\0') {
+           *t = '\0';
+           t++;
+       }
+       *v2 = new_string(*s);   /* don't really need new_string */
+       Printf(2, ("the name is %s\n", *v2));
+       *s = t;
+    }
+}
+
+/*
+ * return the next identifier in the string s
+ */
+char   *
+get_val(s)
+char  **s;
+{
+    char   *t, *r;
+
+    for (t = *s; *t != '\0' && !(isalnum(*t) || *t == '_' || *t == '.'); t++);
+
+    if (*t != '\0') {
+       for (*s = t; isalnum(*t) || *t == '_' || *t == '.'; t++);
+       *t = '\0';
+       r = *s;
+       Printf(3, ("arg is |%s|\n", r));
+       *s = ++t;
+       return r;
+    } else
+       return NULL;
+}
+
+/*
+ * return the next component (sequence of characters up to the next
+ * ';' or '\0') of the string s
+ */
+char   *
+get_comp(s)
+char  **s;
+{
+    char   *t, *r;
+
+    for (t = *s; *t != '\0' && !(isalnum(*t) || *t == '_' || *t == ';'); t++);
+
+    if (*t != '\0') {
+       for (*s = t; *t != '\0' && *t != ';'; t++);
+       *t = '\0';
+       r = *s;
+       Printf(3, ("component is |%s|\n", r));
+       *s = ++t;
+       return r;
+    } else
+       return NULL;
+}
+
+/*
+ * return a copy of that part of the string s which may contain
+ * definitions for the variables generated by posy
+ */
+char   *
+get_string(s, direction)
+char   *s;
+int     direction;
+{
+    char   *t, *t1;
+
+    if (direction & YP_ENCODER)
+       return new_string(s);
+    if (direction & YP_DECODER) {
+       t = new_string(s);
+       for (t1 = t; !(isalnum(*t1) || *t1 == '_'); t1++);
+       if (*t1 == 'i' && *++t1 == 'f' && *++t1 == ' ') {       /* MEMALLOC code */
+           for (; *t1 != '}'; t1++)    /* skip MEMALLOC code */
+               ;
+           t1++;
+           Printf(4, ("returning the string %s\n", t1));
+           return t1;
+       } else
+           return t;
+    }
+    return NULL;
+}
+
+/*
+ * Determine wether this list contains any items that will generate
+ * an optional field. If so return non zero
+ */
+optfield(yp)
+YP      yp;
+{
+    for (; yp; yp = yp->yp_next) {
+       if (yp->yp_flags & YP_OPTIONAL) {
+
+           if ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+               == (YP_OPTIONAL|YP_OPTCONTROL))
+               return (0);
+
+           switch (yp->yp_code) {
+           case YP_BOOL:
+           case YP_INT:
+           case YP_INTLIST:
+           case YP_ENUMLIST:
+           case YP_NULL:
+               return (1);
+           }
+       }
+    }
+    return (0);
+}
+
+gen_dflts(fp, yp, type)
+FILE    *fp;
+YP      yp;
+char   *type;
+{
+    YP      y;
+
+    if (yp == NULL)
+       return;
+    switch (yp->yp_code) {
+    case YP_IDEFINED:
+       break;
+
+    case YP_CHOICE:
+    case YP_SEQTYPE:
+    case YP_SETTYPE:
+    case YP_SEQLIST:
+    case YP_SETLIST:
+       for (y = yp->yp_type; y != NULL; y = y->yp_next) {
+           gen_dflts(fp, y, type);
+       }
+       break;
+
+    default:
+       break;
+    }
+    /* Output definitions for default entries */
+    if (yp->yp_flags & YP_DEFAULT)
+       defdflt(fp, yp, type);
+    
+    if (yp->yp_yfn)
+       declfns(fp, yp->yp_yfn);
+}
+/*
+ * Compute the concatenation into a temporary buffer of two strings
+ * after having run notid on them first
+ */
+char   *
+strp2name(s1, s2)
+char   *s1, *s2;
+{
+    char   *p;
+    static char buf[STRSIZE * 2 + 5];
+
+    if ((int)strlen(s1) > STRSIZE || (int)strlen(s2) > STRSIZE)
+       ferr(1, "strp2name:string to big\n");
+    (void) strcpy(buf, p = notidtoid(s1));
+    free(p);
+    (void) strcat(buf, p = notidtoid(s2));
+    free(p);
+
+    return (buf);
+}
+
+/*
+ * Output the definitions for default entries and initialise the yp's
+ * to have pointers which reference these definitions for use by
+ * gdflt routine.
+ */
+defdflt(fp, yp, name)
+FILE    *fp;
+YP      yp;
+char   *name;
+{
+    YV      yv;
+    YV      yv1;
+    SY      sy;
+    YP      yp1;
+    int     size, i;
+    char   *str;
+    char   *label;
+    struct univ_typ    *p;
+    int                code;
+
+    if ((yp->yp_flags & YP_DEFAULT) == 0)
+       ferrd(1, "defdflt:called with out a default code = %d\n", yp->yp_code);
+    yv = yp->yp_default;
+
+    yp1 = yp;
+
+    /* Find the bottom definition */
+    code = yp1->yp_code;
+    while (code == YP_IDEFINED) {
+       if ((sy = syfind(yp1->yp_identifier)) == NULL) {
+           if ((p = univtyp(yp1->yp_identifier)) == NULL
+              || p->univ_type <= YP_UNDF)
+               ferrs(1,
+                   "defdflt:IDEFINED:cannot find definition of symbol %s\n",
+                   yp1->yp_identifier);
+           code = p->univ_type;
+           break;
+               
+       }
+       yp1 = sy->sy_type;
+       code = yp1->yp_code;
+    }
+
+    switch (code) {
+    case YP_BOOL:
+    case YP_INT:
+    case YP_INTLIST:
+    case YP_ENUMLIST:
+       switch (yv->yv_code) {
+       case YV_NUMBER:
+       case YV_BOOL:
+           /* None needed */
+           break;
+
+       case YV_IDEFINED:
+           if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
+               ferrs(1, "defdflt:BOOL/INT:cannot find definition of %s\n",
+                     yv->yv_identifier);
+           }
+           /* None Needed */
+           break;
+
+       default:
+           ferrd(1, "defdflt:INT/BOOL:unimplemented value code = %d\n",
+                 yv->yv_code);
+       }
+       break;
+
+    case YP_REAL:
+       switch (yv->yv_code) {
+       case YV_REAL:
+            yv1 = yv;
+            goto dumpdef3;
+
+       case YV_IDEFINED:
+           if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
+               ferrs(1, "defdflt:REAL:cannot find definition of %s\n",
+                     yv->yv_identifier);
+           }
+           goto dumpdef3;
+
+       default:
+           ferrd(1, "defdflt:REAL:unimplemented value code = %d\n",
+                 yv->yv_code);
+       }
+       break;
+
+    case YP_BIT:
+    case YP_BITLIST:
+       switch (yv->yv_code) {
+           /*
+            * This is an illegal value for a bit string ! - BUT ACSE
+            * uses it !
+            */
+           /* gdflt also patched to support it */
+       case YV_IDEFINED:
+           ferrs(0,
+                 "warning:bitstring default specified illegally with identifier %s\n",
+                 yv->yv_identifier);
+           if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
+               ferrs(1, "defdflt:BIT:cannot find definition of %s\n",
+                     yv->yv_identifier);
+           }
+           /* doesn't work fix posy-yacc.y */
+           size = numtobstr(yv1, &str);
+           goto dumpdef1;
+
+       case YV_NUMBER:
+           size = numtobstr(yv, &str);
+           goto dumpdef1;
+
+       case YV_VALIST:
+           if ((size = valisttobs(yp1, yv, &str)) < 0) {
+               ferrs(1, "defdflt:bad default value for bit string %s\n",
+                     yp->yp_flags & YP_ID ? yp->yp_identifier : "");
+           }
+           goto dumpdef1;
+
+       case YV_HSTRING:
+           str = yv->yv_xstring;
+           size = yv->yv_xlength*4;
+           goto dumpdef1;
+
+       case YV_BSTRING:
+           str = yv->yv_xstring;
+           size = yv->yv_xlength;
+           goto dumpdef1;
+
+       default:
+           /* Could be a syntax error */
+           ferrd(1, "defdflt:BIT:illegal value code = %d\n", yv->yv_code);
+       }
+       break;
+
+    case YP_IDEFINED:
+       ferrs(1, "defdflt:IDEFINED:internal error on symbol %s\n",
+             yp1->yp_identifier);
+       break;
+
+    case YP_OCT:
+       switch (yv->yv_code) {
+       case YV_NUMBER:
+           size = numtobstr(yv, &str);
+           goto dumpdef2;
+
+       case YV_STRING:
+           str = yv->yv_string;
+           size = strlen(str);
+           goto dumpdef2;
+
+       case YV_HSTRING:
+           str = yv->yv_xstring;
+           size = (yv->yv_xlength + 1)/2;
+           goto dumpdef2;
+
+       case YV_BSTRING:
+           str = yv->yv_xstring;
+           size = (yv->yv_xlength + 7)/8;      /* round up */
+           goto dumpdef2;
+
+       default:
+           /* Could be a syntax error */
+           ferrd(1, "defdflt:OCT:illegal value code = %d\n", yv->yv_code);
+       }
+       break;
+
+    case YP_NULL:
+    case YP_SEQ:
+    case YP_SEQTYPE:
+    case YP_SEQLIST:
+    case YP_SET:
+    case YP_SETTYPE:
+    case YP_SETLIST:
+    case YP_CHOICE:
+    case YP_ANY:
+    case YP_OID:
+       /* None yet */
+       break;
+
+    default:
+       ferrd(1, "defdflt:unknown type %d\n", code);
+    }
+
+    return;
+
+dumpdef1:      /* Bitstrings */
+    label = genlabel(name, yp);
+    yp->yp_action0 = label;
+    yp->yp_act0_lineno = size;
+    i = (size + NBPC - 1) / NBPC;
+    (void) fprintf(fp, "\nstatic unsigned char %s[] = ", label);
+    if (printable(str, i))
+       prstr(fp, str, i);
+    else
+       prhstr(fp, str, i);
+    (void) fprintf(fp, ";\n");
+    return;
+
+dumpdef2:      /* Octet strings (and aliases) */
+    label = genlabel(name, yp);
+    yp->yp_action0 = label;
+    yp->yp_act0_lineno = size;
+    (void) fprintf(fp, "\nstatic unsigned char %s[] = ", label);
+    if (printable(str, size))
+       prstr(fp, str, size);
+    else
+       prhstr(fp, str, size);
+    (void) fprintf(fp, ";\n");
+    return;
+
+dumpdef3:      /* Reals */
+    label = genlabel(name, yp);
+    yp->yp_action0 = label;
+    (void) fprintf(fp, "\nstatic double %s = %f;\n", label, yv1->yv_real);
+    return;
+
+}
+/*
+ * generate the default entry for encoding/decoding fields. This
+ * should contain the default value which the encoder will know means
+ * default encoding
+ */
+gdflt(fp, yp, which)
+FILE   *fp;
+YP      yp;
+int     which;                 /* Which type of entries to generate
+                                * G_ENC encode G_DEC decode */
+{
+    YV      yv;
+    YV      yv1;
+    SY      sy;
+    YP      yp1;
+    char   *ndflt;
+    struct univ_typ     *p;
+    int         code;
+
+
+    if (which == G_ENC)
+       ndflt = "DFLT_F";
+    else
+       ndflt = "DFLT_B";
+
+    if ((yp->yp_flags & YP_DEFAULT) == 0)
+       ferrd(1, "gdflt:called with out a default code = %d\n", yp->yp_code);
+    yv = yp->yp_default;
+
+    yp1 = yp;
+
+    /* Find the bottom definition */
+    code = yp1->yp_code;
+    while (code == YP_IDEFINED) {
+       if ((sy = syfind(yp1->yp_identifier)) == NULL) {
+             if ((p = univtyp(yp1->yp_identifier)) == NULL
+               || p->univ_type <= YP_UNDF)
+                   ferrs(1,
+                       "gdflt:IDEFINED:cannot find definition of symbol %s\n",
+                       yp1->yp_identifier);
+            code = p->univ_type;
+            break;
+
+       }
+       yp1 = sy->sy_type;
+       code = yp1->yp_code;
+    }
+
+    switch (code) {
+    case YP_BOOL:
+    case YP_INT:
+    case YP_INTLIST:
+    case YP_ENUMLIST:
+       switch (yv->yv_code) {
+       case YV_NUMBER:
+       case YV_BOOL:
+           (void) fprintf(fp, "\t{ %s, %d,     0,      0 },\n", ndflt,
+                   yp->yp_default->yv_number);
+           break;
+
+       case YV_IDEFINED:
+           if ((yv1 = calc_yv(yp1, yv->yv_identifier)) == NULL) {
+               ferrs(1, "gdflt:BOOL/INT:cannot find definition of %s\n",
+                     yv->yv_identifier);
+           }
+           (void) fprintf(fp, "\t{ %s, %d,     0,      0 },\n", ndflt,
+                   yv1->yv_number);
+           break;
+
+       default:
+           ferrd(1, "gdflt:INT/BOOL:unimplemented value code = %d\n",
+                 yv->yv_code);
+       }
+       break;
+
+    case YP_BIT:
+    case YP_BITLIST:
+       switch (yv->yv_code) {
+#ifdef ILLEGAL_DEFAULTS
+       case YV_IDEFINED:       /* supporting illegal default
+                                * specification */
+#endif
+       case YV_NUMBER:
+       case YV_HSTRING:
+       case YV_BSTRING:
+       case YV_VALIST:
+           (void) fprintf(fp, "\t{ %s, %d,     %d,     0 },\n", ndflt,
+                   yp->yp_act0_lineno, addptr(yp->yp_action0));
+           break;
+
+       default:
+           /* Could be a syntax error */
+           ferrd(1, "gdflt:BIT:illegal value code = %d\n", yv->yv_code);
+       }
+       break;
+
+    case YP_IDEFINED:
+       ferrs(1, "gdflt:IDEFINED:internal error on symbol %s\n",
+             yp1->yp_identifier);
+       break;
+
+    case YP_REAL:
+       switch (yv->yv_code) {
+#ifdef ILLEGAL_DEFAULTS
+       case YV_IDEFINED:       /* Illegal according to ASN.1 but we can do it
+                                * so why not support it
+                                */
+#endif
+       case YV_REAL:
+           (void) fprintf(fp, "\t{ %s, 0,      %d,     0 },\n", ndflt,
+                   addptr(concat("&", yp->yp_action0)));
+           break;
+
+       default:
+           /* Could be a syntax error */
+           ferrd(1, "gdflt:REAL:illegal value code = %d\n", yv->yv_code);
+       }
+       break;
+
+    case YP_OCT:
+       switch (yv->yv_code) {
+       case YV_NUMBER:
+       case YV_STRING:
+       case YV_HSTRING:
+       case YV_BSTRING:
+           (void) fprintf(fp, "\t{ %s, %d,     %d,     0 },\n", ndflt,
+                   yp->yp_act0_lineno, addptr(yp->yp_action0));
+           break;
+
+       default:
+           /* Could be a syntax error */
+           ferrd(1, "gdflt:OCT:illegal value code = %d\n", yv->yv_code);
+       }
+       break;
+
+    case YP_NULL:
+    case YP_SEQ:
+    case YP_SEQTYPE:
+    case YP_SEQLIST:
+    case YP_SET:
+    case YP_SETTYPE:
+    case YP_SETLIST:
+    case YP_CHOICE:
+    case YP_ANY:
+    case YP_OID:
+       (void) fprintf(fp, "\t{ %s,     0,      0,      0 },\n", ndflt);
+       break;
+
+    default:
+       ferrd(1, "gdflt:unknown type %d\n", yp->yp_code);
+    }
+
+}
+/*
+ * Calculate the value associated with the given identifier id by
+ * looking at the value definitions associated with type definition
+ * yp. Returns the value definition if found or NULL if not.
+ */
+YV
+calc_yv(yp, id)
+YP      yp;
+char   *id;
+{
+    YV      yv;
+
+    for (yv = yp->yp_value; yv != NULL; yv = yv->yv_next) {
+       if (yv->yv_flags & YV_NAMED && strcmp(yv->yv_named, id) == 0)
+           return (yv);
+    }
+
+    return (NULL);
+}
+
+/*
+ * ******* This does not work. posy needs to be fixed for case of
+ * '01'b ***** Turn a Literal number value in yv into a bistring
+ * initialisation. Return the length of the bit string or less than
+ * zero on error. Set the (char *) pointer, whose address is in
+ * ppstr, to point to a string containing the a reference to a
+ * character array which contains the bits.
+ */
+
+numtobstr(yv, ppstr)
+YV      yv;
+char  **ppstr;
+{
+
+    int     ibits, lastb, i;
+    char   *buf;
+
+    buf = malloc(NBPI / NBPC + 1);
+    bzero(buf, NBPI / NBPC + 1);
+    lastb = -1;
+    ibits = yv->yv_number;
+    for (i = 0; i < NBPI; i++) {
+       if ((1 << i) & ibits) {
+           buf[i / NBPC] |= 1 << (NBPC - 1 - (i % NBPC));
+           lastb = i;
+       }
+    }
+
+    *ppstr = buf;
+    return (lastb + 1);
+}
+#define ROUNDUP                10
+/*
+ * Take a list of Values (YV_VALIST) which should contain a list of
+ * bits and convert them into a bitstring initialisation. As in
+ * numtobstr return the size of the bit string or a negative number
+ * if there is an error. Put a reference to a character array which
+ * contains the definition of the bits in the character pointer whose
+ * address is in ppstr. yp is the definition of the type which
+ * contains the names of all the defined bits.
+ */
+valisttobs(yp, yv, ppstr)
+YP      yp;
+YV      yv;
+char  **ppstr;
+{
+
+    YV      yv1, yv2;
+    int     lastb, val, nsize, size;
+    char   *buf;
+
+    lastb = -1;
+    size = ROUNDUP;
+    if ((buf = malloc((unsigned)size)) == NULL) {
+       ferrd(1, "valisttobs:malloc:failed on %d\n", size);
+    }
+    bzero(buf, size);
+    for (yv1 = yv->yv_idlist; yv1 != NULL; yv1 = yv1->yv_next) {
+       if ((yv2 = calc_yv(yp, yv1->yv_identifier)) == NULL) {
+           return (-1);
+       }
+       val = yv2->yv_number;
+       /* Bug here probably */
+       if (size < val / NBPC) {
+           nsize = val / NBPC + ROUNDUP;
+           if ((buf = realloc(buf, (unsigned)nsize)) == NULL) {
+               ferrd(1, "valisttobs:realloc:failed on %d\n", nsize);
+           }
+           bzero(buf + size, nsize - size);
+           size = nsize;
+       }
+       buf[val / NBPC] |= 1 << (NBPC - 1 - (val % NBPC));
+       if (val > lastb)
+           lastb = val;
+    }
+    *ppstr = buf;
+    return (lastb + 1);
+}
+/*
+ * Print the string out in a format acceptable as a quoted string in
+ * a C program including the quotes. Using \ escapes for unprintable
+ * characters
+ */
+prstr(fp, str, len)
+FILE   *fp;
+char   *str;
+int     len;
+{
+    (void) fputc('"', fp);
+    while (len-- > 0) {
+       if (isprint(*str & 0xff)) {
+           (void) fputc(*str & 0xff, fp);
+           str++;
+           continue;
+       }
+       (void) fprintf(fp, "\\%0o", *str & 0xff);
+    }
+    (void) fputc('"', fp);
+#define MAXPLINE       16
+}
+/*
+ * output a initialisation for a character array as unsigned hex
+ * numbers
+ */
+prhstr(fp, str, len)
+FILE   *fp;
+char   *str;
+int     len;
+{
+    int     npline;            /* number on this line */
+
+    (void) fprintf(fp, "{\n");
+    npline = 0;
+    while (len > 0) {
+       if (npline >= MAXPLINE) {
+           (void) fputc('\n', fp);
+           npline = 0;
+       }
+       npline++;
+       (void) fprintf(fp, " 0x%02x,", *str++ & 0xff);
+       len--;
+    }
+    (void) fprintf(fp, "}");
+}
+/*
+ * determine if the string is printable i.e. only sensible to be read
+ * as a character string. 1 (true) if it is 0, if it isn't
+ */
+printable(str, i)
+char   *str;
+int     i;
+{
+    while (i-- > 0) {
+       if (!isprint(*str & 0xff))
+           return (0);         /* look for the first non printable
+                                * character */
+       str++;
+    }
+    return (1);
+}
+/*
+ * generate a unique identifier  using the name given and the name if
+ * present in yp. Return a pointer to it in a space malloc'ed out
+ */
+char   *
+genlabel(name, yp)
+char   *name;
+YP      yp;
+{
+    char    buf[MAXNAME];
+    static int cnt;
+    char   *p1, *p2;
+
+    p1 = notidtoid(name);
+    if (yp->yp_flags & YP_ID) {
+       p2 = notidtoid(yp->yp_id);
+       (void) sprintf(buf, "L%s_%s_%d", p1, p2, cnt++);
+       free(p2);
+    } else
+       (void) sprintf(buf, "L%s_X_%d", p1, cnt++);
+    free(p1);
+
+    return (my_new_str(buf));
+}
+/*
+ * generate a ptr table reference for the given module table entry
+ */
+gen_modref(mod)
+char   *mod;
+{
+    char       buf[BUFSIZ];
+    char       *p1;
+    int                ind;
+
+    p1 = notidtoid(mod);
+    (void) sprintf(buf, "&%s%s%s", PREFIX, p1, MODTYP_SUFFIX);
+    ind = addptr(buf);
+    free(p1);
+
+    return (ind);
+}
+
+char   *
+setfield(p)
+char   *p;
+{
+    char       *f;
+
+    if ((f = getfield(p)) == NULLCP) {
+       fprintf(stderr, "\nsetfield: can't extract field from %s\n", p);
+       exit(1);
+    }
+    return (strdup(f));
+}
+
+/*
+ * print a normal table entry
+ */
+prnte(fp, t, f, yp, p1)
+FILE   *fp;
+char   *t;     /* parent type */
+char   *f;     /* field name */
+YP     yp;     /* object */
+char   *p1;    /* table entry name */
+{
+    if (p1 == NULL)
+       ferr(1, "prnte: called with a NULL p1\n");
+
+    if (t && noindirect(f))
+       prstfield(fp, p1, t, f, c_tag(yp), c_class(yp));
+    else
+       prtfield(fp, p1, t, f, c_tag(yp), c_class(yp));
+}
+
+/*
+ * generate the entry allowing for defined types and then call the given
+ * function to generate the base entry
+ * Algorithm:
+ * If we can find the base type 
+ *   i) generate any ETAG that subsequent definitions might have
+ *   ii) call the function to generate the base entry
+ *   iii) and  the function checks that it matches the type of the value pass
+ * else - can't find the base type - probably because it is external
+ *   i)  generate a warning and exit
+ */
+gen_identry(fp, t, f, yp, fn)
+FILE   *fp;
+char   *t, *f;
+YP     yp;
+int    (*fn)();
+{
+   YP  yp1;
+   int code;
+   SY  sy;
+   YT  pd_yt = NULLYT; /* Passed down tag if any */
+   YT  yt;
+   struct univ_typ     *p = NULL;
+   char        *flags;         /* the flags if any which each subtype must have */
+   int save_flags;
+    
+    yp1 = yp;
+    code = yp1->yp_code;
+
+    if (yp->yp_flags & YP_OPTIONAL)
+       flags = "|FL_OPTIONAL";
+    else if (yp->yp_flags & YP_DEFAULT)
+       flags = "|FL_DEFAULT";
+    else
+       flags = "";
+
+    /* any explicit tag for original yp type is handled before this
+     * routine is called so don't call gen_etag for it here
+     * but we do need to initialise pd_yt for the case of an IMPLICIT TAG.
+     */
+    if ((yp->yp_flags & (YP_TAG|YP_IMPLICIT))== (YP_TAG|YP_IMPLICIT))
+       pd_yt = yp->yp_tag;
+
+    while (code == YP_IDEFINED) {
+        if ((sy = syfind(yp1->yp_identifier)) == NULL) {
+            if ((p = univtyp(yp1->yp_identifier)) == NULL
+               || p->univ_type <= YP_UNDF)
+                ferrs(1,
+                    "\ngen_identry:symbol %s is not defined in this file:\npepsy cannot support value passing for this type, sorry\n",
+                    yp1->yp_identifier);
+            code = p->univ_type;
+            break;
+
+        }
+        yp1 = sy->sy_type;
+           /* check for Explicit tags & generate ETAG entries */
+       pd_yt = gen_etag(fp, pd_yt, yp1, flags);
+        code = yp1->yp_code;
+    }
+
+    if (p) {
+       /* how do we check type is consistent with value passed ? */
+       yp1 = new_type(code, -1);
+
+       yp1->yp_flags |= yp->yp_flags & (YP_OPTIONAL|YP_DEFAULT);
+
+       if (pd_yt == NULLYT) {
+           yp1->yp_tag = new_tag(p->univ_class);
+           yp1->yp_tag->yt_value = new_value(YV_NUMBER);
+           yp1->yp_tag->yt_value->yv_number = p->univ_id;
+       } else
+           yp1->yp_tag = pd_yt;
+       yp1->yp_flags |= YP_TAG|YP_IMPLICIT;
+
+       (*fn)(fp, yp, yp1, t, f);
+
+     /* lets free the yp1 allocated above */
+       if (pd_yt == NULLYT) {
+           free((char *)yp1->yp_tag->yt_value);
+           free((char *)yp1->yp_tag);
+       }
+       free((char *)yp1);
+
+       return;
+    }
+       /* check type is consistent with value passed some where??*/
+
+    save_flags = yp1->yp_flags;
+    yp1->yp_flags |= yp->yp_flags & (YP_OPTIONAL|YP_DEFAULT);
+
+    if (pd_yt) {
+       yt = yp1->yp_tag;
+       yp1->yp_tag = pd_yt;
+       yp1->yp_flags |= YP_TAG|YP_IMPLICIT;
+    }
+
+    (*fn)(fp, yp, yp1, t, f);
+
+    if (pd_yt) {       /* restore the tag for later */
+       yp1->yp_tag = yt;
+    }
+    yp1->yp_flags = save_flags;
+
+}
+
+/*
+ * generate the ETAG entry if needed for following the given defined type
+ * down to what it is. Given that its use above has an IMPLICIT tag pd_yt
+ * if it is non Null
+ */
+YT
+gen_etag(fp, pd_yt, yp, flags)
+FILE   *fp;
+YT     pd_yt;
+YP     yp;
+char   *flags;
+{
+    YT yt;
+
+    yt = yp->yp_tag;
+    if (yt && yt->yt_value) {
+       if ((yp->yp_flags & (YP_TAG|YP_IMPLICIT)) == YP_TAG) {
+                                   /* EXPLICIT TAG so generate an ETAG */
+           if (pd_yt)
+               yt = pd_yt;  /* if we have a value passed down use that */
+           (void) fprintf(fp, "\t{ ETAG, 0, %d, %s%s },\n",
+                          yt->yt_value->yv_number,
+                          class2str(yt->yt_class), flags);
+           pd_yt = NULLYT; /* non't pass on any value */
+
+       } else if ((yp->yp_flags & (YP_TAG|YP_IMPLICIT))== (YP_TAG|YP_IMPLICIT)) {
+           /* otherwise it is implicit and so pass its tag down
+            * unless we already have a tag being passed in which case
+            * the passed down tag overrides this current tag
+            */
+           if (pd_yt == NULLYT)
+               pd_yt = yt;
+       }
+    }
+
+    return (pd_yt);
+}
+
+/*
+ * generate the table entry for a value passing defined type which
+ * is equivalent to the given primative type
+ */
+gen_ventry(fp, oyp, yp, t, f)
+FILE   *fp;
+YP     oyp, yp;
+char   *t, *f;
+{
+    char       *p1;
+    register char      s = oyp->yp_prfexp;     /* type of value passing */
+
+
+    if (noindirect(f) && s != 'q' && s != 'a')
+       ferrs(1,
+        "gen_ventry: must specify a field for primative value- not %s\n", f);
+
+    switch (s) {
+    case 'q': /* [[ q parm->qbufptr ]] */
+       if (yp->yp_code != YP_OCT)
+           warning("qbuf pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+                
+       f = setfield(oyp->yp_strexp);
+       if (noindirect(f))
+           p1 = "SOCTETSTRING";
+       else
+           p1 = "OCTETSTRING";
+       break;
+
+    case 's': /* [[ s ptr ]] */
+       if (yp->yp_code != YP_OCT)
+           warning("string pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_strexp);
+       p1 = "T_STRING";
+       break;
+
+    case 'o': /* [[ o ptr $ length ]] */
+       if (yp->yp_code != YP_OCT)
+           warning("octet/length pair passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+       f = setfield(oyp->yp_strexp);
+       p1 = "OCTET_PTR";
+       prnte(fp, t, f, yp, p1);
+       if (oyp->yp_intexp)
+           f = setfield(oyp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "gen_ventry:OCT: must specify a field [[ s .. ]]\n");
+       p1 = "OCTET_LEN";
+       break;
+
+    case 'x': /* [[ x ptr $ length ]] */
+       if (yp->yp_code != YP_BIT && yp->yp_code != YP_BITLIST)
+           warning("bit string/length pair passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_strexp);
+       p1 = "BITSTR_PTR";
+       prnte(fp, t, f, yp, p1);
+       f = setfield(oyp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tenc_typ:BIT: must specify a field [[ x .. ]]\n");
+       p1 = "BITSTR_LEN";
+       break;
+
+    case 'r': /* [[ r REAL ]] */
+       if (yp->yp_code != YP_REAL)
+           warning("Real passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_strexp);
+       p1 = "REALTYPE";
+       break;
+
+    case 'i': /* [[ i INTEGER ]] */
+       if (yp->yp_code != YP_INT && yp->yp_code != YP_INTLIST
+        && yp->yp_code != YP_ENUMLIST)
+           warning("integer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       if (oyp->yp_intexp)
+           f = setfield(oyp->yp_intexp);
+       p1 = "INTEGER";
+       break;
+
+    case 't': /* [[ t Bitvector ]] */
+       if (yp->yp_code != YP_BIT && yp->yp_code != YP_BITLIST)
+           warning("Bitvector (PE) passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_intexp);
+       if (oyp->yp_varexp && !noindirect(f))
+           p1 = "BITSTRING";
+       else
+           p1 = "SBITSTRING";
+       break;
+
+    case 'b': /* [[ b BOOLEAN ]] */
+       if (yp->yp_code != YP_BOOL)
+           warning("Boolean passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       if (oyp->yp_intexp)
+           f = setfield(oyp->yp_intexp);
+       p1 = "BOOLEAN";
+       break;
+
+    case 'O': /* [[ O Object Identifier ]] */
+       if (yp->yp_code != YP_OID)
+           warning("Object Identifier pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+       f = setfield(oyp->yp_strexp);
+       p1 = "OBJID";
+       break;
+
+    case 'a': /* [[ a ANY ]] */
+       if (yp->yp_code != YP_ANY)
+           warning("PE pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+       f = setfield(oyp->yp_strexp);
+       if (noindirect(f))
+           p1 = "SANY";
+       else
+           p1 = "ANY";
+       break;
+     default:
+       ferrd(1, "gen_vident:unknown Value passed %d\n", (int )s);
+   }
+
+    prnte(fp, t, f, yp, p1);
+}
+
+/*
+ * generate a table entry for a function call that handles this type
+ */
+gen_fn(fp, yp, fn)
+FILE   *fp;
+YP     yp;
+char   *fn;    /* name of routine to generate */
+{
+
+    gen_identry(fp, fn, NULLCP, yp, gen_fnentry);
+}
+
+/*
+ * generate a table entry for a function call that handles this type
+ */
+/* ARGSUSED */
+gen_fnentry(fp, oyp, yp, fn, dummy)
+FILE   *fp;
+YP     oyp;
+YP     yp;
+char   *fn;    /* name of routine to generate */
+char   *dummy;
+{
+
+    (void) fprintf(fp, "\t{ FN_CALL, %d, %s, %s },\n",
+                  addptr(fn), c_tag(yp), c_class(yp));
+}
+/*
+ * declare the functions that are used
+ * One day generate ANSII C definitions as well
+ */
+declfns(fp, fn)
+FILE   *fp;
+YFN    fn;
+{
+    if (fn->yfn_enc) {
+       (void) fprintf(fp, "extern int  %s();\n", fn->yfn_enc);
+    }
+    if (fn->yfn_dec) {
+       (void) fprintf(fp, "extern int  %s();\n", fn->yfn_dec);
+    }
+    if (fn->yfn_prt) {
+       (void) fprintf(fp, "extern int  %s();\n", fn->yfn_prt);
+    }
+    if (fn->yfn_fre) {
+       (void) fprintf(fp, "extern int  %s();\n", fn->yfn_fre);
+    }
+}
+/*
+ * generate the table entry to handle an action - UCODE
+ */
+gen_act(fp, act)
+FILE   *fp;
+Action act;
+{
+    (void) fprintf(fp, "\t{ UCODE, %d, 0, 0 }, /* line %d */\n", act->a_num, 
+                       act->a_line);
+}
+
+/*
+ * print out the field entry for a type where all the parameters are given
+ */
+prtfield(fp, typ, t, f, cl, fl)
+FILE   *fp;
+char   *typ, *t, *f, *cl, *fl;
+{
+    if (cl == NULLCP)
+       cl = "0";
+
+    if (f && t) {
+       if (*f == '&')
+           f++;
+       (void) fprintf(fp, "\t{ %s, OFFSET(%s, %s), %s, %s },\n", typ, t, f,
+                                                       cl, fl);
+    } else
+       (void) fprintf(fp, "\t{ %s, 0, %s, %s },\n", typ, cl, fl);
+}
+
+/*
+ * print out the field entry for a Simple type where all the parameters
+ * are given
+ */
+prstfield(fp, typ, t, f, cl, fl)
+FILE   *fp;
+char   *typ, *t, *f, *cl, *fl;
+{
+    if (cl == NULLCP)
+       cl = "0";
+
+    if (f && t && *f == '&') {
+           f++;
+       (void) fprintf(fp, "\t{ S%s, OFFSET(%s, %s), %s, %s },\n", typ, t, f,
+                                                       cl, fl);
+    } else
+       (void) fprintf(fp, "\t{ S%s, 0, %s, %s },\n", typ, cl, fl);
+}
+
+/*
+ * convert an integer into a temporary string. Useful for calling
+ * the printing routines with
+ */
+char   *
+int2tstr(i)
+int    i;
+{
+    static char        buf[STRSIZE];
+
+    (void) sprintf(buf, "%d", i);
+
+    return (buf);
+}
+
+static char    *codetab[] = {
+    "Undefined", "BOOLEAN", "INTEGER", "INTEGER (named numbers)", "BIT STRING",
+    "BIT STRING (named bits)", "OCTET STRING", "NULL", "SEQUENCE",
+    "SEQUENCE OF", "SEQUENCE",  "SET", "SET OF", "SET", "CHOICE",
+    "ANY", "OBJECT IDENTIFIER", "Defined type", "ENUMERATED",
+    "REAL", "Imported type",
+
+    NULL
+};
+/*
+ * produce a user readable name for a yp_code value
+ */
+char   *
+code2name(code)
+int    code;
+{
+    static char        buf[STRSIZE];
+
+    if (code < 0 || code > YP_IMPTYPE) {
+       (void) sprintf(buf, "Unknown code (%d)", code);
+       return (buf);
+    }
+
+    return (codetab[code]);
+}
+/*
+ * print out a description of the yp type for the user that is good enough
+ * for them to identifier the entry if possible
+ */
+char   *
+yp2name(yp)
+YP     yp;
+{
+    static char        buf[STRSIZE*4];
+    char       *p;
+
+    p = buf;
+    if (yp->yp_code == YP_IDEFINED) {
+       if (yp->yp_module) {
+            (void) sprintf(p, "%s.", yp->yp_module);
+            p += strlen(p);
+       }
+       if (yp->yp_identifier)
+            (void) sprintf(p, "%s", yp->yp_identifier);
+       else
+           (void) strcpy(p, "(no identifier)");
+       p += strlen(p);
+       if (yp->yp_modid) {
+            (void) sprintf(p, " (%s)", sprintoid(yp->yp_modid));
+            p += strlen(p);
+       }
+    } else {
+       (void) sprintf(p, "%s", code2name(yp->yp_code));
+       p += strlen(p);
+    }
+
+    if (yp->yp_flags & YP_ID) {
+       (void) sprintf(p, " %s", yp->yp_id);
+       p += strlen(p);
+    }
+
+    if (yp->yp_lineno > 0) {
+       (void) sprintf(p, " on line %d", yp->yp_lineno);
+       p += strlen(p);
+    }
+
+    return (buf);
+
+}
+/*
+ * generate a table entry for the given compound type. It determines wether to
+ * generate a simple type (prstfield) or not.
+ */
+prcte(fp, type, t, f, yp, p1)
+FILE   *fp;
+char   *type;  /* zero if we are foundation type of the table */
+char   *t;     /* parent type */
+char   *f;     /* field name */
+YP     yp;     /* object */
+char   *p1;    /* table entry name */
+{
+    if (type == NULL || type && noindirect(f))
+       prstfield(fp, p1, t, f, c_tag(yp), c_class(yp));
+    else
+       prtfield(fp, p1, t, type ? f : NULLCP, c_tag(yp), c_class(yp));
+}
diff --git a/src/isode/pepsy/fre.c b/src/isode/pepsy/fre.c
new file mode 100644 (file)
index 0000000..5e71fd8
--- /dev/null
@@ -0,0 +1,702 @@
+/* fre.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:19:03  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:16  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:57  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 */
+
+
+/* LINTLIBRARY */
+
+/*
+ * These routines are the driving routines for freeing of the data
+ */
+#include       <stdio.h>
+#include       "pepsy-driver.h" /* for PEPSY_VERSION defn */
+#include       "psap.h"
+#include       "pepsy.h"
+
+
+extern tpe *next_tpe();
+extern int pepsylose ();
+#define NEXT_TPE(p)    p = next_tpe(p)
+#define CHKTAG(mod, p, pe)     ismatch(p, mod, pe->pe_class, pe->pe_id)
+
+static fre_seq();
+static fre_seqof();
+static fre_choice();
+
+/*
+ * free an objects data. Basic algorithm is to walk through it twice
+ * first time freeing all the "children" of the data structure - then
+ * the second time free the structure itself
+ */
+fre_obj(parm, p, mod, dofree)
+modtyp *mod;
+tpe    *p;
+char   *parm;
+int    dofree;
+{
+    char   *malptr = NULL;     /* Have we seen a malloc */
+    int            ndofree = dofree;   /* Does the function below deallocate space */
+
+    if (parm == 0)
+       return (OK);
+
+    if (p->pe_type != PE_START) {
+       (void) pepsylose (mod, p, NULLPE, "fre_obj: missing PE_START\n");
+       return (NOTOK);
+    }
+
+    for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
+
+       /*
+        * we have to have all these cases here because it is different to the
+        * situation when the entry is not the main entry of the typereference.
+        */
+       switch (p->pe_type) {
+       case MEMALLOC:
+           if (dofree) {
+               malptr = parm;
+               ndofree = 0;    /* we are deallocating space on this level */
+           }
+           break;
+
+       default:
+           if (fre_type(parm, p, mod, ndofree) != OK)
+               return (NOTOK);
+           break;
+       }
+    }
+
+    if (malptr && dofree) { /* If we saw a malloc free item */
+       free(malptr);
+       malptr = NULLCP;
+    }
+
+    return (OK);
+}
+
+/*
+ * Handle freeing of single type field. All the more general routines
+ * fall back to this so we can put the code to free something just
+ * here once and it will handle all the cases else where
+ */
+fre_type(parm, p, mod, dofree)
+char   *parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+int    dofree;
+{
+
+    if (parm == 0)
+       return OK;
+
+again:
+    switch (p->pe_type) {
+    case MEMALLOC:
+       break;
+
+    case PE_END:
+    case PE_START:
+    case UCODE:
+       break;
+
+    case BOPTIONAL:
+    case FREE_ONLY:  /* this next entry is for us */
+    case DFLT_F:
+       p++;
+       goto again;
+
+    case ETAG:
+       switch (p->pe_ucode) {
+
+       default:
+           p++;
+           if (fre_type(parm, p, mod, dofree) != OK)
+               return (NOTOK);
+       }
+       break;
+
+    case SEQ_START:
+    case SET_START:
+       if (fre_seq(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+           return (NOTOK);
+       break;
+
+    case SEQOF_START:
+    case SETOF_START:
+       if (fre_seqof(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+           return (NOTOK);
+       break;
+
+    case SSEQ_START:
+    case SSET_START:
+       if (fre_seq((char *) parm + p->pe_ucode, p, mod, dofree) != OK)
+           return (NOTOK);
+       break;
+
+    case SSEQOF_START:
+    case SSETOF_START:
+       if (fre_seqof((char *) parm + p->pe_ucode, p, mod, dofree) != OK)
+           return (NOTOK);
+       break;
+
+    case IMP_OBJ:
+       p++;
+       if (p->pe_type == EXTOBJ) {
+           if (fre_obj(*(char **) (parm + p->pe_ucode),
+                   (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+                   EXT2MOD(mod, (p + 1)), 1) != OK)
+               return (NOTOK);
+       } else if (p->pe_type == SEXTOBJ) {
+           if (fre_obj((parm + p->pe_ucode),
+                   (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+                   EXT2MOD(mod, (p + 1)), dofree) != OK)
+               return (NOTOK);
+       } else if (p->pe_type == SOBJECT) {
+           if (fre_obj((char *) parm + p->pe_ucode, mod->md_dtab[p->pe_tag], mod, dofree) != OK)
+               return (NOTOK);
+       } else
+           if (fre_obj(*(char **) (parm + p->pe_ucode),
+                   mod->md_dtab[p->pe_tag], mod, 1) != OK)
+               return (NOTOK);
+       break;
+
+    case SOBJECT:
+       if (fre_obj((char *) parm + p->pe_ucode, mod->md_dtab[p->pe_tag], mod, dofree) != OK)
+           return (NOTOK);
+       break;
+
+    case OBJECT:
+       if (fre_obj(*(char **) (parm + p->pe_ucode), mod->md_dtab[p->pe_tag],
+               mod, 1) != OK)
+           return (NOTOK);
+       break;
+
+    case SCHOICE_START:
+       if (fre_choice((char *) parm + p->pe_ucode, p, mod, dofree) != OK)
+           return (NOTOK);
+       break;
+
+    case CHOICE_START:
+       if (fre_choice(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+           return (NOTOK);
+       break;
+
+    case SEXTOBJ:
+       if (p[1].pe_type != EXTMOD) {
+           (void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
+           return (NOTOK);
+       }
+       if (fre_obj(parm + p->pe_ucode, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+               EXT2MOD(mod, (p + 1)), dofree) != OK)
+           return (NOTOK);
+       break;
+
+    case EXTOBJ:
+       if (p[1].pe_type != EXTMOD) {
+           (void) pepsylose (mod, p, NULLPE, "fre_type:missing EXTMOD");
+           return (NOTOK);
+       }
+       if (fre_obj(*(char **) (parm + p->pe_ucode),
+               (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+               EXT2MOD(mod, (p + 1)), 1) != OK)
+           return (NOTOK);
+       break;
+
+    case INTEGER:
+    case BOOLEAN:
+    case T_NULL:
+    case REALTYPE:
+       break;
+
+    case SANY:
+       /*
+        * These tests of the pointer don't appear necessary from the
+        * definition of encoding and decoding but ISODE generates
+        * freeing code that does these checks and ISODE's ps layer
+        * definitely requires it
+        */
+       if (parm != NULL) {
+           pe_free((PE) parm);
+           parm = NULL;
+       }
+       break;
+
+    case ANY:
+       if (*(char **) (parm + p->pe_ucode) != NULL) {
+           pe_free(*(PE *) (parm + p->pe_ucode));
+           *((PE *) (parm + p->pe_ucode)) = NULLPE;
+       }
+       break;
+
+    case SOCTETSTRING:
+       if (parm != NULL) {
+           qb_free((struct qbuf *) parm);
+           parm = NULL;
+       }
+       break;
+
+    case T_STRING:
+    case OCTET_PTR:
+    case BITSTR_PTR:
+       if (*(char **) (parm + p->pe_ucode) != NULL) {
+           free(*(char **) (parm + p->pe_ucode));
+           *(char **) (parm + p->pe_ucode) = NULLCP;
+       }
+       break;
+
+    case OCTETSTRING:
+       if (*(char **) (parm + p->pe_ucode) != NULL) {
+           qb_free(*(struct qbuf **) (parm + p->pe_ucode));
+           *(struct qbuf **) (parm + p->pe_ucode) = (struct qbuf *)0;
+       }
+       break;
+
+    case SBITSTRING:
+       if (parm != NULL) {
+           pe_free((PE) parm);
+           parm = NULL;
+       }
+       break;
+
+    case BITSTRING:
+       if (*(char **) (parm + p->pe_ucode) != NULL) {
+           pe_free(*(PE *) (parm + p->pe_ucode));
+           *(PE *) (parm + p->pe_ucode) = NULLPE;
+       }
+       break;
+
+    case SOBJID:
+       if (parm != NULL) {
+           oid_free((OID) parm);
+           parm = NULL;
+       }
+       break;
+
+    case OBJID:
+       if (*(char **) (parm + p->pe_ucode) != NULL) {
+           oid_free(*(OID *) (parm + p->pe_ucode));
+           *(OID *) (parm + p->pe_ucode) = NULLOID;
+       }
+       break;
+
+    case FN_CALL:
+        break; /* can't do anything with this */
+
+    case FFN_CALL:
+       if ((FN_PTR(mod, p))(parm) == NOTOK)
+           return pepsylose (mod, p, NULLPE,
+                             "fre_type:FN_CALL:call failed");
+       break;
+
+    default:
+       (void) pepsylose (mod, p, NULLPE, "fre_type: %d not implemented\n",
+           p->pe_type);
+       return (NOTOK);
+    }
+
+    return (OK);
+}
+
+/*
+ * free elements of a sequential type. e.g. sequence or set
+ */
+static fre_seq(parm, p, mod, dofree)
+char   *parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+int    dofree;
+{
+/*    int    *popt = NULL;     Pointer to optional field */
+    char   *malptr = NULL;     /* Have we seen a malloc */
+    int            ndofree = dofree;   /* Does the function below deallocate space */
+
+
+    if (parm == 0)
+       return OK;
+
+    if (p->pe_type != SEQ_START && p->pe_type != SET_START
+     && p->pe_type != SSEQ_START && p->pe_type != SSET_START) {
+       (void) pepsylose (mod, p, NULLPE, "fre_seq: bad starting item %d\n",
+           p->pe_type);
+       return (NOTOK);
+    }
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    while (p->pe_type != PE_END) {
+
+       switch (p->pe_type) {
+       case MEMALLOC:
+           if (dofree) {
+               malptr = parm;
+               ndofree = 0;    /* we are deallocating space on this level */
+           }
+           break;
+
+       case OPTL:
+/*         popt = (int *) (parm + p->pe_ucode); */
+           break;
+
+       case ETAG:
+           p++;
+           continue;
+
+       case UCODE:
+           break;
+
+       case SET_START:
+       case SEQ_START:
+           if (fre_seq(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+               return (NOTOK);
+           break;
+
+       case SETOF_START:
+       case SEQOF_START:
+           if (fre_seqof(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+               return (NOTOK);
+           break;
+
+       case SSEQ_START:
+       case SSET_START:
+           if (fre_seq((char *) parm + p->pe_ucode, p, mod, ndofree) != OK)
+               return (NOTOK);
+           break;
+
+       case SSEQOF_START:
+       case SSETOF_START:
+           if (fre_seqof((char *) parm + p->pe_ucode, p, mod, ndofree) != OK)
+               return (NOTOK);
+           break;
+
+       case IMP_OBJ:
+           p++;
+           continue;
+
+       case SOBJECT:
+           if (fre_obj((char *) parm + p->pe_ucode,
+               mod->md_dtab[p->pe_tag], mod, ndofree) != OK)
+               return (NOTOK);
+           break;
+
+       case OBJECT:
+           if (fre_obj(*(char **) (parm + p->pe_ucode),
+                   mod->md_dtab[p->pe_tag], mod, 1) != OK)
+               return (NOTOK);
+           break;
+
+       case SCHOICE_START:
+           if (fre_choice((char *) parm + p->pe_ucode, p, mod, ndofree) != OK)
+               return (NOTOK);
+           break;
+
+       case CHOICE_START:
+           if (fre_choice(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+               return (NOTOK);
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               (void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
+               return (NOTOK);
+           }
+           if (fre_obj(parm + p->pe_ucode, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+                   EXT2MOD(mod, (p + 1)), ndofree) != OK)
+               return (NOTOK);
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               (void) pepsylose (mod, p, NULLPE, "fre_seq:missing EXTMOD");
+               return (NOTOK);
+           }
+           if (fre_obj(*(char **) (parm + p->pe_ucode),
+                   (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+                   EXT2MOD(mod, (p + 1)), 1) != OK)
+               return (NOTOK);
+           break;
+
+       default:
+           if (fre_type(parm, p, mod, ndofree) != OK)
+               return (NOTOK);
+           break;
+       }
+
+       NEXT_TPE(p);
+    }
+    if (malptr && dofree) {    /* If we saw a malloc free item */
+       free(malptr);
+       malptr = NULLCP;
+    }
+    
+    return (OK);
+
+}
+
+/*
+ * free all the fields in a SET OF/SEQUENCE OF type structure. We
+ * must follow the linked list until the end
+ */
+static fre_seqof(parm, p, mod, dofree)
+char   *parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+int    dofree;
+{
+    tpe    *start;             /* first entry in list */
+    char   *oparm;
+
+    if (parm == 0)
+       return OK;
+
+    if (p->pe_type != SEQOF_START && p->pe_type != SETOF_START
+     && p->pe_type != SSEQOF_START && p->pe_type != SSETOF_START) {
+       (void) pepsylose (mod, p, NULLPE, "fre_seqof: illegal field");
+       return (NOTOK);
+    }
+    for (start = p; (char *) parm != NULL; p = start) {
+       p++;
+
+       if (p->pe_type == DFLT_B)
+           p++;
+
+       while (p->pe_type != PE_END) {
+
+           switch (p->pe_type) {
+           case MEMALLOC:
+               break;
+
+           case ETAG:
+               p++;
+               continue;
+
+           case UCODE:
+               break;
+
+           case SEQ_START:
+           case SET_START:
+               if (fre_seq(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+                   return (NOTOK);
+               break;
+
+           case SEQOF_START:
+           case SETOF_START:
+               if (fre_seqof(*(char **) (parm + p->pe_ucode), p, mod, 1) != OK)
+                   return (NOTOK);
+               break;
+
+           case SSEQ_START:
+           case SSET_START:
+               if (fre_seq((char *) parm + p->pe_ucode, p, mod, dofree) != OK)
+                   return (NOTOK);
+               break;
+
+           case SSEQOF_START:
+           case SSETOF_START:
+               if (fre_seqof((char *) parm + p->pe_ucode, p, mod, dofree) != OK)
+                   return (NOTOK);
+               break;
+
+           case IMP_OBJ:
+               p++;
+               continue;
+
+           case SOBJECT:
+               if (fre_obj(parm + p->pe_ucode, mod->md_dtab[p->pe_tag], mod, 0) != OK)
+                   return (NOTOK);
+               break;
+
+           case OBJECT:
+               if (fre_obj(*(char **) (parm + p->pe_ucode),
+                       mod->md_dtab[p->pe_tag], mod, 1) != OK)
+                   return (NOTOK);
+               break;
+
+           case SCHOICE_START:
+               if (fre_choice((char *) parm + p->pe_ucode, p, mod, 0) != OK)
+                   return (NOTOK);
+               break;
+
+           case CHOICE_START:
+               if (fre_choice(*(char **)(parm + p->pe_ucode), p, mod, 1) != OK)
+                   return (NOTOK);
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD) {
+                   (void) pepsylose (mod, p, NULLPE,
+                       "fre_seqof: missing EXTMOD");
+                   return (NOTOK);
+               }
+               if (fre_obj(parm + p->pe_ucode, (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+                       EXT2MOD(mod, (p + 1)), 0) != OK)
+                   return (NOTOK);
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD) {
+                   (void) pepsylose (mod, p, NULLPE,
+                       "fre_seqof: missing EXTMOD");
+                   return (NOTOK);
+               }
+               if (fre_obj(*(char **) (parm + p->pe_ucode),
+                       (EXT2MOD(mod, (p + 1)))->md_dtab[p->pe_tag],
+                       EXT2MOD(mod, (p + 1)), 1) != OK)
+                   return (NOTOK);
+               break;
+
+           default:
+               if (fre_type(parm, p, mod, 1) != OK)
+                   return (NOTOK);
+               break;
+           }
+
+           NEXT_TPE(p);
+       }
+       oparm = parm;
+       parm = *(char **) (parm + p->pe_ucode); /* Any more ? */
+       if (dofree) {
+           free(oparm);
+           oparm = NULLCP;
+       }
+    }
+
+    return (OK);
+
+}
+
+/*
+ * free the item of the choice. Use the SCTRL field to determine
+ * which item is present and then call the appropriate routine to
+ * free it
+ */
+static fre_choice(parm, p, mod, dofree)
+char   *parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+int    dofree;
+{
+    int     cnt;
+    char   *malptr = NULL;     /* Have we seen a malloc */
+    int            ndofree = dofree;   /* Does the function below deallocate space */
+
+    if (parm == 0)
+       return OK;
+
+    if (p->pe_type != CHOICE_START && p->pe_type != SCHOICE_START) {
+       (void) pepsylose (mod, p, NULLPE,
+           "fre_choice:CHOICE_START missing found %d\n", p->pe_type);
+    }
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    if (p->pe_type == MEMALLOC) {
+       if (dofree) {
+           malptr = parm;
+           ndofree = 0;        /* we are deallocating space on this level */
+       }
+       p++;
+    }
+    if (p->pe_type != SCTRL) {
+       (void) pepsylose (mod, p, NULLPE,
+           "fre_choice: missing SCTRL information\n");
+       return (NOTOK);
+    }
+    cnt = *(int *) (parm + p->pe_ucode);
+    if (cnt != 0)
+       cnt--;
+    if (cnt < 0) {
+       (void) pepsylose (mod, p, NULLPE,"fre_choice:offset negative %d", cnt);
+       return (NOTOK);
+    }
+    for (p++; p->pe_type != PE_END; NEXT_TPE(p)) {
+       if (ISDTYPE(p)) {
+           if (cnt == 0) {
+               if (fre_type(parm, p, mod, ndofree) != OK)
+                   return (NOTOK);
+               if (malptr && dofree) { /* If we saw a malloc free item */
+                   free(malptr);
+                   malptr = NULLCP;
+               }
+               return (OK);
+           }
+           cnt--;
+       }
+    }
+
+    (void) pepsylose (mod, p, NULLPE, "fre_choice: no choice taken");
+    return (NOTOK);
+}
+/*
+ * look out for FN_CALL - if this entry is really a FN_CALL return non zero
+ * else return 0
+ * Basically we have to stop FN_CALL being tested by hasdata which will call
+ * the decoding function which is illegal and gives rubbish.
+ */
+callsfn(p, mod)
+tpe    *p;
+modtyp *mod;
+{
+
+    while (p->pe_type != PE_END) {
+       switch (p->pe_type) {
+       case ETAG:
+           p++;
+           continue;
+
+       case FN_CALL:
+           return (1);
+
+       default:
+       case INTEGER:
+       case REALTYPE:
+       case BOOLEAN:
+       case T_NULL:
+       case IMP_OBJ:
+       case OBJECT:
+           return (0);
+       }
+    }
+
+    (void) pepsylose (mod, p, NULLPE,"callsfn:Corrupted tables:PE_END found\n");
+    ferr(1, "callsfn:Mangled tables\n");
+    /*NOTREACHED*/
+
+}
diff --git a/src/isode/pepsy/lex.l.gnrc b/src/isode/pepsy/lex.l.gnrc
new file mode 100644 (file)
index 0000000..5676e38
--- /dev/null
@@ -0,0 +1,630 @@
+/* lex.l - lex ASN.1 analyzer */
+/* %WARNING% */
+
+%{
+#ifndef        lint
+static char *RCSid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:38  eichin
+ * autoconfed isode for kerberos work
+ *
+Revision 1.1  94/06/10  03:19:06  eichin
+autoconfed isode for kerberos work
+
+# Revision 1.1  1994/05/31 20:39:22  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+ * Revision 8.0  91/07/17  12:42:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ *
+ */
+
+
+struct table {
+    char   *t_keyword;
+    int            t_value;
+    int            t_porting;
+};
+
+static struct table reserved[] = {
+    "ABSENT", ABSENT, 0,
+    "ANY", ANY, 0,
+    "APPLICATION", APPLICATION, 0,
+    "BEGIN", BGIN, 0,
+    "BIT", BIT, 0,
+    "BITSTRING", BITSTRING, 0,
+    "BOOLEAN", BOOLEAN, 0,
+    "BY", BY, 0,
+    "CHOICE", CHOICE, 0,
+    "COMPONENT", COMPONENT, 0,
+    "COMPONENTS", COMPONENTS, 0,
+    "COMPONENTSOF", COMPONENTSOF, 0,
+    "DECODER", DECODER, 0,
+    "DEFAULT", DEFAULT, 0,
+    "DEFINED", DEFINED, 0,
+    "DEFINITIONS", DEFINITIONS, 0,
+    "ENCODER", ENCODER, 0,
+    "ENCRYPTED", ENCRYPTED, 0,
+    "END", END, 0,
+    "ENUMERATED", ENUMERATED, 0,
+    "EXPLICIT", EXPLICIT, 0,
+    "EXPORTS", EXPORTS, 0,
+    "FALSE", FALSE, 0,
+    "FROM", FROM, 0,
+    "IDENTIFIER", IDENTIFIER, 0,
+    "IMPLICIT", IMPLICIT, 0,
+    "IMPORTS", IMPORTS, 0,
+    "INCLUDE", INCLUDES, 0,
+    "INTEGER", INTEGER, 0,
+    "MIN", MIN, 0,
+    "MAX", MAX, 0,
+    "NULL", NIL, 0,
+    "OBJECT", OBJECT, 0,
+    "OCTET", OCTET, 0,
+    "OCTETSTRING", OCTETSTRING, 0,
+    "OF", OF, 0,
+    "OPTIONAL", OPTIONAL, 0,
+    "PREFIXES", PREFIXES, 0,
+    "PRESENT", PRESENT, 0,
+    "PRINTER", PRINTER, 0,
+    "PRIVATE", PRIVATE, 0,
+    "REAL", REAL, 0,
+    "SECTIONS", SECTIONS, 0,
+    "SEQUENCE", SEQUENCE, 0,
+    "SEQUENCEOF", SEQUENCEOF, 0,
+    "SET", SET, 0,
+    "SETOF", SETOF, 0,
+    "SIZE", SIZE, 0,
+    "STRING", STRING, 0,
+    "TAGS", TAGS, 0,
+    "TRUE", TRUE, 0,
+    "UNIVERSAL", UNIVERSAL, 0,
+    "WITH", WITH, 0,
+    "PLUS-INFINITY", PLUSINFINITY, 0,
+    "MINUS-INFINITY", MINUSINFINITY, 0,
+%BEGIN(ROSY)%
+    "OPERATION", OPERATION, 1,
+    "ARGUMENT", ARGUMENT, 0,
+    "RESULT", RESULT, 0,
+    "ERRORS", ERRORS, 0,
+    "LINKED", LINKED, 0,
+    "ERROR", ERROR, 1,
+    "PARAMETER", PARAMETER, 0,
+/* start new stuff */
+    "ABSTRACT-OPERATION", OPERATION, 0,
+    "ABSTRACT-ERROR", ERROR, 0,
+    "ABSTRACT", ABSTRACT, 0,
+    "OPERATIONS", OPERATIONS, 0,
+    "CONSUMER", CONSUMER, 0,
+    "SUPPLIER", SUPPLIER, 0,
+    "INVOKES", INVOKES, 0,
+    "PORT", PORT, 0,
+    "PORTS", PORTS, 0,
+/* refine is beyond me! (JPO)
+    "REFINE", REFINE, 0,
+    "AS", AS, 0,
+    "RECURRING", RECURRING, 0,
+    "VISIBLE", VISIBLE, 0,
+    "PAIRED", PAIRED, 0,
+*/
+/* end new stuff */
+%END(ROSY)%
+%BEGIN(MOSY)%
+    "OBJECT-TYPE", OBJECTYPE, 1,
+    "SYNTAX", SYNTAX, 0,
+    "ACCESS", ACCESS, 0,
+    "STATUS", STATUS, 0,
+%END(MOSY)%
+    NULL, 0
+};
+
+%}
+
+%%
+
+"--"                   {   register int c, d;
+
+                           for (d = 0; c = input (); d = c == '-')
+                               if (c == '\n' || (d && c == '-'))
+                                   break;
+                       }
+[ \t]*                 {
+                           if (yydebug)
+                               fprintf (stderr, "WT\n");
+                       }
+\n                     {
+                           if (yydebug)
+                               fprintf (stderr, "NL\n");
+                       }
+"::="                  {
+                           if (yydebug)
+                               fprintf (stderr, "SY: CCE\n");
+                           return CCE;
+                       }
+"..."                  {
+                           if (yydebug)
+                               fprintf (stderr, "SY: DOTDOTDOT\n");
+                           return DOTDOTDOT;
+                       }
+".."                   {
+                           if (yydebug)
+                               fprintf (stderr, "SY: DOTDOT\n");
+                           return DOTDOT;
+                       }
+"."                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: DOT\n");
+                           return DOT;
+                       }
+";"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: SEMICOLON");
+                           return SEMICOLON;
+                       }
+","                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: COMMA\n");
+                           return COMMA;
+                       }
+"{"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: LBRACE\n");
+                           return LBRACE;
+                       }
+"}"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: RBRACE\n");
+                           return RBRACE;
+                       }
+"|"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: BAR\n");
+                           return BAR;
+                       }
+"-"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: MINUS\n");
+                           return MINUS;
+                       }
+"+"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: PLUS\n");
+                           return PLUS;
+                       }
+%BEGIN(ROSY)%
+"[S]"                  {
+                           if (yydebug)
+                               fprintf (stderr, "SY: OBJECTSUPPLIER\n");
+                           return OBJECTSUPPLIER;
+                       }
+"[C]"                  {
+                           if (yydebug)
+                               fprintf (stderr, "SY: OBJECTCONSUMER\n");
+                           return OBJECTCONSUMER;
+                       }
+%END(ROSY)%
+"[["|"$"|"<<"          {   register int tok, c, d, len;
+                           register char *cp, *ep, *pp;
+
+                           if (*yytext == '$')
+                               tok = VLENGTH;
+                           else
+                               if (*yytext == '<')
+                                   tok = CONTROL;
+                               else {
+                                   while((c = input()) == ' ' || c =='\t')
+                                       continue;
+                                   switch (c) {
+                                       case 'a': tok = VALA;
+                                                 break;
+                                       case 'b': tok = VALB;
+                                                 break;
+                                       case 'i': tok = VALI;
+                                                 break;
+                                       case 's': tok = VALS;
+                                                 break;
+                                       case 'o': tok = VALO;
+                                                 break;
+                                       case 'x': tok = VALX;
+                                                 break;
+                                       case 'p': tok = VALP;
+                                                 break;
+                                       case 'q': tok = VALQ;
+                                                 break;
+                                       case 'r': tok = VALR;
+                                                 break;
+                                       case 't': tok = VALT;
+                                                 break;
+                                       case 'O': tok = VALOID;
+                                                 break;
+                                       case 'P': tok = PARAMETERTYPE;
+                                                 break;
+                                       case 'T': tok = VALTYPE;
+                                                 break;
+                                       case 'E': tok = ENC_FN;
+                                                 break;
+                                       case 'D': tok = DEC_FN;
+                                                 break;
+                                       case 'F': tok = FRE_FN;
+                                                 break;
+                                       default : myyerror ("unknown token: \"%s\"", yytext);
+                                                 break;
+                                   }
+                                   if ((c = input()) != ' ' && c != '\t'
+                                       && c != '\n')
+                                       yyerror ("syntax error in [[ ... ]]");
+                               }
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading value");
+                               if ((d == ']' && c == ']' && tok !=CONTROL) ||
+                                   (c == '$' && (tok ==VALX || tok ==VALO)) ||
+                                   (d == '>' && c == '>' && tok ==CONTROL)) {
+                                   if ((tok == VALX || tok == VALO) &&
+                                      (c != '$'))
+                                      yyerror("Missing '$' in [[ - ]]");
+                                   if (c == '$') {unput(c); *cp = NULL;}
+                                   else *--cp = NULL;
+                                   yylval.yy_string = pp;
+                                   if (yydebug)
+                                       fprintf (stderr, "VAL: \"%s\"\n",
+                                               yylval.yy_string);
+                                   return tok;
+                               }
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+"["                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: LBRACKET\n");
+                           return LBRACKET;
+                       }
+"]"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: RBRACKET\n");
+                           return RBRACKET;
+                       }
+"<"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: LANGLE\n");
+                           return LANGLE;
+                       }
+"("                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: LPAREN\n");
+                           return LPAREN;
+                       }
+")"                    {
+                           if (yydebug)
+                               fprintf (stderr, "SY: RPAREN\n");
+                           return RPAREN;
+                       }
+"\*"                   {
+                           if (yydebug)
+                               fprintf (stderr, "SY: STAR\n");
+                           return STAR;
+                       }
+[0-9]+                 {
+                           (void) sscanf (yytext, "%d", &yylval.yy_number);
+                           if (yydebug)
+                               fprintf (stderr, "LIT: 0x%x\n", yylval.yy_number);
+                           return LITNUMBER;
+                       }
+-[0-9]+                        {
+                           (void) sscanf (yytext, "%d", &yylval.yy_number);
+                           if (yydebug)
+                               fprintf (stderr, "LIT: 0x%x\n", yylval.yy_number);
+                           return LITNUMBER;
+                       }
+'[^'$]*'[BbHh]         {   register char *cp; register int i;
+
+                           switch (*(cp = yytext + strlen (yytext) - 1)) {
+                               case 'H':
+                               case 'h':
+                                   *--cp = NULL;
+                                   for (cp = yytext + 1; *cp; cp++)
+                                       if (!isxdigit(*cp))
+                                           yyerror ("bad hex string");
+                                   yylval.yy_string = new_string(yytext + 1);
+                                   if (yydebug)
+                                       fprintf (stderr,
+                                           "HSTRING: %s\n", yylval.yy_string);
+                                   return HSTRING;
+
+                               case 'B':
+                               case 'b':
+                                   *--cp = NULL;
+                                   for (cp = yytext + 1; *cp; cp++)
+                                       if (*cp != '0' && *cp != '1')
+                                           yyerror ("bad bit string");
+                                   yylval.yy_string = new_string(yytext + 1);
+                                   if (yydebug)
+                                       fprintf (stderr,
+                                           "BSTRING: %s\n", yylval.yy_string);
+                                   return BSTRING;
+                           }
+                           yyerror ("illegal string");
+                       }
+\"[^\"$]*\"            {
+                           yytext[strlen (yytext) - 1] = NULL;
+                           yylval.yy_string = new_string (yytext + 1);
+                           if (yydebug)
+                               fprintf (stderr, "LIT: \"%s\"\n", yylval.yy_string);
+                           return LITSTRING;
+                       }
+[A-Z][A-Za-z0-9-]*     {   register struct table *t;
+
+                           for (t = reserved; t -> t_keyword; t++)
+                               if (strcmp (t -> t_keyword, yytext) == 0) {
+                                   if (yyporting && t -> t_porting)
+                                       break;
+                                   if (yydebug)
+                                       fprintf (stderr,
+                                                 "KE: \"%s\"\n", yytext);
+                                   yylval.yy_number = yylineno;
+                                   return t -> t_value;
+                               }
+                           yylval.yy_string = new_string (yytext);
+                           if (yydebug)
+                               fprintf (stderr, "ID: \"%s\"\n", yylval.yy_string);
+                           return ID;
+                       }
+[a-z][A-Za-z0-9-]*     {   yylval.yy_string = new_string (yytext);
+                           if (yydebug)
+                               fprintf (stderr, "NAME: \"%s\"\n", yylval.yy_string);
+                           return NAME;
+                       }
+"%["                   {   register int c, d, len;
+                           register char *cp, *ep, *pp;
+
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading value");
+                               if (d == '%' && c == ']' ) {
+                                   *--cp = NULL;
+                                   yylval.yy_string = pp;
+                                   if (yydebug)
+                                       fprintf (stderr, "VAL: \"%s\"\n",
+                                                yylval.yy_string);
+                                   return SCTRL;
+                               }
+                               if (d == '\n')
+                                   yyerror ("newline in %[ %] construct");
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+"%{"                   {   register int c, d, len;
+                           int     mylineno;
+                           register char *cp, *ep, *pp;
+
+                           mylineno = yylineno;
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading action");
+                               if (d == '%' && c == '}') {
+                                   *--cp = NULL;
+                                   yylval.yy_action = new_action (pp, mylineno);;
+                                   if (yydebug)
+                                       fprintf (stderr, "ACTION: \"%s\", %d\n",
+                                               yylval.yy_action -> ya_text,
+                                               yylval.yy_action -> ya_lineno);
+                                   return ACTION;
+                               }
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+%BEGIN(PEPSY)%
+"<[DEP]<"                      {   register int c, d, len;
+                           int     mylineno;
+                           register char *cp, *ep, *pp;
+                           int c_typ = (yytext[1] == 'D' ? DCHOICE :
+                               (yytext[1] == 'E' ? ECHOICE : PCHOICE));
+
+                           mylineno = yylineno;
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading action");
+                               if (d == '>' && c == '>') {
+                                   *--cp = NULL;
+                                   yylval.yy_action = new_action (pp, mylineno);;
+                                   if (yydebug)
+                                       fprintf (stderr,"%cCHOICE: \"%s\", %d\n",
+                                                yytext[1],
+                                               yylval.yy_action -> ya_text,
+                                               yylval.yy_action -> ya_lineno);
+                                   return c_typ;
+                               }
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+
+"%E{"                  {   register int c, d, len;
+                           int     mylineno;
+                           register char *cp, *ep, *pp;
+
+                           mylineno = yylineno;
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading action");
+                               if (d == '%' && c == '}') {
+                                   *--cp = NULL;
+                                   yylval.yy_action = new_action (pp, mylineno);;
+                                   if (yydebug)
+                                       fprintf (stderr,"EACTION: \"%s\", %d\n",
+                                               yylval.yy_action -> ya_text,
+                                               yylval.yy_action -> ya_lineno);
+                                   return EACTION;
+                               }
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+"%D{"                  {   register int c, d, len;
+                           int     mylineno;
+                           register char *cp, *ep, *pp;
+
+                           mylineno = yylineno;
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading action");
+                               if (d == '%' && c == '}') {
+                                   *--cp = NULL;
+                                   yylval.yy_action = new_action (pp, mylineno);;
+                                   if (yydebug)
+                                       fprintf (stderr,"DACTION: \"%s\", %d\n",
+                                               yylval.yy_action -> ya_text,
+                                               yylval.yy_action -> ya_lineno);
+                                   return DACTION;
+                               }
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+"%P{"                  {   register int c, d, len;
+                           int     mylineno;
+                           register char *cp, *ep, *pp;
+
+                           mylineno = yylineno;
+                           if ((pp = malloc ((unsigned) (len = BUFSIZ)))
+                                   == NULL)
+                               yyerror ("out of memory");
+
+                           for (ep = (cp = pp) + len - 1, d = NULL;; d = c) {
+                               if ((c = input ()) == NULL)
+                                   yyerror ("end-of-file while reading action");
+                               if (d == '%' && c == '}') {
+                                   *--cp = NULL;
+                                   yylval.yy_action = new_action (pp, mylineno);;
+                                   if (yydebug)
+                                       fprintf (stderr,"PACTION: \"%s\", %d\n",
+                                               yylval.yy_action -> ya_text,
+                                               yylval.yy_action -> ya_lineno);
+                                   return PACTION;
+                               }
+                               if (cp >= ep) {
+                                   register int curlen = cp - pp;
+                                   register char *dp;
+
+                                   if ((dp = realloc (pp,
+                                               (unsigned) (len += BUFSIZ)))
+                                           == NULL)
+                                       yyerror ("out of memory");
+                                   cp = dp + curlen;
+                                   ep = (pp = dp) + len - 1;
+                               }
+                               *cp++ = c;
+                           }
+                       }
+%END(PEPSY)%
+.                      {   
+                           myyerror ("unknown token: \"%s\"", yytext);
+                       }
+
+%%
diff --git a/src/isode/pepsy/libpepsy.3 b/src/isode/pepsy/libpepsy.3
new file mode 100644 (file)
index 0000000..a4f99a8
--- /dev/null
@@ -0,0 +1,42 @@
+.TH LIBPEPSY 3 "16 Oct 1987"
+.\" $Header$
+.\"
+.\"
+.\" $Log$
+.\" Revision 1.1  1994/06/10 03:30:42  eichin
+.\" autoconfed isode for kerberos work
+.\"
+Revision 1.1  94/06/10  03:19:08  eichin
+autoconfed isode for kerberos work
+
+# Revision 1.1  1994/05/31 20:39:24  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+.\" Revision 8.0  91/07/17  12:42:58  isode
+.\" Release 7.0
+.\" 
+.\" 
+.SH NAME
+libpepsy \- PEPSY support library
+.SH SYNOPSIS
+\fIpepsy\fR\0...\0\fImodule.py\fR
+.sp
+\fIcc\fR\0...\0\fImodule_tables.c\fR\0\fB\-lisode\fR
+.SH DESCRIPTION
+The \fIlibpepsy\fR library contains driver routines for processing
+the tables produced by \fIpepsy\fR.
+Also contains the tables for the ASN.1 defined types
+generated by \fIpepsy\fR and some miscellanous printing routines in
+\fIvprint.c\fR.
+This library is unspectacular but necessary.
+.SH FILES
+None
+.SH "SEE ALSO"
+pepsy(1)
+.SH DIAGNOSTICS
+Routines for users use routines return
+the manifest constant \fBNOTOK\fR (\-1) on error.
+Others return \fBNULLPE\fR on error.
+.SH AUTHOR
+Andrew Worsley,
+CSIRO and UCL
diff --git a/src/isode/pepsy/macdefs.h b/src/isode/pepsy/macdefs.h
new file mode 100644 (file)
index 0000000..b39a9d2
--- /dev/null
@@ -0,0 +1,57 @@
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:44  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:19:10  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:31  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:59  isode
+ * Release 7.0
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+/*
+ * common encoding macro definitions
+ */
+
+#define DO_OFFSET(parm, p)     ((parm) + (p)->pe_ucode)
+#define NO_OFFSET(parm, p)     (parm)
+
+/* various things From Pointer And Offset- *_FPAO */
+
+#define INT_FPAO(parm, p)      (*(integer *)DO_OFFSET(parm, p))
+
+#define REAL_FPAO(parm, p)     (*(double *)DO_OFFSET(parm, p))
+
+#define CHAR_FPAO(parm, p)     (*(char *)DO_OFFSET(parm, p))
+
+#define OID_FPAO(parm, p)      (*(OID *)DO_OFFSET(parm, p))
+#define SOID_FPAO(parm, p)     ((OID)NO_OFFSET(parm, p))
+
+#define PTR_FPAO(parm, p)      (*(char **)DO_OFFSET(parm, p))
+#define SPTR_FPAO(parm, p)     ((char *)NO_OFFSET(parm, p))
+
+#define QB_FPAO(parm, p)       (*(struct qbuf **)DO_OFFSET(parm, p))
+#define SQB_FPAO(parm, p)      ((struct qbuf *)NO_OFFSET(parm, p))
+
+#define PE_FPAO(parm, p)       (*(PE *)DO_OFFSET(parm, p))
+#define SPE_FPAO(parm, p)      ((PE)NO_OFFSET(parm, p)
+
+#define TYPE2MOD(mod, p)       ((mod)->md_etab[p->pe_tag])
diff --git a/src/isode/pepsy/main.c b/src/isode/pepsy/main.c
new file mode 100644 (file)
index 0000000..1b5360e
--- /dev/null
@@ -0,0 +1,4244 @@
+/* main.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:46  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  94/06/10  03:19:12  eichin
+ * autoconfed isode for kerberos work
+ * 
+ * Revision 1.1  1994/05/31 20:39:33  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:42:59  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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       <ctype.h>
+#include "config.h"
+#ifdef PEPSY_REALS
+#include       <math.h>
+#define F_SMALL        (1.0e-10)       /* How accurate should reals agree */
+#endif
+#include       "psap.h"
+#include       "T1-types.h"
+#include       "T2-types.h"
+#include       "T3-types.h"
+
+
+
+#include "test_table.h"
+       /* compactly generate the new item of data */
+#define new(x) ((x *)calloc(1, sizeof (x)))
+
+#define NULLQB (struct qbuf *)0
+char   *fill();
+static char   *idname();
+static char   *clname();
+static int prntbits();
+static int pclen();
+static int prntos();
+static int prntstr();
+
+extern int print_pe();
+extern modtyp  _ZBIT_1;
+extern char    *bitstr2strb();
+extern PE mkpelist(), mkpe();
+extern OID     mkoid();
+extern struct type_UNIV_EXTERNAL *mkext();
+
+extern struct rep_elem *mkrep_elem();
+extern struct rep_int  *mkrep_int();
+
+extern void    exit();
+
+static int     t_test = 1;     /* Iteration of the test */
+
+#define NullParm       ((char  *) 0)
+/*ARGSUSED*/
+main(argc, argv)
+int    argc;
+char   **argv;
+{
+    int        i;
+    int succ, fail;
+
+    succ = fail = 0;
+    if (argc <= 1) {
+       for (i = MAXTCASE - 1; i >= 0; i--) {
+           if (t_case[i].tst_entry < 0)
+               continue;
+           for (t_test = t_case[i].tst_tests; t_test > 0; t_test--) {
+               if (ed_tst(i) != OK) {
+                   (void) printf("Failed\n");
+                   fail++;
+               } else
+                   succ++;
+           }
+       }
+       if (fail > 0)
+           (void) printf("Failed\n");
+       (void) printf("Total %d  = %d successes %d failures\n", fail + succ, succ, fail);
+#ifdef PEP_TEST
+       tailorfree();
+#endif
+    } else {
+       i = atoi(argv[1]);
+       if (argc > 2)
+           t_test = atoi(argv[2]);
+       (void) printf("Test %d\n", i);
+       if (ed_tst(i) != OK)
+           (void) printf("Failed\n");
+#ifdef PEP_TEST
+       tailorfree();
+#endif
+    }
+    return (fail);
+
+}
+
+/*
+ * Perform a test of encoding/decoding on type number tynum
+ */
+ed_tst(tynum)
+int    tynum;
+{
+    PE pe;
+    char *parm1, *parm2;
+
+    if (tynum < 0 || tynum >= MAXTCASE)
+           ferrd(1, "ed_tst illegal type %d\n", tynum);
+    
+
+    if ((parm1 = fill(tynum)) == NULL) {
+       ferr(1, "calloc did not work\n");
+    }
+
+#define encode(tynum, x, parm) \
+       enc_f(t_case[tynum].tst_entry, &_ZT1_mod, (x), 1, 0, NULLCP, (parm))
+
+    if (encode(tynum, &pe, parm1) == NOTOK) {
+       (void) printf("encode:failed on %s: %s\n", t_case[tynum].tst_name,
+            PY_pepy);
+       return(NOTOK);
+    }
+       
+
+#define decode(tynum, x, parm) \
+       dec_f(t_case[tynum].tst_entry, &_ZT1_mod, (x), 1, (int *) 0, (char **)NULL, (parm))
+
+    if (decode(tynum, pe, &parm2) == NOTOK) {
+           (void) printf("decode:failed on %s: %s\n", t_case[tynum].tst_name,
+                PY_pepy);
+           return (NOTOK);
+    }
+       
+    if (tcmp(tynum, parm1, parm2)) {
+       (void) printf("%s: not transfered properly\n", t_case[tynum].tst_name);
+       return (NOTOK);
+    }
+
+#if PRNT
+#define print(tynum, x)        \
+    prnt_f(t_case[tynum].tst_entry, &_ZT1_mod, (x), 1, (int *) 0, (char **)0)
+
+    (void) printf("\n\"%s\" t_test = %d\n", t_case[tynum].tst_name, t_test);
+    if (print(tynum, pe) == NOTOK) {
+           (void) printf("Print:failed on %s: %s\n", t_case[tynum].tst_name,
+                PY_pepy);
+           exit(2);
+    }
+#endif
+       
+
+
+#define fre_space(tynum, parm) \
+       fre_obj(parm, _ZT1_mod.md_dtab[t_case[tynum].tst_entry], &_ZT1_mod, 1)
+
+    if (fre_space(tynum, parm1) != OK)
+       return (NOTOK);
+    if (fre_space(tynum, parm2) != OK)
+       return (NOTOK);
+
+    if (pe)
+       pe_free(pe);
+
+    return (OK);
+}
+
+    /*SUPPRESS 218*/
+/*
+ * fill in some test data for the given type
+ */
+char   *
+fill(tynum)
+int    tynum;
+{
+    char       *parm;
+    static int count;
+    int                i;
+    char       *p;
+
+    if ((parm = calloc(1, t_case[tynum].tst_size)) == NULL) {
+       ferr(1, "calloc did not work\n");
+    }
+
+    switch (tynum) {
+    case TY_MPDU:
+#define Xparm ((struct type_T1_MPDU *)parm)
+       if ((Xparm->a__seq = new(struct element_T1_1)) == NULL) {
+               (void) printf("calloc did not work\n");
+               return NULL;
+       }
+       Xparm->a__seq->fred = 10;
+       Xparm->a__seq->george = 1;
+       break;
+#undef Xparm
+    
+    case TY_EMBEDDED:
+#define Xparm ((struct type_T1_Embedded *)parm)
+       Xparm->anMPDU = (struct type_T1_MPDU *)fill(TY_MPDU);
+       Xparm->ei = 6966;
+       break;
+#undef Xparm
+
+    case TY_STRINGS:
+#define Xparm  ((struct type_T1_Strings *)parm)
+       Xparm->ostring = str2qb("12\376\0\377a6", 7, 1);
+       Xparm->bstring = strb2bitstr("\270\017\010\020\040\100", 50, 0, 0);
+       Xparm->nstring = str2qb("123456", 6, 1);
+       Xparm->pstring = str2qb("hello, world", 12, 1);
+       Xparm->tstring = str2qb("teletex", 7, 1);
+       Xparm->t61string = str2qb("T.61", 4, 1);
+       Xparm->vstring = str2qb("visible", 7, 1);
+       Xparm->vis__string = str2qb("visible again", 13, 1);
+       Xparm->i646string = str2qb("who knows what this is", 22, 1);
+       Xparm->ia5string = str2qb("This is ASCII\n\r", 15, 1);
+       Xparm->graphstring = str2qb("This is a graphic string", 24, 1);
+       Xparm->genstring = str2qb("This is a general string", 24, 1);
+       break;
+#undef Xparm
+
+    case TY_EMB_STRINGS:
+#define Xparm  ((struct type_T1_Emb__Strings *)parm)
+       Xparm->atest = 2001;
+       Xparm->ctest = strb2bitstr("\03\010\252\125", 24, 0, 0);
+       Xparm->btest = str2qb("Good bye", 8, 1);
+       Xparm->big__test = (struct type_T1_Strings *)fill(TY_STRINGS);
+       if ((Xparm->emb__test = new(struct element_T1_0)) == NULL) {
+               (void) printf("calloc did not work\n");
+               return NULL;
+       }
+       Xparm->emb__test->em__int = -101;
+       Xparm->emb__test->em__oct = str2qb("Embedded octet string", 21, 1);
+       Xparm->emb__test->em__bit = strb2bitstr("\377\252\125\370\01", 40, 0,0);
+       break;
+#undef Xparm
+
+    case TY_IMPLICIT:
+#define Xparm  ((struct type_T1_Impl__Tags *)parm)
+       Xparm->i__impl = -1;
+       Xparm->o__impl = str2qb("I'm an implicit tagged octet string", 36, 1);
+       Xparm->b__impl = strb2bitstr("\0\0\01\230\01", 40, 0, 0);
+       Xparm->f__impl = 0xff; /* True */
+       Xparm->obj__impl = (struct type_T1_Emb__Strings *)fill(TY_EMB_STRINGS);
+       if ((Xparm->i__emb__test = new(struct element_T1_2)) == NULL) {
+               (void) printf("calloc did not work\n");
+               return NULL;
+       }
+       Xparm->i__emb__test->i__em__int = -101;
+       Xparm->i__emb__test->i__em__oct = str2qb("Implicit Embedded", 18, 1);
+       Xparm->i__emb__test->i__em__bit = strb2bitstr("\200\200\200\200", 32, 0, 0);
+#undef Xparm
+       break;
+
+    case TY_EXPLICIT:
+#define Xparm  ((struct type_T1_Expl__Tags *)parm)
+       Xparm->i__expl = 35051;
+       Xparm->o__expl = str2qb("explicit tagged octet string", 28, 1);
+       Xparm->b__expl = strb2bitstr("\070\070\070\077", 32, 0, 0);
+       Xparm->f__expl = 0xf0; /* True */
+       Xparm->obj__expl = (struct type_T1_Emb__Strings *)fill(TY_EMB_STRINGS);
+       if ((Xparm->i__exp__test = new(struct element_T1_3)) == NULL) {
+               (void) printf("calloc did not work\n");
+               return NULL;
+       }
+       Xparm->i__exp__test->i__ex__int = -9;
+       Xparm->i__exp__test->i__ex__oct = str2qb("Explicit Embedded", 18, 1);
+       Xparm->i__exp__test->i__ex__bit = strb2bitstr("\03\03\03\03\277", 40, 0, 0);
+#undef Xparm
+       break;
+       
+    case TY_SEQOF:
+#define Xparm  ((struct type_T1_Seqof__Test *)parm)
+    count = 2;
+    Xparm->sqof__test1 = (struct element_T1_4 *) fill(TY_ELEMENT4);
+    count = 2;
+    Xparm->stof__test1 = (struct member_T1_2 *) fill(TY_MEMBER2);
+    Xparm->i__test1 = 33;
+    count = 2;
+    Xparm->sqof__test2 = (struct element_T1_6 *) fill(TY_ELEMENT6);
+    count = 2;
+    Xparm->stof__test2 = (struct member_T1_4 *) fill(TY_MEMBER4);
+    Xparm->i__test2 = 99;
+    break;
+#undef Xparm
+       
+    case TY_ELEMENT4:
+#define Xparm  ((struct element_T1_4 *)parm)
+    Xparm->element_T1_5 = (struct type_T1_Expl__Tags *)fill(TY_EXPLICIT);
+    if (count-- > 0)
+       Xparm->next = (struct element_T1_4 *) fill(TY_ELEMENT4);
+    else
+       Xparm->next = NULL;
+    break;
+#undef Xparm
+       
+    case TY_MEMBER2:
+#define Xparm  ((struct member_T1_2 *)parm)
+    Xparm->member_T1_3 = (struct type_T1_Expl__Tags *)fill(TY_EXPLICIT);
+    if (count-- > 0)
+       Xparm->next = (struct member_T1_2 *) fill(TY_MEMBER2);
+    else
+       Xparm->next = NULL;
+    break;
+#undef Xparm
+
+    case TY_ELEMENT6:
+#define Xparm  ((struct element_T1_6 *)parm)
+    Xparm->element_T1_7 = (struct element_T1_8 *)fill(TY_ELEMENT8);
+    if (count-- > 0)
+       Xparm->next = (struct element_T1_6 *) fill(TY_ELEMENT6);
+    else
+       Xparm->next = NULL;
+    break;
+#undef Xparm
+
+    case TY_ELEMENT8:
+#define Xparm  ((struct element_T1_8 *)parm)
+    Xparm->sqof__in = (struct type_T1_Expl__Tags *)fill(TY_EXPLICIT);
+    Xparm->sqof__i = 212121;
+    Xparm->sqof__o = str2qb("Element8 Embedded", 18, 1);
+    break;
+#undef Xparm
+
+    case TY_MEMBER4:
+#define Xparm  ((struct member_T1_4 *)parm)
+    Xparm->member_T1_5 = (struct element_T1_9 *)fill(TY_ELEMENT9);
+    if (count-- > 0)
+       Xparm->next = (struct member_T1_4 *) fill(TY_MEMBER4);
+    else
+       Xparm->next = NULL;
+    break;
+#undef Xparm
+
+    case TY_ELEMENT9:
+#define Xparm  ((struct element_T1_9 *)parm)
+       Xparm->stof__in = (struct type_T1_Expl__Tags *)fill(TY_EXPLICIT);
+       Xparm->stof__i = -12345;
+       Xparm->stof__o = str2qb("XYZabcde Embedded", 18, 1);
+    break;
+#undef Xparm
+
+    case TY_CHOICE:
+#define Xparm  ((struct type_T1_Choice__Test *)parm)
+       Xparm->c1 = (struct choice_T1_0 *) fill(TY_CHOICE0);
+       Xparm->c2 = (struct choice_T1_1 *) fill(TY_CHOICE1);
+       Xparm->c3 = (struct choice_T1_2 *) fill(TY_CHOICE2);
+       Xparm->c4 = (struct element_T1_11 *) fill(TY_ELEMENT11);
+       break;
+#undef Xparm
+
+    case TY_CHOICE0:
+#define Xparm  ((struct choice_T1_0 *)parm)
+       
+       switch (Xparm->offset = (t_test + 10)%choice_T1_0_obj__c1 + 1) {
+       case choice_T1_0_i__c1:
+           Xparm->un.i__c1 = 10101;
+           break;
+       
+       case choice_T1_0_o__c1:
+           Xparm->un.o__c1 = str2qb("Andrew Worsley!!!", 18, 1);
+           break;
+       
+       case choice_T1_0_b__c1:
+           Xparm->un.b__c1 = strb2bitstr("\02\02\02\07\077", 40, 0, 0);
+           break;
+       
+       case choice_T1_0_f__c1:
+           Xparm->un.f__c1 = 0x11;
+           break;
+       
+       case choice_T1_0_obj__c1:
+           Xparm->un.obj__c1 = (struct type_T1_Emb__Strings *) fill(TY_EMB_STRINGS);
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE0:illegal offset %d\n", Xparm->offset);
+       }
+       break;
+#undef Xparm
+
+    case TY_CHOICE1:
+#define Xparm  ((struct choice_T1_1 *)parm)
+       
+       switch (Xparm->offset = (t_test + 11)%choice_T1_1_obj__c2 + 1) {
+       case choice_T1_1_i__c2:
+           Xparm->un.i__c2 = 1212;
+           break;
+       
+       case choice_T1_1_o__c2:
+           Xparm->un.o__c2 = str2qb("Richard Worsley!!", 18, 1);
+           break;
+       
+       case choice_T1_1_b__c2:
+           Xparm->un.b__c2 = strb2bitstr("\02\01\01\07\077", 40, 0, 0);
+           break;
+       
+       case choice_T1_1_f__c2:
+           Xparm->un.f__c2 = 0x12;
+           break;
+       
+       case choice_T1_1_obj__c2:
+           Xparm->un.obj__c2 = (struct type_T1_Emb__Strings *) fill(TY_EMB_STRINGS);
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE1:illegal offset %d\n", Xparm->offset);
+       }
+       break;
+#undef Xparm
+
+    case TY_CHOICE2:
+#define Xparm  ((struct choice_T1_2 *)parm)
+       
+       switch (Xparm->offset = (t_test + 12)%choice_T1_2_i__c3 + 1) {
+       case choice_T1_2_i__c3:
+           Xparm->un.i__c3 = 689364;
+           break;
+       
+       case choice_T1_2_seq__c3:
+           Xparm->un.seq__c3 = (struct element_T1_10 *) fill(TY_ELEMENT10);
+           break;
+       
+       case choice_T1_2_set__c3:
+           Xparm->un.set__c3 = (struct member_T1_6 *) fill(TY_MEMBER6);
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE2:illegal offset %d\n", Xparm->offset);
+       }
+       break;
+#undef Xparm
+
+    case TY_CHOICE3:
+#define Xparm  ((struct choice_T1_3 *)parm)
+       
+       switch (Xparm->offset = (t_test + 13)%choice_T1_3_sc__b__i + 1) {
+       case choice_T1_3_sc__a__i:
+           Xparm->un.sc__a__i = 16891;
+           break;
+       
+       case choice_T1_3_sc__b__i:
+           Xparm->un.sc__b__i = 13151;
+           break;
+       
+       case choice_T1_3_c4__i:
+           Xparm->un.c4__i = 10938;
+           break;
+       
+       case choice_T1_3_c4__obj:
+           Xparm->un.c4__obj = (struct type_T1_Expl__Tags *) fill(TY_EXPLICIT);
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE3:illegal offset %d\n", Xparm->offset);
+       }
+       break;
+#undef Xparm
+
+    case TY_ELEMENT10:
+#define Xparm  ((struct element_T1_10 *)parm)
+       Xparm->seq__c3__in = (struct type_T1_Expl__Tags *) fill(TY_EXPLICIT);
+       Xparm->seq__c3__i = 40938;
+       Xparm->seq__c3__o = str2qb("James Worsley!!!!", 18, 1);
+       break;
+#undef Xparm
+
+    case TY_MEMBER6:
+#define Xparm  ((struct member_T1_6 *)parm)
+       Xparm->set__c3__in = (struct type_T1_Expl__Tags *) fill(TY_EXPLICIT);
+       Xparm->set__c3__i = 0x40938;
+       Xparm->set__c3__o = str2qb("Patrick Worsley!!", 18, 1);
+       break;
+#undef Xparm
+
+    case TY_ELEMENT11:
+#define Xparm  ((struct element_T1_11 *)parm)
+       Xparm->c4__choice = (struct choice_T1_3 *) fill(TY_CHOICE3);
+       break;
+#undef Xparm
+
+    case TY_OPTIONAL:
+#define Xparm  ((struct type_T1_Opt__Strings *)parm)
+        if (t_test & opt_T1_Opt__Strings_a__opt) {
+           Xparm->optionals |= opt_T1_Opt__Strings_a__opt;
+           Xparm->a__opt = 192837;
+       }
+        if (t_test & opt_T1_Opt__Strings_d__opt) {
+           Xparm->optionals |= opt_T1_Opt__Strings_d__opt;
+           Xparm->d__opt = 1;
+       }
+       Xparm->b__opt = str2qb("Susan Hannah Sibel", 19, 1);
+        if (t_test*(t_test + 1) & opt_T1_Opt__Strings_d__opt) {
+           Xparm->c__opt = strb2bitstr("\012\017\02\07\077", 40, 0, 0);
+       }
+        if (t_test & opt_T1_Opt__Strings_e__opt) {
+           Xparm->optionals |= opt_T1_Opt__Strings_e__opt;
+           Xparm->e__opt = 0;
+       }
+        if ((t_test + 12)*t_test & opt_T1_Opt__Strings_a__opt) {
+           Xparm->big__opt = (struct type_T1_Strings *) fill(TY_STRINGS);
+       }
+        if ((t_test + 2)*t_test & opt_T1_Opt__Strings_a__opt) {
+           Xparm->emb__opt = (struct element_T1_12 *) fill(TY_ELEMENT12);
+       }
+        if ((t_test + 4)*t_test & opt_T1_Opt__Strings_a__opt) {
+           Xparm->st__opt = (struct member_T1_7 *) fill(TY_MEMBER7);
+       }
+        if ((t_test + 8)*t_test & opt_T1_Opt__Strings_a__opt) {
+           Xparm->obj__opt = (struct type_T1_MPDU *) fill(TY_MPDU);
+       }
+        if (t_test & opt_T1_Opt__Strings_etag__opt) {
+           Xparm->optionals |= opt_T1_Opt__Strings_etag__opt;
+           Xparm->etag__opt = 2983461;
+       }
+        if ((t_test + 6)*t_test & opt_T1_Opt__Strings_a__opt) {
+           Xparm->ch__opt = (struct choice_T1_4 *) fill(TY_CHOICE4);
+       }
+       break;
+#undef Xparm
+
+     case TY_ELEMENT12:
+#define Xparm  ((struct element_T1_12 *)parm)
+        if ((t_test + 10)*t_test & opt_T1_element_T1_12_oem__int) {
+           Xparm->optionals |= opt_T1_element_T1_12_oem__int;
+           Xparm->oem__int = 197336;
+       }
+        if (t_test*(t_test + 22) & opt_T1_Opt__Strings_a__opt) {
+           Xparm->oem__oct = str2qb("Ling Worsley", 13, 1);
+       }
+        if (t_test*(t_test + 16) & opt_T1_Opt__Strings_d__opt) {
+           Xparm->oem__bit = strb2bitstr("\0142\0117\02\017\07", 40, 0, 0);
+       }
+        break;
+#undef Xparm
+
+     case TY_MEMBER7:
+#define Xparm  ((struct member_T1_7 *)parm)
+        if ((t_test + 12)*t_test & opt_T1_member_T1_7_st__int0) {
+           Xparm->optionals |= opt_T1_member_T1_7_st__int0;
+           Xparm->st__int0 = 85659;
+       }
+        if ((t_test + 12)*t_test & opt_T1_member_T1_7_st__int1) {
+           Xparm->optionals |= opt_T1_member_T1_7_st__int1;
+           Xparm->st__int1 = 664388;
+       }
+        if ((t_test + 12)*t_test & opt_T1_member_T1_7_st__int2) {
+           Xparm->optionals |= opt_T1_member_T1_7_st__int2;
+           Xparm->st__int2 = 967768;
+       }
+        break;
+#undef Xparm
+
+    case TY_CHOICE4:
+#define Xparm  ((struct choice_T1_4 *)parm)
+       
+       switch (Xparm->offset = (t_test + 14)%choice_T1_4_ch__2 + 1) {
+       case choice_T1_4_ch__1:
+           Xparm->un.ch__1 = 74576;
+           break;
+       
+       case choice_T1_4_ch__2:
+           Xparm->un.ch__2 = 28828;
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE4:illegal offset %d\n", Xparm->offset);
+       }
+       break;
+#undef Xparm
+
+     case TY_EXTREF:
+#define Xparm  ((struct type_T1_E__ref *)parm)
+       Xparm->a__ref = (struct type_T2_Info *) fill(TY_T2_INFO);
+       Xparm->b__ref = (struct type_T2_Info *) fill(TY_T2_INFO);
+       Xparm->c__ref = (struct type_T1_Choice__Test *) fill(TY_CHOICE);
+        if ((t_test + 20)*t_test & 0x2) {
+           Xparm->d__ref = (struct type_T2_Info *) fill(TY_T2_INFO);
+       }
+        if ((t_test + 20)*t_test & 0x1) {
+           Xparm->e__ref = (struct type_T2_Info *) fill(TY_T2_INFO);
+       }
+        break;
+#undef Xparm
+
+     case TY_T2_INFO:
+#define Xparm  ((struct type_T2_Info *)parm)
+       Xparm->a1 = 101910;
+       Xparm->a2 = -304985;
+       Xparm->a3 = 13;
+       Xparm->a4 = (struct type_T2_MPDU *) fill(TY_T2_MPDU);
+        break;
+#undef Xparm
+
+     case TY_T2_MPDU:
+#define Xparm  ((struct type_T2_MPDU *)parm)
+       Xparm->a__seq = (struct element_T2_0 *) fill(TY_T2_ELEM0);
+        break;
+#undef Xparm
+
+     case TY_T2_ELEM0:
+#define Xparm  ((struct element_T2_0 *)parm)
+       Xparm->fred = 998877;
+        break;
+#undef Xparm
+
+     case TY_OPTIMISED:
+#define Xparm  ((struct type_T1_Optimised *)parm)
+       Xparm->o1 = strb2bitstr("\0241\0227\032\011\0237", 40, 0, 0);
+       Xparm->o2 = str2qb("Peckling Worsley!!!!", 20, 1);
+       Xparm->o3 = (struct type_T1_MPDU *) fill(TY_MPDU);
+       Xparm->o4 = (PE ) mkpelist(t_test);
+       Xparm->element_T1_14  = (struct member_T1_9 *) fill(TY_MEMBER9);
+       break;
+#undef Xparm
+
+     case TY_MEMBER9:
+#define Xparm  ((struct member_T1_9 *)parm)
+       Xparm->o5 = mkpelist(t_test);
+       Xparm->o6 = mkpelist(t_test);
+       Xparm->o7 = mkoid(t_test);
+       break;
+#undef Xparm
+
+    case TY_EXTERNAL:
+#define Xparm  ((struct type_T1_Ext__typ *)parm)
+        Xparm->ext = mkext(t_test*8 + 1);
+        Xparm->a__ny = mkpe(t_test*8 + 1);
+        Xparm->ext__impl = mkext(t_test*6 + 1);
+        Xparm->any__impl = mkpe(t_test*8 + 3);
+        Xparm->ext__expl = mkext(t_test*4 + 1);
+        Xparm->any__expl = mkpe(t_test*8 + 5);
+       break;
+#undef Xparm
+
+    case TY_SEXTERNAL:
+#define Xparm  ((struct type_T1_SExt *)parm)
+       free(parm);     /* don't need it */
+       Xparm = mkext(21);
+       break;
+#undef Xparm
+
+    case TY_ETAGOBJ:
+#define Xparm  ((struct type_T1_Etags *)parm)
+       switch (Xparm->offset = (t_test + 4)%type_T1_Etags_bE + 1) {
+       case type_T1_Etags_aE:
+           Xparm->un.aE = 10283;
+           break;
+       
+       case type_T1_Etags_bE:
+           Xparm->un.bE = 40986;
+           break;
+       
+       default:
+           ferrd(1, "TY_ETAGOBJ:illegal offset %d\n", Xparm->offset);
+       }
+       break;
+#undef Xparm
+
+/* This has to be changed when posy is upgraded to handle DEFAULTS properly */
+    case TY_DEFAULT:
+#define Xparm  ((struct type_T1_Def__Strings *)parm)
+       if (t_test*t_test & 2)
+           Xparm->a__def = int_T1_a__def_a__def__0;
+       else
+           Xparm->a__def = int_T1_a__def_a__def__1;
+       if (t_test*t_test & 4)
+           Xparm->b__def = str2qb("Susan Sibel !!!!", 17, 1);
+       else if (t_test*t_test & 8)
+           Xparm->b__def = str2qb("hello, world", 12, 1);
+       else
+           Xparm->b__def = NULLQB;
+       if (t_test*t_test & 8)
+           Xparm->c__def = strb2bitstr(int2strb(bit_T1_c__def_c__def__two, 9),
+               9, 0, 0);
+       else
+           Xparm->c__def = NULLPE;
+       if (t_test*t_test & 0x10)
+           Xparm->okay = 0;
+       else
+           Xparm->okay = 1;
+       if (t_test*t_test & 0x20)
+           Xparm->e__def = 0;
+       else
+           Xparm->e__def = 1;
+       Xparm->big__def = (struct type_T1_Strings *) fill(TY_STRINGS);
+       if (t_test*t_test*t_test & 0x10)
+           Xparm->emb__def = NULL;
+       else
+           Xparm->emb__def = (struct element_T1_13 *) fill(TY_ELEMENT13);
+       if (t_test*t_test*t_test & 0x20)
+           Xparm->st__def = NULL;
+       else
+           Xparm->st__def = (struct member_T1_8 *) fill(TY_MEMBER8);
+       break;
+#undef Xparm
+
+    case TY_ELEMENT13:
+#define Xparm ((struct element_T1_13 *)parm)
+       if (t_test*t_test*t_test & 1)
+           Xparm->colour = int_T1_colour_green;
+       else
+           Xparm->colour = int_T1_colour_red;
+       if (t_test*t_test & 040)
+           Xparm->oem__oct = str2qb("Julia Dzuikas !!!!", 19, 1);
+       else
+           Xparm->oem__oct = NULLQB;
+       if (t_test*t_test*t_test & 2)
+           Xparm->version = strb2bitstr(int2strb((1 << bit_T1_version_basic)
+                                            |(1 << bit_T1_version_patch1), 3),
+                                            3, 0, 0);
+       else
+           Xparm->version = strb2bitstr(int2strb((1 << bit_T1_version_basic),
+                                                   3), 3, 0, 0);
+       break;
+#undef Xparm
+
+    case TY_MEMBER8:
+#define Xparm ((struct member_T1_8 *)parm)
+       if (t_test*t_test*t_test & 4)
+           Xparm->wine = int_T1_wine_burgundy;
+       else
+           Xparm->wine = int_T1_wine_claret;
+       if (t_test*t_test*t_test & 010)
+           Xparm->beer = int_T1_beer_vb;
+       else
+           Xparm->beer = int_T1_beer_hieneken;
+       if (t_test*t_test*t_test & 020)
+           Xparm->spirit = int_T1_spirit_vodka;
+       else
+           Xparm->spirit = int_T1_spirit_brandy;
+       break;
+#undef Xparm
+
+    case TY_STEST:
+#define Xparm ((struct type_T1_Stest *)parm)
+       if (t_test*(t_test + 2)*t_test & 4)
+           Xparm->st1 = (struct type_T1_Sint *)fill(TY_SINT);
+       else
+           Xparm->st1 = (struct type_T1_Sint *)NULL;
+       if (t_test*(t_test + 2)*t_test & 010)
+           Xparm->st2 = str2qb("goodbye, world", 14, 1);
+       else
+           Xparm->st2 = str2qb("xxxxxxx, world", 14, 1);
+       break;
+#undef Xparm
+
+    case TY_SINT:
+#define Xparm ((struct type_T1_Sint *)parm)
+       if (t_test*(t_test + 4)*t_test & 4)
+           Xparm->parm = 33;
+       else
+           Xparm->parm = 44;
+       break;
+#undef Xparm
+
+    case TY_ETYPE:
+#define Xparm ((struct type_T1_Enum__type *)parm)
+       switch (t_test & 3) {
+       case 0:
+           Xparm->parm = int_T1_Enum__type_pork;
+           break;
+
+       case 1:
+           Xparm->parm = int_T1_Enum__type_beef;
+           break;
+
+
+       case 2:
+           Xparm->parm = int_T1_Enum__type_chicken;
+           break;
+
+
+       case 3:
+           Xparm->parm = int_T1_Enum__type_lamb;
+           break;
+
+       default:
+           ferrd(1, "fill:ETYPE: Self consistency failure\n", t_test);
+       }
+       break;
+#undef Xparm
+
+    case TY_ENUM_TEST:
+#define Xparm ((struct type_T1_T__enum *)parm)
+       i = t_test;
+       Xparm->ae1 = (struct type_T1_Enum__type *)fill(TY_ETYPE);
+       t_test++;
+       Xparm->ae2 = (struct type_T1_Enum__type *)fill(TY_ETYPE);
+       t_test++;
+       Xparm->ae3 = (struct type_T1_Enum__type *)fill(TY_ETYPE);
+       t_test++;
+       if (t_test & 1)
+           Xparm->ae5 = (struct type_T1_Enum__type *)fill(TY_ETYPE);
+       Xparm->ae4 = (struct type_T1_Enum__type *)fill(TY_ETYPE);
+       t_test++;
+       if (t_test & 2)
+           Xparm->ae4->parm = int_T1_Enum__type_chicken; /* Default */
+       t_test = i;
+       break;
+#undef Xparm
+
+#ifdef PEPSY_REALS
+    case TY_REAL:
+#define Xparm  ((struct type_T1_Real *)parm)
+       switch (t_test % 3) {
+       case 0:
+           Xparm->parm = -2.28789;
+           break;
+       
+       case 1:
+           Xparm->parm = 927639.98009;
+           break;
+
+       case 2:
+           Xparm->parm = 0.0;
+           break;
+
+       default:
+       ferrd(1, "fill:TY_REAL:Internal error %d\n", t_test);
+        }
+        break;
+#undef Xparm
+
+    case TY_REAL_TEST:
+#define Xparm  ((struct type_T1_T__real *)parm)
+       i = t_test;
+        Xparm->r1 = (struct type_T1_Real *) fill(TY_REAL);
+       t_test++;
+        Xparm->r2 = (struct type_T1_Real *) fill(TY_REAL);
+       t_test++;
+        Xparm->r3 = (struct type_T1_Real *) fill(TY_REAL);
+       t_test++;
+
+       Xparm->r4 = (struct type_T1_Real *) fill(TY_REAL);
+       t_test++;
+       if (i & 1)      /* Default */
+           Xparm->r4->parm = 3.1415962;
+
+       if (i & 2) {    /* Optional */
+           Xparm->r5 = (struct type_T1_Real *) fill(TY_REAL);
+       }
+       t_test = i;
+       break;
+#undef Xparm
+
+/* all strings have to be malloc'ed out ! */
+    case TY_OPTPEPY:
+    case TY_DEFPEPY:
+#define Xparm  ((struct pepy_refs1 *)parm)
+        Xparm->t_int = 12354 + t_test;
+        Xparm->t_int1 = 12354 + t_test;
+        Xparm->t_enum = t_test + 1;
+        Xparm->t_enum1 = t_test + 1;
+        Xparm->t_qbuf = str2qb("Some is out there!", 18, 1);
+        Xparm->t_qbuf1 = str2qb("Some is out there!", 18, 1);
+        Xparm->t_string = strdup("hello, world\n");
+        Xparm->t_string1 = strdup("hello, world\n");
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_ostring = p;
+        Xparm->t_olen = t_test + 4;
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_ostring1 = p;
+        Xparm->t_olen1 = t_test + 4;
+        Xparm->t_bool = t_test % 2;
+        Xparm->t_bool1 = t_test % 2;
+        Xparm->t_real = sqrt(t_test * 3.1415962);
+        Xparm->t_real1 = sqrt(t_test * 3.1415962);
+        Xparm->t_oid = mkoid(t_test);
+       if (tynum != TY_OPTPEPY)
+           Xparm->t_oid1 = mkoid(t_test);
+       Xparm->t_pe = strb2bitstr("\0221\0327\052\211\0237\200", 41, 0, 0);
+       Xparm->t_pe1 = strb2bitstr("\0221\0327\052\211\0237\200", 41, 0, 0);
+        Xparm->t_any = mkpe(t_test*8 + 3);
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_bstring = p;
+        Xparm->t_blen = t_test*8 + 8;
+       break;
+#undef Xparm
+
+    case TY_PEPY:
+#define Xparm  ((struct pepy_refs *)parm)
+        Xparm->t_int = 12354 + t_test;
+        Xparm->t_enum = t_test + 1;
+        Xparm->t_qbuf = str2qb("Some is out there!", 18, 1);
+        Xparm->t_string = strdup("hello, world\n");
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_ostring = p;
+        Xparm->t_olen = t_test + 4;
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_bstring = p;
+        Xparm->t_blen = t_test*8 + 4;
+        Xparm->t_bool = t_test % 2;
+        Xparm->t_real = sqrt(t_test * 3.1415962);
+        Xparm->t_oid = mkoid(t_test);
+       Xparm->t_pe = strb2bitstr("\0221\0327\052\011\0237\200", 41, 0, 0);
+        Xparm->t_any = mkpe(t_test*8 + 3);
+        Xparm->t_def = (struct pepy_refs1 *)fill(TY_DEFPEPY);
+        Xparm->t_opt = (struct pepy_refs1 *)fill(TY_OPTPEPY);
+       for (i = NUMOPT - 1; i >= 0; i--)
+            if ((t_test + i) % 2 == 1)
+                BITSET(Xparm->t_opt->opt_set, i);
+            else
+                BITCLR(Xparm->t_opt->opt_set, i);
+       break;
+#undef Xparm
+
+    case TY_S_COMPD:
+#define Xparm  ((struct pepy_refs1 *)parm)
+        Xparm->t_int = 12354 + t_test;
+        Xparm->t_enum = t_test + 1;
+        Xparm->t_int1 = 12354 + t_test;
+        Xparm->t_enum1 = t_test + 1;
+       for (i = NUMOPT - 1; i >= 0; i--) {
+           if (i != OPT_INT1 && i != OPT_INT2
+           && i != OPT_ENUM1 && i != OPT_ENUM2)
+               continue;
+
+            if ((t_test + i) % 2 == 1)
+                BITSET(Xparm->opt_set, i);
+            else
+                BITCLR(Xparm->opt_set, i);
+       }
+       break;
+#undef Xparm
+
+#endif
+
+    case TY_ACTION:
+    case TY_REPEAT:
+#define Xparm  ((struct repeats *)parm)
+       Xparm->rp_sq1 = mkrep_int(t_test - 1);
+       Xparm->rp_sq2 = mkrep_elem(t_test - 1);
+       Xparm->rp_st1 = mkrep_int(t_test - 1);
+       Xparm->rp_st2 = mkrep_elem(2*t_test - 1);
+       switch (t_test % 3) {
+       case 0:
+           Xparm->rp_choice = RP_INT;
+           Xparm->rp_int = t_test*t_test - 10;
+           break;
+
+       case 1:
+           Xparm->rp_choice = RP_BOOL;
+           Xparm->rp_bool = (t_test + 1) % 2;
+           break;
+
+       case 2:
+           Xparm->rp_choice = RP_OSTRING;
+           Xparm->rp_ostring = strdup("lets go home");
+           Xparm->rp_int = strlen(Xparm->rp_ostring);
+           break;
+
+       default:
+           ferrd(1, "fill:TY_REPEAT:Internal error %d\n", t_test);
+       }
+       break;
+#undef Xparm
+
+    case TY_VPDEFINED:
+#define Xparm  ((struct pepy_refs *)parm)
+        Xparm->t_int = 9354 + t_test;
+        Xparm->t_enum = t_test + 1;
+        Xparm->t_qbuf = str2qb("Some one is out there!", 22, 1);
+        Xparm->t_string = strdup("hello there, world\n");
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_ostring = p;
+        Xparm->t_olen = t_test + 4;
+       p = malloc(30);
+       bcopy("\0001234567890", p, 30);
+        Xparm->t_bstring = p;
+        Xparm->t_blen = t_test*8 + 4;
+       Xparm->t_pe = strb2bitstr("\0221\0327\052\211\0237\200", t_test + 33, 0, 0);
+        Xparm->t_bool = t_test % 2;
+        Xparm->t_real = sqrt((float )t_test);
+        Xparm->t_oid = mkoid(t_test);
+        Xparm->t_any = mkpe(t_test*7 + 3);
+       break;
+#undef Xparm
+
+    case TY_FUNC:
+#define Xparm  ((struct codedata *)parm)
+        Xparm->cd_a = mkpe(t_test + 2);
+        Xparm->cd_b = mkpe(t_test + 3);
+        Xparm->cd_c = mkpe(t_test + 5);
+        Xparm->cd_d = mkpe(t_test + 7);
+        Xparm->cd_int = t_test - 1;
+       if (t_test % 2)
+           Xparm->cd_string = strdup("hello there, world\n");
+       else
+           Xparm->cd_string = strdup("hello world\n");
+       for (i = NCD_OPT - 1; i >= 0; i--) {
+            if ((t_test + i) % 2 == 1)
+                BITSET(Xparm->cd_opt_set, i);
+            else
+                BITCLR(Xparm->cd_opt_set, i);
+       }
+       Xparm->cd_left = (struct codedata *)fill(TY_OPTFUNC);
+       Xparm->cd_right = (struct codedata *)fill(TY_DFTFUNC);
+       break;
+#undef Xparm
+
+    case TY_OPTFUNC:
+#define Xparm  ((struct codedata *)parm)
+       if ((t_test + 2) % 3)
+           Xparm->cd_a = mkpe(t_test + 2);
+       if ((t_test + 1) % 3)
+           Xparm->cd_b = mkpe(t_test + 3);
+       Xparm->cd_c = mkpe(t_test + 5);
+       Xparm->cd_d = mkpe(t_test + 7);
+        Xparm->cd_int = t_test - 1;
+       if (t_test % 2)
+           Xparm->cd_string = strdup("hello there, world\n");
+       else
+           Xparm->cd_string = NULLCP;
+       for (i = NCD_OPT - 1; i >= 0; i--) {
+            if ((t_test + i) % 2 == 1)
+                BITSET(Xparm->cd_opt_set, i);
+            else
+                BITCLR(Xparm->cd_opt_set, i);
+       }
+       break;
+#undef Xparm
+
+    case TY_DFTFUNC:
+#define Xparm  ((struct codedata *)parm)
+       if ((t_test + 2) % 3)
+           Xparm->cd_a = mkpe(t_test*2 + 1);
+       if ((t_test + 1) % 3)
+           Xparm->cd_b = mkpe(t_test*2 + 2);
+        Xparm->cd_c = mkpe(t_test*2 + 3);
+        Xparm->cd_d = mkpe(t_test*2 + 4);
+        Xparm->cd_int = t_test - 2;
+       if (t_test % 2)
+           Xparm->cd_string = strdup("hello there, world\n");
+       else
+           Xparm->cd_string = strdup("Some is out");
+       for (i = NCD_OPT - 1; i >= 0; i--) {
+            if ((t_test + i) % 2 == 1)
+                BITSET(Xparm->cd_opt_set, i);
+            else
+                BITCLR(Xparm->cd_opt_set, i);
+       }
+       break;
+#undef Xparm
+
+#ifdef PEPSY_REALS
+    case TY_ASIMPLE:
+#define Xparm  ((struct codedata *)parm)
+        Xparm->cd_a = mkpe(t_test + 2);
+        Xparm->cd_int = 2*t_test - 1;
+        Xparm->cd_int1 = 2*t_test - 1;
+        Xparm->cd_int2 = 2*t_test - 1;
+       if (t_test % 2)
+           Xparm->cd_string = strdup("hello there, world\n");
+       else
+           Xparm->cd_string = strdup("hello world\n");
+       Xparm->cd_string1 = strdup("hello world\n");
+       Xparm->cd_string2 = strdup("hello world\n");
+       Xparm->cd_bool = t_test % 2;
+       Xparm->cd_real = t_test * 3.1415962;
+       Xparm->cd_oid = mkoid(t_test*2);
+       Xparm->cd_oid1 = mkoid(t_test*2);
+       Xparm->cd_oid2 = mkoid(t_test*2);
+       Xparm->cd_bit = strb2bitstr("\0221\0327\052\211\0237\200", t_test + 30,
+                                   0, 0);
+       Xparm->cd_right = (struct codedata *)fill(TY_DFTFUNC);
+       break;
+#undef Xparm
+#endif
+
+    default:
+       ferrd(1, "fill:unknown type %d\n", tynum);
+    }
+
+    return (parm);
+}
+
+/*
+ * compare two structures for differences of fields indicating an
+ * error
+ */
+tcmp(tynum, parm1, parm2)
+int    tynum;
+char   *parm1, *parm2;
+{
+    int        d;
+    int        i;
+
+    d = 0;
+
+    switch (tynum) {
+    case TY_MPDU:
+#define Xparm1 ((struct type_T1_MPDU *)parm1)
+#define Xparm2 ((struct type_T1_MPDU *)parm2)
+       if (Xparm1->a__seq && !Xparm2->a__seq
+         || !Xparm1->a__seq && Xparm2->a__seq) {
+           (void) printf("a__seq missing/present\n");
+           d++;
+       }
+       if (Xparm1->a__seq && Xparm2->a__seq) {
+           if (Xparm1->a__seq->fred != Xparm2->a__seq->fred) {
+               (void) printf("%s->a__seq->fred %d != %d\n",  
+                   Xparm1->a__seq->fred, Xparm2->a__seq->fred);
+               d++;
+           }
+           if (Xparm1->a__seq->george != Xparm2->a__seq->george) {
+               (void) printf("%s a__seq->george %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->a__seq->george, Xparm2->a__seq->george);
+               d++;
+           }
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_EMBEDDED:
+#define Xparm1 ((struct type_T1_Embedded *)parm1)
+#define Xparm2 ((struct type_T1_Embedded *)parm2)
+       if (Xparm1->anMPDU && !Xparm2->anMPDU ||!Xparm1->anMPDU && Xparm2->anMPDU) {
+           (void) printf("anMPDU missing/present\n");
+           d++;
+       }
+       if (Xparm1->anMPDU && Xparm2->anMPDU) {
+               d += tcmp(TY_MPDU, (char *)Xparm1->anMPDU, (char *)Xparm2->anMPDU);
+       }
+       if (Xparm1->ei != Xparm2->ei) {
+           (void) printf("%s ei %d != %d\n",  
+               t_case[tynum].tst_name, Xparm1->ei, Xparm2->ei);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_STRINGS:
+#define Xparm1 ((struct type_T1_Strings *)parm1)
+#define Xparm2 ((struct type_T1_Strings *)parm2)
+       if (qb_cmp(Xparm1->ostring, Xparm2->ostring)) {
+               (void) printf("ostring octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->bstring, Xparm2->bstring)) {
+           (void) printf("bstring bitstring different\n");
+           d++;
+       }
+       if (qb_cmp(Xparm1->nstring, Xparm2->nstring)) {
+               (void) printf("nstring octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->pstring, Xparm2->pstring)) {
+               (void) printf("pstring octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->tstring, Xparm2->tstring)) {
+               (void) printf("tstring octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->t61string, Xparm2->t61string)) {
+               (void) printf("t61string octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->vstring, Xparm2->vstring)) {
+               (void) printf("vstring octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->vis__string, Xparm2->vis__string)) {
+               (void) printf("vis__string octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->i646string, Xparm2->i646string)) {
+               (void) printf("i646string octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->ia5string, Xparm2->ia5string)) {
+               (void) printf("ia5string octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->graphstring, Xparm2->graphstring)) {
+               (void) printf("graphstring octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->genstring, Xparm2->genstring)) {
+               (void) printf("genstring octet string different\n");
+               d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_EMB_STRINGS:
+#define Xparm1 ((struct type_T1_Emb__Strings *)parm1)
+#define Xparm2 ((struct type_T1_Emb__Strings *)parm2)
+       if (qb_cmp(Xparm1->btest, Xparm2->btest)) {
+               (void) printf("btest octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->ctest, Xparm2->ctest)) {
+           (void) printf("ctest bitstring different\n");
+           d++;
+       }
+       if (Xparm1->atest != Xparm2->atest) {
+               (void) printf("atest integers different\n");
+               d++;
+       }
+       if (Xparm1->big__test && Xparm2->big__test) {
+               d += tcmp(TY_STRINGS, (char *)Xparm1->big__test, (char *)Xparm2->big__test);
+       } else if (Xparm1->big__test || Xparm2->big__test) {
+               (void) printf("big__test one Strings missing!\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->emb__test->em__oct, Xparm2->emb__test->em__oct)) {
+               (void) printf("emb__test->em__oct octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->emb__test->em__bit, Xparm2->emb__test->em__bit)) {
+           (void) printf("emb__test->em__bit bitstring different\n");
+           d++;
+       }
+       if (Xparm1->emb__test->em__int != Xparm2->emb__test->em__int) {
+               (void) printf("emb__test->em__int integers different\n");
+               d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_IMPLICIT:
+#define Xparm1 ((struct type_T1_Impl__Tags *)parm1)
+#define Xparm2 ((struct type_T1_Impl__Tags *)parm2)
+       if (qb_cmp(Xparm1->o__impl, Xparm2->o__impl)) {
+               (void) printf("o__impl octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->b__impl, Xparm2->b__impl)) {
+           (void) printf("b__impl bitstring different\n");
+           d++;
+       }
+       if (Xparm1->i__impl != Xparm2->i__impl) {
+               (void) printf("i__impl integers different\n");
+               d++;
+       }
+       if (Xparm1->obj__impl && Xparm2->obj__impl) {
+               d += tcmp(TY_EMB_STRINGS, (char *)Xparm1->obj__impl, (char *)Xparm2->obj__impl);
+       } else if (Xparm1->obj__impl || Xparm2->obj__impl) {
+               (void) printf("obj__impl one Embedded Strings missing!\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->i__emb__test->i__em__oct, Xparm2->i__emb__test->i__em__oct)) {
+               (void) printf("i__emb__test->i__em__oct octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->i__emb__test->i__em__bit, Xparm2->i__emb__test->i__em__bit)) {
+           (void) printf("i__emb__test->i__em__bit bitstring different\n");
+           d++;
+       }
+       if (Xparm1->i__emb__test->i__em__int != Xparm2->i__emb__test->i__em__int) {
+               (void) printf("i__emb__test->i__em__int integers different\n");
+               d++;
+       }
+#undef Xparm1
+#undef Xparm2
+       break;
+       
+    case TY_EXPLICIT:
+#define Xparm1 ((struct type_T1_Expl__Tags *)parm1)
+#define Xparm2 ((struct type_T1_Expl__Tags *)parm2)
+       if (qb_cmp(Xparm1->o__expl, Xparm2->o__expl)) {
+               (void) printf("o__expl octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->b__expl, Xparm2->b__expl)) {
+           (void) printf("b__expl bitstring different\n");
+           d++;
+       }
+       if (Xparm1->i__expl != Xparm2->i__expl) {
+               (void) printf("i__expl integers different\n");
+               d++;
+       }
+       if (Xparm1->obj__expl && Xparm2->obj__expl) {
+               d += tcmp(TY_EMB_STRINGS, (char *)Xparm1->obj__expl, (char *)Xparm2->obj__expl);
+       } else if (Xparm1->obj__expl || Xparm2->obj__expl) {
+               (void) printf("obj__expl one Embedded Strings missing!\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->i__exp__test->i__ex__oct, Xparm2->i__exp__test->i__ex__oct)) {
+               (void) printf("i__exp__test->i__ex__oct octet string different\n");
+               d++;
+       }
+       if (bit_cmp(Xparm1->i__exp__test->i__ex__bit, Xparm2->i__exp__test->i__ex__bit)) {
+           (void) printf("i__exp__test->i__ex__bit bitstring different\n");
+           d++;
+       }
+       if (Xparm1->i__exp__test->i__ex__int != Xparm2->i__exp__test->i__ex__int) {
+               (void) printf("i__exp__test->i__ex__int integers different\n");
+               d++;
+       }
+#undef Xparm1
+#undef Xparm2
+       break;
+       
+
+    case TY_SEQOF:
+#define Xparm1 ((struct type_T1_Seqof__Test *)parm1)
+#define Xparm2 ((struct type_T1_Seqof__Test *)parm2)
+    if (Xparm1->sqof__test1 && Xparm2->sqof__test1) {
+       d += tcmp(TY_ELEMENT4, (char *)Xparm1->sqof__test1, (char *)Xparm2->sqof__test1);
+    } else if (Xparm1->sqof__test1 || Xparm2->sqof__test1) {
+       (void) printf("sqof__test1 one missing");
+       d++;
+    }
+    if (Xparm1->stof__test1 && Xparm2->stof__test1) {
+       d += tcmp(TY_MEMBER2, (char *)Xparm1->stof__test1, (char *)Xparm2->stof__test1);
+    } else if (Xparm1->stof__test1 || Xparm2->stof__test1) {
+       (void) printf("stof__test1 one missing");
+       d++;
+    }
+    if (Xparm1->i__test1 != Xparm2->i__test1) {
+       (void) printf("i__test1 integers different\n");
+       d++;
+    }
+    if (Xparm1->sqof__test2 && Xparm2->sqof__test2) {
+       d += tcmp(TY_ELEMENT6, (char *)Xparm1->sqof__test2, (char *)Xparm2->sqof__test2);
+    } else if (Xparm1->sqof__test2 || Xparm2->sqof__test2) {
+       (void) printf("sqof__test2 one missing");
+       d++;
+    }
+    if (Xparm1->stof__test2 && Xparm2->stof__test2) {
+       d += tcmp(TY_MEMBER4, (char *)Xparm1->stof__test2, (char *)Xparm2->stof__test2);
+    } else if (Xparm1->stof__test2 || Xparm2->stof__test2) {
+       (void) printf("stof__test2 one missing");
+       d++;
+    }
+    if (Xparm1->i__test2 != Xparm2->i__test2) {
+       (void) printf("i__test2 integers different\n");
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+       
+    case TY_ELEMENT4:
+#define Xparm1 ((struct element_T1_4 *)parm1)
+#define Xparm2 ((struct element_T1_4 *)parm2)
+    if (Xparm1->element_T1_5 && Xparm2->element_T1_5) {
+       d += tcmp(TY_EXPLICIT, (char *)Xparm1->element_T1_5, (char *)Xparm2->element_T1_5);
+    } else if (Xparm1->element_T1_5 || Xparm2->element_T1_5) {
+       (void) printf("element_T1_5 one missing");
+       d++;
+    }
+    if (Xparm1->next && Xparm2->next) {
+       d += tcmp(TY_ELEMENT4, (char *)Xparm1->next, (char *)Xparm2->next);
+    } else if (Xparm1->next || Xparm2->next) {
+       (void) printf("%s: next one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+       
+    case TY_MEMBER2:
+#define Xparm1 ((struct member_T1_2 *)parm1)
+#define Xparm2 ((struct member_T1_2 *)parm2)
+    if (Xparm1->member_T1_3 && Xparm2->member_T1_3) {
+       d += tcmp(TY_EXPLICIT, (char *)Xparm1->member_T1_3, (char *)Xparm2->member_T1_3);
+    } else if (Xparm1->member_T1_3 || Xparm2->member_T1_3) {
+       (void) printf("%s: member_T1_3 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->next && Xparm2->next) {
+       d += tcmp(TY_MEMBER2, (char *)Xparm1->next, (char *)Xparm2->next);
+    } else if (Xparm1->next || Xparm2->next) {
+       (void) printf("%s: next one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ELEMENT6:
+#define Xparm1 ((struct element_T1_6 *)parm1)
+#define Xparm2 ((struct element_T1_6 *)parm2)
+    if (Xparm1->element_T1_7 && Xparm2->element_T1_7) {
+       d += tcmp(TY_ELEMENT8, (char *)Xparm1->element_T1_7, (char *)Xparm2->element_T1_7);
+    } else if (Xparm1->element_T1_7 || Xparm2->element_T1_7) {
+       (void) printf("%s: element_T1_7 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->next && Xparm2->next) {
+       d += tcmp(TY_ELEMENT6, (char *)Xparm1->next, (char *)Xparm2->next);
+    } else if (Xparm1->next || Xparm2->next) {
+       (void) printf("%s: next one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ELEMENT8:
+#define Xparm1 ((struct element_T1_8 *)parm1)
+#define Xparm2 ((struct element_T1_8 *)parm2)
+    if (Xparm1->sqof__in && Xparm2->sqof__in) {
+       d += tcmp(TY_EXPLICIT, (char *)Xparm1->sqof__in, (char *)Xparm2->sqof__in);
+    } else if (Xparm1->sqof__in || Xparm2->sqof__in) {
+       (void) printf("%s: sqof__in one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->sqof__i != Xparm2->sqof__i) {
+       (void) printf("sqof__i integers different\n");
+       d++;
+    }
+    if (qb_cmp(Xparm1->sqof__o, Xparm2->sqof__o)) {
+       (void) printf("sqof__o octet string different\n");
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_MEMBER4:
+#define Xparm1 ((struct member_T1_4 *)parm1)
+#define Xparm2 ((struct member_T1_4 *)parm2)
+    if (Xparm1->member_T1_5 && Xparm2->member_T1_5) {
+       d += tcmp(TY_ELEMENT9, (char *)Xparm1->member_T1_5, (char *)Xparm2->member_T1_5);
+    } else if (Xparm1->member_T1_5 || Xparm2->member_T1_5) {
+       (void) printf("%s: member_T1_5 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->next && Xparm2->next) {
+       d += tcmp(TY_MEMBER4, (char *)Xparm1->next, (char *)Xparm2->next);
+    } else if (Xparm1->next || Xparm2->next) {
+       (void) printf("%s: next one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ELEMENT9:
+#define Xparm1 ((struct element_T1_9 *)parm1)
+#define Xparm2 ((struct element_T1_9 *)parm2)
+    if (Xparm1->stof__in && Xparm2->stof__in) {
+       d += tcmp(TY_EXPLICIT, (char *)Xparm1->stof__in, (char *)Xparm2->stof__in);
+    } else if (Xparm1->stof__in || Xparm2->stof__in) {
+       (void) printf("%s: stof__in one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->stof__i != Xparm2->stof__i) {
+       (void) printf("stof__i integers different\n");
+       d++;
+    }
+    if (qb_cmp(Xparm1->stof__o, Xparm2->stof__o)) {
+       (void) printf("stof__o octet string different\n");
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_CHOICE:
+#define Xparm1 ((struct type_T1_Choice__Test *)parm1)
+#define Xparm2 ((struct type_T1_Choice__Test *)parm2)
+    if (Xparm1->c1 && Xparm2->c1) {
+       d += tcmp(TY_CHOICE0, (char *)Xparm1->c1, (char *)Xparm2->c1);
+    } else if (Xparm1->c1 || Xparm2->c1) {
+       (void) printf("%s: c1 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->c2 && Xparm2->c2) {
+       d += tcmp(TY_CHOICE1, (char *)Xparm1->c2, (char *)Xparm2->c2);
+    } else if (Xparm1->c2 || Xparm2->c2) {
+       (void) printf("%s: c2 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->c3 && Xparm2->c3) {
+       d += tcmp(TY_CHOICE2, (char *)Xparm1->c3, (char *)Xparm2->c3);
+    } else if (Xparm1->c3 || Xparm2->c3) {
+       (void) printf("%s: c3 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    if (Xparm1->c4 && Xparm2->c4) {
+       d += tcmp(TY_ELEMENT11, (char *)Xparm1->c4, (char *)Xparm2->c4);
+    } else if (Xparm1->c4 || Xparm2->c4) {
+       (void) printf("%s: c4 one missing", t_case[tynum].tst_name);
+       d++;
+    }
+    break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_CHOICE0:
+#define Xparm1 ((struct choice_T1_0 *)parm1)
+#define Xparm2 ((struct choice_T1_0 *)parm2)
+       if (Xparm1->offset != Xparm2->offset) {
+           d++;
+           (void) printf("%s: offset mismatch %d != %d\n", t_case[tynum].tst_name,
+               Xparm1->offset, Xparm2->offset);
+           break;
+       }
+       switch (Xparm1->offset) {
+       case choice_T1_0_i__c1:
+           if (Xparm1->un.i__c1 != Xparm2->un.i__c1) {
+               d++;
+               (void) printf("%s: i__c1 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.i__c1, Xparm2->un.i__c1);
+           }
+           break;
+       
+       case choice_T1_0_o__c1:
+           if (qb_cmp(Xparm1->un.o__c1, Xparm2->un.o__c1)) {
+               (void) printf("o__c1 octet string different\n");
+               d++;
+           }
+           break;
+       
+       case choice_T1_0_b__c1:
+           if (bit_cmp(Xparm1->un.b__c1, Xparm2->un.b__c1)) {
+               (void) printf("un.b__c1 bitstring different\n");
+               d++;
+           }
+           break;
+       
+       case choice_T1_0_f__c1:
+           if (Xparm1->un.f__c1 && !Xparm2->un.f__c1
+             || !Xparm1->un.f__c1 && Xparm2->un.f__c1) {
+               (void) printf("f__c1 Boolean different\n");
+               d++;
+           }
+           break;
+       
+       case choice_T1_0_obj__c1:
+           if (Xparm1->un.obj__c1 && Xparm2->un.obj__c1) {
+               d += tcmp(TY_EMB_STRINGS, (char *)Xparm1->un.obj__c1,
+                 (char *)Xparm2->un.obj__c1);
+           } else if (Xparm1->un.obj__c1 || Xparm2->un.obj__c1) {
+               (void) printf("%s: un.obj__c1 one missing", t_case[tynum].tst_name);
+               d++;
+           }
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE0:illegal offset %d\n", Xparm1->offset);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_CHOICE1:
+#define Xparm1 ((struct choice_T1_1 *)parm1)
+#define Xparm2 ((struct choice_T1_1 *)parm2)
+       
+       if (Xparm1->offset != Xparm2->offset) {
+           d++;
+           (void) printf("%s: offset mismatch %d != %d\n", t_case[tynum].tst_name,
+               Xparm1->offset, Xparm2->offset);
+           break;
+       }
+       switch (Xparm1->offset) {
+       case choice_T1_1_i__c2:
+           if (Xparm1->un.i__c2 != Xparm2->un.i__c2) {
+               d++;
+               (void) printf("%s: i__c2 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.i__c2, Xparm2->un.i__c2);
+           }
+           break;
+       
+       case choice_T1_1_o__c2:
+           if (qb_cmp(Xparm1->un.o__c2, Xparm2->un.o__c2)) {
+               (void) printf("o__c2 octet string different\n");
+               d++;
+           }
+           break;
+       
+       case choice_T1_1_b__c2:
+           if (bit_cmp(Xparm1->un.b__c2, Xparm2->un.b__c2)) {
+               (void) printf("un.b__c2 bitstring different\n");
+               d++;
+           }
+           break;
+       
+       case choice_T1_1_f__c2:
+           if (Xparm1->un.f__c2 && !Xparm2->un.f__c2
+             || !Xparm1->un.f__c2 && Xparm2->un.f__c2) {
+               d++;
+               (void) printf("%s: f__c2 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.f__c2, Xparm2->un.f__c2);
+           }
+           break;
+       
+       case choice_T1_1_obj__c2:
+           if (Xparm1->un.obj__c2 && Xparm2->un.obj__c2) {
+               d += tcmp(TY_EMB_STRINGS, (char *)Xparm1->un.obj__c2,
+                 (char *)Xparm2->un.obj__c2);
+           } else if (Xparm1->un.obj__c2 || Xparm2->un.obj__c2) {
+               (void) printf("%s: un.obj__c2 one missing", t_case[tynum].tst_name);
+               d++;
+           }
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE1:illegal offset %d\n", Xparm1->offset);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_CHOICE2:
+#define Xparm1 ((struct choice_T1_2 *)parm1)
+#define Xparm2 ((struct choice_T1_2 *)parm2)
+       
+       switch (Xparm1->offset) {
+       case choice_T1_2_i__c3:
+           if (Xparm1->un.i__c3 != Xparm2->un.i__c3) {
+               d++;
+               (void) printf("%s: i__c3 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.i__c3, Xparm2->un.i__c3);
+           }
+           break;
+       
+       case choice_T1_2_seq__c3:
+           if (Xparm1->un.seq__c3 && Xparm2->un.seq__c3) {
+               d += tcmp(TY_ELEMENT10, (char *)Xparm1->un.seq__c3, (char *)Xparm2->un.seq__c3);
+           } else if (Xparm1->un.seq__c3 || Xparm2->un.seq__c3) {
+               (void) printf("%s: un.seq__c3 one missing", t_case[tynum].tst_name);
+               d++;
+           }
+           break;
+       
+       case choice_T1_2_set__c3:
+           if (Xparm1->un.set__c3 && Xparm2->un.set__c3) {
+               d += tcmp(TY_MEMBER6, (char *)Xparm1->un.set__c3, (char *)Xparm2->un.set__c3);
+           } else if (Xparm1->un.set__c3 || Xparm2->un.set__c3) {
+               (void) printf("%s: un.set__c3 one missing", t_case[tynum].tst_name);
+               d++;
+           }
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE2:illegal offset %d\n", Xparm1->offset);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_CHOICE3:
+#define Xparm1 ((struct choice_T1_3 *)parm1)
+#define Xparm2 ((struct choice_T1_3 *)parm2)
+       
+       switch (Xparm1->offset) {
+       case choice_T1_3_sc__a__i:
+           if (Xparm1->un.sc__a__i != Xparm2->un.sc__a__i) {
+               d++;
+               (void) printf("%s: sc__a__i mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.sc__a__i, Xparm2->un.sc__a__i);
+           }
+           break;
+       
+       case choice_T1_3_sc__b__i:
+           if (Xparm1->un.sc__b__i != Xparm2->un.sc__b__i) {
+               d++;
+               (void) printf("%s: sc__b__i mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.sc__b__i, Xparm2->un.sc__b__i);
+           }
+           break;
+       
+       case choice_T1_3_c4__i:
+           if (Xparm1->un.c4__i != Xparm2->un.c4__i) {
+               d++;
+               (void) printf("%s: c4__i mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.c4__i, Xparm2->un.c4__i);
+           }
+           break;
+       
+       case choice_T1_3_c4__obj:
+           if (Xparm1->un.c4__obj && Xparm2->un.c4__obj) {
+               d += tcmp(TY_EXPLICIT, (char *)Xparm1->un.c4__obj, (char *)Xparm2->un.c4__obj);
+           } else if (Xparm1->un.c4__obj || Xparm2->un.c4__obj) {
+               (void) printf("%s: un.c4__obj one missing", t_case[tynum].tst_name);
+               d++;
+           }
+           break;
+       
+       default:
+           ferrd(1, "TY_CHOICE3:illegal offset %d\n", Xparm1->offset);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ELEMENT10:
+#define Xparm1 ((struct element_T1_10 *)parm1)
+#define Xparm2 ((struct element_T1_10 *)parm2)
+       if (Xparm1->seq__c3__in && Xparm2->seq__c3__in) {
+           d += tcmp(TY_EXPLICIT, (char *)Xparm1->seq__c3__in, (char *)Xparm2->seq__c3__in);
+       } else if (Xparm1->seq__c3__in || Xparm2->seq__c3__in) {
+           (void) printf("%s: seq__c3__in one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->seq__c3__i != Xparm2->seq__c3__i) {
+           d++;
+           (void) printf("%s: seq__c3__i mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->seq__c3__i, Xparm2->seq__c3__i);
+       }
+       if (qb_cmp(Xparm1->seq__c3__o, Xparm2->seq__c3__o)) {
+           (void) printf("seq__c3__o octet string different\n");
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_MEMBER6:
+#define Xparm1 ((struct member_T1_6 *)parm1)
+#define Xparm2 ((struct member_T1_6 *)parm2)
+       if (Xparm1->set__c3__in && Xparm2->set__c3__in) {
+           d += tcmp(TY_EXPLICIT, (char *)Xparm1->set__c3__in, (char *)Xparm2->set__c3__in);
+       } else if (Xparm1->set__c3__in || Xparm2->set__c3__in) {
+           (void) printf("%s: set__c3__in one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->set__c3__i != Xparm2->set__c3__i) {
+           d++;
+           (void) printf("%s: set__c3__i mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->set__c3__i, Xparm2->set__c3__i);
+       }
+       if (qb_cmp(Xparm1->set__c3__o, Xparm2->set__c3__o)) {
+           (void) printf("set__c3__o octet string different\n");
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ELEMENT11:
+#define Xparm1 ((struct element_T1_11 *)parm1)
+#define Xparm2 ((struct element_T1_11 *)parm2)
+       if (Xparm1->c4__choice && Xparm2->c4__choice) {
+           d += tcmp(TY_CHOICE3, (char *)Xparm1->c4__choice, (char *)Xparm2->c4__choice);
+       } else if (Xparm1->c4__choice || Xparm2->c4__choice) {
+           (void) printf("%s: c4__choice one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_OPTIONAL:
+#define Xparm1 ((struct type_T1_Opt__Strings *)parm1)
+#define Xparm2 ((struct type_T1_Opt__Strings *)parm2)
+        if (Xparm1->optionals & opt_T1_Opt__Strings_a__opt) {
+           if (Xparm1->a__opt != Xparm2->a__opt) {
+               d++;
+               (void) printf("%s: a__opt mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->a__opt, Xparm2->a__opt);
+           }
+       }
+        if (Xparm1->optionals & opt_T1_Opt__Strings_d__opt) {
+           if (Xparm1->d__opt && !Xparm2->d__opt
+             || !Xparm1->d__opt && Xparm2->d__opt) {
+               d++;
+               (void) printf("%s: d__opt mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->d__opt, Xparm2->d__opt);
+           }
+       }
+       if (Xparm1->b__opt != NULLQB && Xparm2->b__opt != NULLQB) {
+           if (qb_cmp(Xparm1->b__opt, Xparm2->b__opt)) {
+               (void) printf("b__opt octet string different\n");
+               d++;
+           }
+       }
+       if (Xparm1->b__opt != NULLQB && Xparm2->b__opt == NULLQB
+        || Xparm1->b__opt == NULLQB && Xparm2->b__opt != NULLQB) {
+           (void) printf("%s: b__opt one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->c__opt != NULLPE && Xparm2->c__opt != NULLPE) {
+           if (bit_cmp(Xparm1->c__opt, Xparm2->c__opt)) {
+               (void) printf("%s:c__opt bitstring different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+        if (Xparm1->optionals & opt_T1_Opt__Strings_e__opt) {
+           if (Xparm1->e__opt && !Xparm2->e__opt
+           || !Xparm1->e__opt && Xparm2->e__opt) {
+               d++;
+               (void) printf("%s: e__opt mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->e__opt, Xparm2->e__opt);
+           }
+       }
+       if (Xparm1->big__opt && Xparm2->big__opt) {
+           d += tcmp(TY_STRINGS, (char *)Xparm1->big__opt,
+              (char *)Xparm2->big__opt);
+       } else if (Xparm1->big__opt && !Xparm2->big__opt
+              || !Xparm1->big__opt && Xparm2->big__opt) {
+           (void) printf("%s: big__opt one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->emb__opt && Xparm2->emb__opt) {
+           d += tcmp(TY_ELEMENT12, (char *)Xparm1->emb__opt,
+              (char *)Xparm2->emb__opt);
+       } else if (Xparm1->emb__opt && !Xparm2->emb__opt
+              || !Xparm1->emb__opt && Xparm2->emb__opt) {
+           (void) printf("%s: emb__opt one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->st__opt && Xparm2->st__opt) {
+           d += tcmp(TY_MEMBER7, (char *)Xparm1->st__opt,
+              (char *)Xparm2->st__opt);
+       } else if (Xparm1->st__opt && !Xparm2->st__opt
+              || !Xparm1->st__opt && Xparm2->st__opt) {
+           (void) printf("%s: st__opt one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->obj__opt && Xparm2->obj__opt) {
+           d += tcmp(TY_MPDU, (char *)Xparm1->obj__opt,
+              (char *)Xparm2->obj__opt);
+       } else if (Xparm1->obj__opt && !Xparm2->obj__opt
+              || !Xparm1->obj__opt && Xparm2->obj__opt) {
+           (void) printf("%s: obj__opt one missing", t_case[tynum].tst_name);
+           d++;
+       }
+        if (Xparm1->optionals & opt_T1_Opt__Strings_etag__opt) {
+           if (Xparm1->etag__opt != Xparm2->etag__opt) {
+               d++;
+               (void) printf("%s: etag__opt mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->etag__opt, Xparm2->etag__opt);
+           }
+       }
+       if (Xparm1->ch__opt && Xparm2->ch__opt) {
+           d += tcmp(TY_CHOICE4, (char *)Xparm1->ch__opt,
+              (char *)Xparm2->ch__opt);
+       } else if (Xparm1->ch__opt && !Xparm2->ch__opt
+              || !Xparm1->ch__opt && Xparm2->ch__opt) {
+           (void) printf("%s: ch__opt one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_ELEMENT12:
+#define Xparm1 ((struct element_T1_12 *)parm1)
+#define Xparm2 ((struct element_T1_12 *)parm2)
+        if (Xparm1->optionals & opt_T1_element_T1_12_oem__int) {
+           if (Xparm1->oem__int != Xparm2->oem__int) {
+               d++;
+               (void) printf("%s: oem__int mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->oem__int, Xparm2->oem__int);
+           }
+       }
+       if (Xparm1->oem__oct != NULLQB && Xparm2->oem__oct != NULLQB) {
+           if (qb_cmp(Xparm1->oem__oct, Xparm2->oem__oct)) {
+               (void) printf("oem__oct octet string different\n");
+               d++;
+           }
+       }
+       if (Xparm1->oem__oct != NULLQB && Xparm2->oem__oct == NULLQB
+        || Xparm1->oem__oct == NULLQB && Xparm2->oem__oct != NULLQB) {
+           (void) printf("%s: oem__oct one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->oem__bit != NULLPE && Xparm2->oem__bit != NULLPE) {
+           if (bit_cmp(Xparm1->oem__bit, Xparm2->oem__bit)) {
+               (void) printf("%s:oem__bit bitstring different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_MEMBER7:
+#define Xparm1 ((struct member_T1_7 *)parm1)
+#define Xparm2 ((struct member_T1_7 *)parm2)
+        if (Xparm1->optionals & opt_T1_member_T1_7_st__int0) {
+           if (Xparm1->st__int0 != Xparm2->st__int0) {
+               d++;
+               (void) printf("%s: st__int0 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->st__int0, Xparm2->st__int0);
+           }
+       }
+        if (Xparm1->optionals & opt_T1_member_T1_7_st__int1) {
+           if (Xparm1->st__int1 != Xparm2->st__int1) {
+               d++;
+               (void) printf("%s: st__int1 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->st__int1, Xparm2->st__int1);
+           }
+       }
+        if (Xparm1->optionals & opt_T1_member_T1_7_st__int2) {
+           if (Xparm1->st__int2 != Xparm2->st__int2) {
+               d++;
+               (void) printf("%s: st__int2 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->st__int2, Xparm2->st__int2);
+           }
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_CHOICE4:
+#define Xparm1 ((struct choice_T1_4 *)parm1)
+#define Xparm2 ((struct choice_T1_4 *)parm2)
+       if (Xparm1->offset != Xparm2->offset) {
+           d++;
+           (void) printf("%s: offset mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->offset, Xparm2->offset);
+           break;
+       }
+       switch (Xparm1->offset) {
+       case choice_T1_4_ch__1:
+           if (Xparm1->un.ch__1 != Xparm2->un.ch__1) {
+               d++;
+               (void) printf("%s: ch__1 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.ch__1, Xparm2->un.ch__1);
+           }
+           break;
+       
+       case choice_T1_4_ch__2:
+           if (Xparm1->un.ch__2 != Xparm2->un.ch__2) {
+               d++;
+               (void) printf("%s: ch__2 mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.ch__2, Xparm2->un.ch__2);
+           }
+           break;
+       
+       default:
+           ferrd(1, "tcmp:TY_CHOICE4:illegal offset %d\n", Xparm1->offset);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_EXTREF:
+#define Xparm1 ((struct type_T1_E__ref *)parm1)
+#define Xparm2 ((struct type_T1_E__ref *)parm2)
+       if (Xparm1->a__ref && Xparm2->a__ref) {
+           d += tcmp(TY_T2_INFO, (char *)Xparm1->a__ref,
+              (char *)Xparm2->a__ref);
+       } else if (Xparm1->a__ref == NULL || Xparm2->a__ref == NULL) {
+           (void) printf("%s: a__ref one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->b__ref && Xparm2->b__ref) {
+           d += tcmp(TY_T2_INFO, (char *)Xparm1->b__ref,
+              (char *)Xparm2->b__ref);
+       } else if (Xparm1->b__ref == NULL || Xparm2->b__ref == NULL) {
+           (void) printf("%s: b__ref one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->c__ref && Xparm2->c__ref) {
+           d += tcmp(TY_CHOICE, (char *)Xparm1->c__ref,
+              (char *)Xparm2->c__ref);
+       } else if (Xparm1->c__ref == NULL || Xparm2->c__ref == NULL) {
+           (void) printf("%s: c__ref one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->d__ref && Xparm2->d__ref) {
+           d += tcmp(TY_T2_INFO, (char *)Xparm1->d__ref,
+              (char *)Xparm2->d__ref);
+       } else if (Xparm1->d__ref && !Xparm2->d__ref
+              || !Xparm1->d__ref && Xparm2->d__ref) {
+           (void) printf("%s: d__ref one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->e__ref && Xparm2->e__ref) {
+           d += tcmp(TY_T2_INFO, (char *)Xparm1->e__ref,
+              (char *)Xparm2->e__ref);
+       } else if (Xparm1->e__ref && !Xparm2->e__ref
+              || !Xparm1->e__ref && Xparm2->e__ref) {
+           (void) printf("%s: e__ref one missing", t_case[tynum].tst_name);
+           d++;
+       }
+        break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_T2_INFO:
+#define Xparm1 ((struct type_T2_Info *)parm1)
+#define Xparm2 ((struct type_T2_Info *)parm2)
+       if (Xparm1->a1 != Xparm2->a1) {
+           d++;
+           (void) printf("%s: a1 mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->a1, Xparm2->a1);
+       }
+       if (Xparm1->a2 != Xparm2->a2) {
+           d++;
+           (void) printf("%s: a2 mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->a2, Xparm2->a2);
+       }
+       if (Xparm1->a3 != Xparm2->a3) {
+           d++;
+           (void) printf("%s: a3 mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->a3, Xparm2->a3);
+       }
+       if (Xparm1->a4 && Xparm2->a4) {
+           d += tcmp(TY_T2_MPDU, (char *)Xparm1->a4, (char *)Xparm2->a4);
+       } else if (Xparm1->a4 == NULL || Xparm2->a4 == NULL) {
+           (void) printf("%s: a4 one missing", t_case[tynum].tst_name);
+           d++;
+       }
+        break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_T2_MPDU:
+#define Xparm1 ((struct type_T2_MPDU *)parm1)
+#define Xparm2 ((struct type_T2_MPDU *)parm2)
+       if (Xparm1->a__seq && Xparm2->a__seq) {
+           d += tcmp(TY_T2_ELEM0, (char *)Xparm1->a__seq,
+              (char *)Xparm2->a__seq);
+       } else if (Xparm1->a__seq == NULL || Xparm2->a__seq == NULL) {
+           (void) printf("%s: a__seq one missing", t_case[tynum].tst_name);
+           d++;
+       }
+        break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_T2_ELEM0:
+#define Xparm1 ((struct element_T2_0 *)parm1)
+#define Xparm2 ((struct element_T2_0 *)parm2)
+       if (Xparm1->fred != Xparm2->fred) {
+           d++;
+           (void) printf("%s: fred mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->fred, Xparm2->fred);
+       }
+        break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_OPTIMISED:
+#define Xparm1 ((struct type_T1_Optimised *)parm1)
+#define Xparm2 ((struct type_T1_Optimised *)parm2)
+       if (Xparm1->o1 == NULLPE || Xparm2->o1 == NULLPE) {
+           (void) printf("%s: o1 one missing\n", t_case[tynum].tst_name);
+           d++;
+       } else if (bit_cmp(Xparm1->o1, Xparm2->o1)) {
+               (void) printf("%s:o1 bitstring different\n",
+                   t_case[tynum].tst_name);
+               d++;
+       }
+       if (Xparm1->o2 != NULLQB && Xparm2->o2 != NULLQB) {
+           if (qb_cmp(Xparm1->o2, Xparm2->o2)) {
+               (void) printf("o2 octet string different\n");
+               d++;
+           }
+       } else {
+           (void) printf("%s: o2 one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->o3 && Xparm2->o3) {
+           d += tcmp(TY_MPDU, (char *)Xparm1->o3, (char *)Xparm2->o3);
+       } else if (Xparm1->o3 == NULL || Xparm2->o3 == NULL) {
+           (void) printf("%s: o3 one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->o4 != NULLPE && Xparm2->o4 == NULLPE
+        || Xparm1->o4 == NULLPE && Xparm2->o4 != NULLPE) {
+           (void) printf("%s: o4 one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->o4 != NULLPE && Xparm2->o4 != NULLPE) {
+           if (pe_cmp(Xparm1->o4, Xparm2->o4)) {
+               (void) printf("%s:o4 SET of ANY different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+       if (Xparm1->element_T1_14 && Xparm2->element_T1_14) {
+           d += tcmp(TY_MEMBER9, (char *)Xparm1->element_T1_14,
+           (char *)Xparm2->element_T1_14);
+       } else if (Xparm1->element_T1_14 == NULL
+                || Xparm2->element_T1_14 == NULL) {
+           (void) printf("%s: element_T1_14 one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+     case TY_MEMBER9:
+#define Xparm1 ((struct member_T1_9 *)parm1)
+#define Xparm2 ((struct member_T1_9 *)parm2)
+       if (Xparm1->o5 != NULLPE && Xparm2->o5 != NULLPE) {
+           if (pe_cmp(Xparm1->o5, Xparm2->o5)) {
+               (void) printf("%s:o5 SET of ANY different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: o5 one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->o6 != NULLPE && Xparm2->o6 != NULLPE) {
+           if (pe_cmp(Xparm1->o6, Xparm2->o6)) {
+               (void) printf("%s:o6 SET of ANY different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: o6 one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->o7 != NULLOID && Xparm2->o7 != NULLOID) {
+           if (oid_cmp(Xparm1->o7, Xparm2->o7)) {
+               (void) printf("%s:o7 OID different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: o7 one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_EXTERNAL:
+#define Xparm1 ((struct type_T1_Ext__typ *)parm1)
+#define Xparm2 ((struct type_T1_Ext__typ *)parm2)
+       if (Xparm1->ext != NULL && Xparm2->ext != NULL) {
+           if (ext_cmp(Xparm1->ext, Xparm2->ext)) {
+               (void) printf("%s:ext EXTERNAL different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: ext one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->a__ny != NULLPE && Xparm2->a__ny != NULLPE) {
+           if (pe_cmp(Xparm1->a__ny, Xparm2->a__ny)) {
+               (void) printf("%s:a__ny ANY different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: a__ny one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->ext__impl != NULL && Xparm2->ext__impl != NULL) {
+           if (ext_cmp(Xparm1->ext__impl, Xparm2->ext__impl)) {
+               (void) printf("%s:ext__impl EXTERNAL different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: ext__impl one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->any__impl != NULLPE && Xparm2->any__impl != NULLPE) {
+           if (pe_cmp(Xparm1->any__impl, Xparm2->any__impl)) {
+               (void) printf("%s:any__impl ANY different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: any__impl one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->ext__expl != NULL && Xparm2->ext__expl != NULL) {
+           if (ext_cmp(Xparm1->ext__expl, Xparm2->ext__expl)) {
+               (void) printf("%s:ext__expl EXTERNAL different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: ext__expl one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->any__expl != NULLPE && Xparm2->any__expl != NULLPE) {
+           if (pe_cmp(Xparm1->any__expl, Xparm2->any__expl)) {
+               (void) printf("%s:any__expl ANY different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: any__expl one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_SEXTERNAL:
+#define Xparm1 ((struct type_T1_SExt *)parm1)
+#define Xparm2 ((struct type_T1_SExt *)parm2)
+       if (Xparm1 != NULL && Xparm2 != NULL) {
+           if (ext_cmp(Xparm1, Xparm2)) {
+               (void) printf("%s:ext EXTERNAL different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: ext one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+
+    case TY_ETAGOBJ:
+#define Xparm1 ((struct type_T1_Etags *)parm1)
+#define Xparm2 ((struct type_T1_Etags *)parm2)
+       if (Xparm1->offset != Xparm2->offset) {
+           d++;
+           (void) printf("%s: offset mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->offset, Xparm2->offset);
+           break;
+       }
+       switch (Xparm1->offset) {
+       case type_T1_Etags_aE:
+           if (Xparm1->un.aE != Xparm2->un.aE) {
+               d++;
+               (void) printf("%s: un.aE mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.aE, Xparm2->un.aE);
+           }
+           break;
+       
+       case type_T1_Etags_bE:
+           if (Xparm1->un.bE != Xparm2->un.bE) {
+               d++;
+               (void) printf("%s: un.bE mismatch %d != %d", t_case[tynum].tst_name,
+                   Xparm1->un.bE, Xparm2->un.bE);
+           }
+           break;
+       
+       default:
+           ferrd(1, "TY_ETAGOBJ:illegal offset %d\n", Xparm1->offset);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+/* This has to be changed when posy is upgraded to handle DEFAULTS properly */
+    case TY_DEFAULT:
+#define Xparm1 ((struct type_T1_Def__Strings *)parm1)
+#define Xparm2 ((struct type_T1_Def__Strings *)parm2)
+       if (Xparm1->a__def != Xparm2->a__def) {
+           d++;
+           (void) printf("%s: a__def mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->a__def, Xparm2->a__def);
+       }
+       if (Xparm1->b__def != NULLQB && Xparm2->b__def != NULLQB) {
+           if (qb_cmp(Xparm1->b__def, Xparm2->b__def)) {
+               (void) printf("b__def octet string different\n");
+               d++;
+           }
+       } else if (Xparm2->b__def == NULLQB) {
+           (void) printf("%s: b__def one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->c__def != NULLPE && Xparm2->c__def != NULLPE) {
+           if (bit_cmp(Xparm1->c__def, Xparm2->c__def)) {
+                   (void) printf("%s:c__def bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->c__def == NULLPE) {
+           (void) printf("%s: c__def restored version missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->okay != Xparm2->okay) {
+           d++;
+           (void) printf("%s: okay mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->okay, Xparm2->okay);
+       }
+       /* Can't test NULL ....
+       if (Xparm1->e__opt != Xparm2->e__opt) {
+           d++;
+           (void) printf("%s: e__opt mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->e__opt, Xparm2->e__opt);
+       }
+       */
+       if (Xparm1->big__def && Xparm2->big__def) {
+           d += tcmp(TY_STRINGS, (char *)Xparm1->big__def,
+           (char *)Xparm2->big__def);
+       } else {
+           (void) printf("%s: big__def one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->emb__def && Xparm2->emb__def) {
+           d += tcmp(TY_ELEMENT13, (char *)Xparm1->emb__def,
+           (char *)Xparm2->emb__def);
+       } else if (Xparm1->emb__def != NULL || Xparm2->emb__def != NULL) {
+           (void) printf("%s: emb__def one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->st__def && Xparm2->st__def) {
+           d += tcmp(TY_MEMBER8, (char *)Xparm1->st__def,
+           (char *)Xparm2->st__def);
+       } else if (Xparm1->st__def != NULL || Xparm2->st__def != NULL) {
+           (void) printf("%s: st__def one missing", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ELEMENT13:
+#define Xparm1 ((struct element_T1_13 *)parm1)
+#define Xparm2 ((struct element_T1_13 *)parm2)
+       if (Xparm1->colour != Xparm2->colour) {
+           d++;
+           (void) printf("%s: colour mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->colour, Xparm2->colour);
+       }
+       if (Xparm1->oem__oct != NULLQB && Xparm2->oem__oct != NULLQB) {
+           if (qb_cmp(Xparm1->oem__oct, Xparm2->oem__oct)) {
+               (void) printf("oem__oct octet string different\n");
+               d++;
+           }
+       } else if (Xparm1->oem__oct != NULLQB || Xparm2->oem__oct != NULLQB) {
+           (void) printf("oem__oct: one missing 0x%x, 0x%x\n", Xparm1->oem__oct,
+           Xparm1->oem__oct);
+           d++;
+       }
+       if (Xparm1->version != NULLPE && Xparm2->version != NULLPE) {
+           if (bit_cmp(Xparm1->version, Xparm2->version)) {
+                   (void) printf("%s:version bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->version == NULLPE) {
+           (void) printf("%s: version decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_MEMBER8:
+#define Xparm1 ((struct member_T1_8 *)parm1)
+#define Xparm2 ((struct member_T1_8 *)parm2)
+       if (Xparm1->wine != Xparm2->wine) {
+           d++;
+           (void) printf("%s: wine mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->wine, Xparm2->wine);
+       }
+       if (Xparm1->beer != Xparm2->beer) {
+           d++;
+           (void) printf("%s: beer mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->beer, Xparm2->beer);
+       }
+       if (Xparm1->spirit != Xparm2->spirit) {
+           d++;
+           (void) printf("%s: spirit mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->spirit, Xparm2->spirit);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_STEST:
+#define Xparm1 ((struct type_T1_Stest *)parm1)
+#define Xparm2 ((struct type_T1_Stest *)parm2)
+       if (Xparm1->st1 != NULL && Xparm2->st1 != NULL) {
+           d += tcmp(TY_SINT, (char *)Xparm1->st1, (char *)Xparm2->st1);
+       } else if (Xparm2->st1 == NULL) {
+           d++;
+           (void) printf("%s: missing", t_case[tynum].tst_name);
+       }
+       if (Xparm1->st2 != NULL && Xparm2->st2 != NULL) {
+           if (qb_cmp(Xparm1->st2, Xparm2->st2)) {
+               (void) printf("%s:st2 octet string different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else if (Xparm2->st2 == NULL) {
+           d++;
+           (void) printf("%s: missing", t_case[tynum].tst_name);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_SINT:
+#define Xparm1 ((struct type_T1_Sint *)parm1)
+#define Xparm2 ((struct type_T1_Sint *)parm2)
+       if (Xparm1->parm != Xparm2->parm) {
+           (void) printf("%s:parm %d != %d\n", t_case[tynum].tst_name, Xparm1->parm,
+               Xparm2->parm);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ETYPE:
+#define Xparm1 ((struct type_T1_Enum__type *)parm1)
+#define Xparm2 ((struct type_T1_Enum__type *)parm2)
+       if (Xparm1->parm != Xparm2->parm) {
+           (void) printf("%s:parm %d != %d\n", t_case[tynum].tst_name, Xparm1->parm,
+               Xparm2->parm);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_ENUM_TEST:
+#define Xparm1 ((struct type_T1_T__enum *)parm1)
+#define Xparm2 ((struct type_T1_T__enum *)parm2)
+       if (Xparm1->ae1 && Xparm2->ae1 ) {
+           d += tcmp(TY_ETYPE, (char *)Xparm1->ae1, (char *)Xparm2->ae1);
+       } else {
+           d++;
+           (void) printf("%s:ae1 missing\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->ae2 && Xparm2->ae2 ) {
+           d += tcmp(TY_ETYPE, (char *)Xparm1->ae2, (char *)Xparm2->ae2);
+       } else {
+           d++;
+           (void) printf("%s:ae2 missing\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->ae3 && Xparm2->ae3 ) {
+           d += tcmp(TY_ETYPE, (char *)Xparm1->ae3, (char *)Xparm2->ae3);
+       } else {
+           d++;
+           (void) printf("%s:ae3 missing\n", t_case[tynum].tst_name);
+       }
+       /* Default */
+       if (Xparm1->ae4 && Xparm2->ae4 ) {
+           d += tcmp(TY_ETYPE, (char *)Xparm1->ae4, (char *)Xparm2->ae4);
+       } else {
+           d++;
+           (void) printf("%s:ae4 missing\n", t_case[tynum].tst_name);
+       }
+       /* Optional */
+       if (Xparm1->ae5 && Xparm2->ae5 ) {
+           d += tcmp(TY_ETYPE, (char *)Xparm1->ae5, (char *)Xparm2->ae5);
+       } else if (Xparm1->ae5 || Xparm2->ae5) {
+           d++;
+           (void) printf("%s:ae5 missing\n", t_case[tynum].tst_name);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+#ifdef PEPSY_REALS
+    case TY_REAL:
+#define Xparm1 ((struct type_T1_Real *)parm1)
+#define Xparm2 ((struct type_T1_Real *)parm2)
+       /* Horrible floating point test for roughly equal */
+       if (fabs(Xparm1->parm) < F_SMALL/2) {
+            if (fabs(Xparm1->parm - Xparm2->parm) > F_SMALL) {
+               (void) printf("%s:parm %f != %f\n", t_case[tynum].tst_name,
+                   Xparm1->parm, Xparm2->parm);
+               d++;
+           }
+       } else if (fabs((Xparm1->parm - Xparm2->parm)/Xparm1->parm) > F_SMALL) {
+           (void) printf("%s:parm %f != %f\n", t_case[tynum].tst_name, Xparm1->parm,
+               Xparm2->parm);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_REAL_TEST:
+#define Xparm1 ((struct type_T1_T__real *)parm1)
+#define Xparm2 ((struct type_T1_T__real *)parm2)
+       if (Xparm1->r1 && Xparm2->r1 ) {
+           d += tcmp(TY_REAL, (char *)Xparm1->r1, (char *)Xparm2->r1);
+       } else {
+           d++;
+           (void) printf("%s:r1 missing\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->r2 && Xparm2->r2 ) {
+           d += tcmp(TY_REAL, (char *)Xparm1->r2, (char *)Xparm2->r2);
+       } else {
+           d++;
+           (void) printf("%s:r2 missing\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->r3 && Xparm2->r3 ) {
+           d += tcmp(TY_REAL, (char *)Xparm1->r3, (char *)Xparm2->r3);
+       } else {
+           d++;
+           (void) printf("%s:r3 missing\n", t_case[tynum].tst_name);
+       }
+       /* Default */
+       if (Xparm1->r4 && Xparm2->r4 ) {
+           d += tcmp(TY_REAL, (char *)Xparm1->r4, (char *)Xparm2->r4);
+       } else {
+           d++;
+           (void) printf("%s:r4 missing\n", t_case[tynum].tst_name);
+       }
+       /* Optional */
+       if (Xparm1->r5 && Xparm2->r5 ) {
+           d += tcmp(TY_REAL, (char *)Xparm1->r5, (char *)Xparm2->r5);
+       } else if (Xparm1->r5 || Xparm2->r5) {
+           d++;
+           (void) printf("%s:r5 missing\n", t_case[tynum].tst_name);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_PEPY:
+#define Xparm1 ((struct pepy_refs *)parm1)
+#define Xparm2 ((struct pepy_refs *)parm2)
+       if (Xparm1->t_int != Xparm2->t_int) {
+           d++;
+           (void) printf("%s: t_int mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->t_int, Xparm2->t_int);
+       }
+
+       if (Xparm1->t_enum != Xparm2->t_enum) {
+           d++;
+           (void) printf("%s:t_enum mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->t_enum, Xparm2->t_enum);
+       }
+
+       if (qb_cmp(Xparm1->t_qbuf, Xparm2->t_qbuf)) {
+               (void) printf("t_qbuf octet string different\n");
+               d++;
+       }
+
+       if (Xparm1->t_bool != Xparm2->t_bool) {
+           d++;
+           (void) printf("%s:t_bool mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->t_bool, Xparm2->t_bool);
+       }
+
+#ifdef PEPSY_REALS
+       /* Horrible floating point test for roughly equal */
+       if (fabs(Xparm1->t_real) < F_SMALL/2) {
+            if (fabs(Xparm1->t_real - Xparm2->t_real) > F_SMALL) {
+               (void) printf("%s:t_real %f != %f\n", t_case[tynum].tst_name,
+                   Xparm1->t_real, Xparm2->t_real);
+               d++;
+           }
+       } else if (fabs((Xparm1->t_real - Xparm2->t_real)/Xparm1->t_real) > F_SMALL) {
+           (void) printf("%s:t_real %f != %f\n", t_case[tynum].tst_name,
+               Xparm1->t_real, Xparm2->t_real);
+           d++;
+       }
+#endif
+       if (Xparm1->t_any != NULLPE && Xparm2->t_any != NULLPE) {
+           if (pe_cmp(Xparm1->t_any, Xparm2->t_any)) {
+               (void) printf("%s:t_any different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+       if (Xparm1->t_oid != NULLOID && Xparm2->t_oid != NULLOID) {
+           if (oid_cmp(Xparm1->t_oid, Xparm2->t_oid)) {
+               (void) printf("%s:t_oid OID different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: t_oid one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_bstring != NULLCP && Xparm2->t_bstring != NULLCP) {
+           if (bitstr_cmp(Xparm1->t_bstring, Xparm1->t_blen,
+               Xparm2->t_bstring, Xparm2->t_blen)) {
+                   (void) printf("%s:t_blen string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_bstring == NULLCP) {
+           (void) printf("%s: t_bstring decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_ostring != NULLCP && Xparm2->t_ostring != NULLCP) {
+           if (Xparm1->t_olen != Xparm2->t_olen) {
+                   (void) printf("%s:t_olen string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           } else if (bcmp(Xparm1->t_ostring, Xparm2->t_ostring,
+               Xparm1->t_olen)) {
+                   (void) printf("%s:t_ostring string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_ostring == NULLCP) {
+           (void) printf("%s: t_ostring decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_string != NULLCP && Xparm2->t_string != NULLCP) {
+           if (strcmp(Xparm1->t_string, Xparm2->t_string)) {
+                   (void) printf("%s:t_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_string == NULLCP) {
+           (void) printf("%s: t_string decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_pe != NULLPE && Xparm2->t_pe != NULLPE) {
+           if (bit_cmp(Xparm1->t_pe, Xparm2->t_pe)) {
+                   (void) printf("%s:t_pe bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_pe == NULLPE) {
+           (void) printf("%s: t_pe decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_def && Xparm2->t_def ) {
+           d += tcmp(TY_DEFPEPY, (char *)Xparm1->t_def, (char *)Xparm2->t_def);
+       } else if (Xparm1->t_def || Xparm2->t_def) {
+           d++;
+           (void) printf("%s:t_def missing\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->t_opt && Xparm2->t_opt ) {
+           d += tcmp(TY_OPTPEPY, (char *)Xparm1->t_opt, (char *)Xparm2->t_opt);
+           for (i = NUMOPT - 1; i >= 0; i--)
+                if (BITTEST(Xparm1->t_opt->opt_set, i)
+                    != BITTEST(Xparm2->t_opt->opt_set, i)) {
+                   d++;
+                   (void) printf("%s:t_opt missing optional %d\n",
+                       t_case[tynum].tst_name, i);
+                }
+       } else if (Xparm1->t_opt || Xparm2->t_opt) {
+           d++;
+           (void) printf("%s:t_opt missing\n", t_case[tynum].tst_name);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_DEFPEPY:
+    case TY_OPTPEPY:
+#define Xparm1 ((struct pepy_refs1 *)parm1)
+#define Xparm2 ((struct pepy_refs1 *)parm2)
+       if (tynum == TY_DEFPEPY || (BITTEST(Xparm1->opt_set, OPT_INT1) != 0
+            && BITTEST(Xparm2->opt_set, OPT_INT1) != 0)) {
+           if (Xparm1->t_int != Xparm2->t_int) {
+               d++;
+               (void) printf("%s: t_int mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_int, Xparm2->t_int);
+           }
+       }
+       if (tynum == TY_DEFPEPY || (BITTEST(Xparm1->opt_set, OPT_INT2) != 0
+            && BITTEST(Xparm2->opt_set, OPT_INT2) != 0)) {
+           if (Xparm1->t_int1 != Xparm2->t_int1) {
+               d++;
+               (void) printf("%s: t_int1 mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_int1, Xparm2->t_int1);
+           }
+       }
+
+       if (tynum == TY_DEFPEPY || (BITTEST(Xparm1->opt_set, OPT_ENUM1) != 0
+            && BITTEST(Xparm2->opt_set, OPT_ENUM1) != 0)) {
+           if (Xparm1->t_enum != Xparm2->t_enum) {
+               d++;
+               (void) printf("%s:t_enum mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_enum, Xparm2->t_enum);
+           }
+       }
+       if (tynum == TY_DEFPEPY || (BITTEST(Xparm1->opt_set, OPT_ENUM2) != 0
+            && BITTEST(Xparm2->opt_set, OPT_ENUM2) != 0)) {
+           if (Xparm1->t_enum1 != Xparm2->t_enum1) {
+               d++;
+               (void) printf("%s:t_enum1 mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_enum1, Xparm2->t_enum1);
+           }
+       }
+
+       if (qb_cmp(Xparm1->t_qbuf, Xparm2->t_qbuf)) {
+               (void) printf("t_qbuf octet string different\n");
+               d++;
+       }
+       if (qb_cmp(Xparm1->t_qbuf1, Xparm2->t_qbuf1)) {
+               (void) printf("t_qbuf1 octet string different\n");
+               d++;
+       }
+
+       if (tynum == TY_DEFPEPY || (BITTEST(Xparm1->opt_set, OPT_BOOL1) != 0
+            && BITTEST(Xparm2->opt_set, OPT_BOOL1) != 0)) {
+           if (Xparm1->t_bool != Xparm2->t_bool) {
+               d++;
+               (void) printf("%s:t_bool mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_bool, Xparm2->t_bool);
+           }
+       }
+       if (tynum == TY_OPTPEPY) {
+           if (BITTEST(Xparm1->opt_set, OPT_BOOL2) != 0
+            && BITTEST(Xparm2->opt_set, OPT_BOOL2) != 0) {
+               if (Xparm1->t_bool1 != Xparm2->t_bool1) {
+                   d++;
+                   (void) printf("%s:t_bool1 mismatch %d != %d\n", t_case[tynum].tst_name,
+                       Xparm1->t_bool1, Xparm2->t_bool1);
+               }
+           } else if (BITTEST(Xparm1->opt_set, OPT_BOOL2) != 0
+                   || BITTEST(Xparm2->opt_set, OPT_BOOL2) != 0) {
+               d++;
+               (void) printf("%s: t_bool1 missing %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->opt_set, Xparm2->opt_set);
+           }
+       }
+
+#ifdef PEPSY_REALS
+       /* Horrible floating point test for roughly equal */
+       if (fabs(Xparm1->t_real) < F_SMALL/2) {
+            if (fabs(Xparm1->t_real - Xparm2->t_real) > F_SMALL) {
+               (void) printf("%s:t_real %f != %f\n", t_case[tynum].tst_name,
+                   Xparm1->t_real, Xparm2->t_real);
+               d++;
+           }
+       } else if (tynum == TY_DEFPEPY 
+           && fabs((Xparm1->t_real - Xparm2->t_real)/Xparm1->t_real) > F_SMALL) {
+           (void) printf("%s:t_real %f != %f\n", t_case[tynum].tst_name,
+               Xparm1->t_real, Xparm2->t_real);
+           d++;
+       }
+       if (fabs(Xparm1->t_real1) < F_SMALL/2) {
+            if (fabs(Xparm1->t_real1 - Xparm2->t_real1) > F_SMALL) {
+               (void) printf("%s:t_real1 %f != %f\n", t_case[tynum].tst_name,
+                   Xparm1->t_real1, Xparm2->t_real1);
+               d++;
+           }
+       } else if (tynum == TY_DEFPEPY 
+           && fabs((Xparm1->t_real1 - Xparm2->t_real1)/Xparm1->t_real1) > F_SMALL) {
+           (void) printf("%s:t_real1 %f != %f\n", t_case[tynum].tst_name,
+               Xparm1->t_real1, Xparm2->t_real1);
+           d++;
+       }
+#endif
+       if (Xparm1->t_any != NULLPE && Xparm2->t_any != NULLPE) {
+           if (pe_cmp(Xparm1->t_any, Xparm2->t_any)) {
+               (void) printf("%s:t_any different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+
+       if (Xparm1->t_oid != NULLOID && Xparm2->t_oid != NULLOID) {
+           if (oid_cmp(Xparm1->t_oid, Xparm2->t_oid)) {
+               (void) printf("%s:t_oid OID different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: t_oid one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_oid1 != NULLOID && Xparm2->t_oid1 != NULLOID) {
+           if (oid_cmp(Xparm1->t_oid1, Xparm2->t_oid1)) {
+               (void) printf("%s:t_oid1 OID different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+
+       if (Xparm1->t_bstring != NULLCP && Xparm2->t_bstring != NULLCP) {
+           if (bitstr_cmp(Xparm1->t_bstring, Xparm1->t_blen,
+               Xparm2->t_bstring, Xparm2->t_blen)) {
+                   (void) printf("%s:t_blen string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_bstring == NULLCP) {
+           (void) printf("%s: t_bstring decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_bstring1 != NULLCP && Xparm2->t_bstring1 != NULLCP) {
+           if (bitstr_cmp(Xparm1->t_bstring1, Xparm1->t_blen1,
+               Xparm2->t_bstring1, Xparm2->t_blen1)) {
+                   (void) printf("%s:t_blen1 string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (tynum == TY_DEFPEPY && Xparm2->t_bstring1 == NULLCP) {
+           (void) printf("%s: t_bstring1 decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+
+       if (Xparm1->t_ostring != NULLCP && Xparm2->t_ostring != NULLCP) {
+           if (Xparm1->t_olen != Xparm2->t_olen) {
+                   (void) printf("%s:t_olen string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           } else if (bcmp(Xparm1->t_ostring, Xparm2->t_ostring,
+               Xparm1->t_olen)) {
+                   (void) printf("%s:t_ostring string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_ostring == NULLCP) {
+           (void) printf("%s: t_ostring decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_ostring1 != NULLCP && Xparm2->t_ostring1 != NULLCP) {
+           if (Xparm1->t_olen1 != Xparm2->t_olen1) {
+                   (void) printf("%s:t_olen1 string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           } else if (bcmp(Xparm1->t_ostring1, Xparm2->t_ostring1,
+               Xparm1->t_olen1)) {
+                   (void) printf("%s:t_ostring string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_ostring1 == NULLCP) {
+           (void) printf("%s: t_ostring1 decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+
+       if (Xparm1->t_string != NULLCP && Xparm2->t_string != NULLCP) {
+           if (strcmp(Xparm1->t_string, Xparm2->t_string)) {
+                   (void) printf("%s:t_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_string == NULLCP) {
+           (void) printf("%s: t_string decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_string1 != NULLCP && Xparm2->t_string1 != NULLCP) {
+           if (strcmp(Xparm1->t_string1, Xparm2->t_string1)) {
+                   (void) printf("%s:t_string1 string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_string1 == NULLCP) {
+           (void) printf("%s: t_string1 decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+
+       if (Xparm1->t_pe != NULLPE && Xparm2->t_pe != NULLPE) {
+           if (bit_cmp(Xparm1->t_pe, Xparm2->t_pe)) {
+                   (void) printf("%s:t_pe bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_pe == NULLPE) {
+           (void) printf("%s: t_pe decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_pe1 != NULLPE && Xparm2->t_pe1 != NULLPE) {
+           if (bit_cmp(Xparm1->t_pe1, Xparm2->t_pe1)) {
+                   (void) printf("%s:t_pe1 bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_pe1 == NULLPE) {
+           (void) printf("%s: t_pe1 decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_S_COMPD:
+#define Xparm1 ((struct pepy_refs1 *)parm1)
+#define Xparm2 ((struct pepy_refs1 *)parm2)
+       if (BITTEST(Xparm1->opt_set, OPT_INT1) != 0
+        && BITTEST(Xparm2->opt_set, OPT_INT1) != 0) {
+           if (Xparm1->t_int != Xparm2->t_int) {
+               d++;
+               (void) printf("%s: t_int mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_int, Xparm2->t_int);
+           }
+       } else if (BITTEST(Xparm1->opt_set, OPT_INT1) != 0
+               || BITTEST(Xparm2->opt_set, OPT_INT1) != 0) {
+           d++;
+           (void) printf("%s: t_int missing %d != %d\n", t_case[tynum].tst_name,
+               Xparm1->opt_set, Xparm2->opt_set);
+       }
+
+       if (BITTEST(Xparm1->opt_set, OPT_INT2) != 0
+        && BITTEST(Xparm2->opt_set, OPT_INT2) != 0) {
+           if (Xparm1->t_int1 != Xparm2->t_int1) {
+               d++;
+               (void) printf("%s: t_int1 mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_int1, Xparm2->t_int1);
+           }
+       } else if (BITTEST(Xparm1->opt_set, OPT_INT2) != 0
+               || BITTEST(Xparm2->opt_set, OPT_INT2) != 0) {
+           d++;
+           (void) printf("%s: t_int1 missing %d != %d\n", t_case[tynum].tst_name,
+               Xparm1->opt_set, Xparm2->opt_set);
+       }
+
+       if (BITTEST(Xparm1->opt_set, OPT_ENUM1) != 0
+        && BITTEST(Xparm2->opt_set, OPT_ENUM1) != 0) {
+           if (Xparm1->t_enum != Xparm2->t_enum) {
+               d++;
+               (void) printf("%s:t_enum mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_enum, Xparm2->t_enum);
+           }
+       } else if (BITTEST(Xparm1->opt_set, OPT_ENUM1) != 0
+               || BITTEST(Xparm2->opt_set, OPT_ENUM1) != 0) {
+           d++;
+           (void) printf("%s: t_int missing %d != %d\n", t_case[tynum].tst_name,
+               Xparm1->opt_set, Xparm2->opt_set);
+       }
+
+       if (BITTEST(Xparm1->opt_set, OPT_ENUM2) != 0
+        && BITTEST(Xparm2->opt_set, OPT_ENUM2) != 0) {
+           if (Xparm1->t_enum1 != Xparm2->t_enum1) {
+               d++;
+               (void) printf("%s:t_enum1 mismatch %d != %d\n", t_case[tynum].tst_name,
+                   Xparm1->t_enum1, Xparm2->t_enum1);
+           }
+       } else if (BITTEST(Xparm1->opt_set, OPT_ENUM2) != 0
+               || BITTEST(Xparm2->opt_set, OPT_ENUM2) != 0) {
+           d++;
+           (void) printf("%s: t_int missing %d != %d\n", t_case[tynum].tst_name,
+               Xparm1->opt_set, Xparm2->opt_set);
+       }
+
+       for (i = NUMOPT - 1; i >= 0; i--) {
+           if (i != OPT_INT1 && i != OPT_INT2
+           && i != OPT_ENUM1 && i != OPT_ENUM2)
+               continue;
+
+            if (BITTEST(Xparm1->opt_set, i) != BITTEST(Xparm2->opt_set, i)) {
+               d++;
+               (void) printf("%s:t_opt missing optional %d\n",
+                   t_case[tynum].tst_name, i);
+            }
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+#endif
+
+    case TY_ACTION:
+    case TY_REPEAT:
+#define Xparm1 ((struct repeats *)parm1)
+#define Xparm2 ((struct repeats *)parm2)
+       if (ri_cmp(Xparm1->rp_sq1, Xparm2->rp_sq1)) {
+           d++;
+           (void) printf("%s:rp_sq1 mangled\n", t_case[tynum].tst_name);
+       }
+       if (re_cmp(Xparm1->rp_sq2, Xparm2->rp_sq2)) {
+           d++;
+           (void) printf("%s:rp_sq2 mangled\n", t_case[tynum].tst_name);
+       }
+       if (ri_cmp(Xparm1->rp_st1, Xparm2->rp_st1)) {
+           d++;
+           (void) printf("%s:rp_st1 mangled\n", t_case[tynum].tst_name);
+       }
+       if (re_cmp(Xparm1->rp_st2, Xparm2->rp_st2)) {
+           d++;
+           (void) printf("%s:rp_st2 mangled\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->rp_choice != Xparm2->rp_choice) {
+           d++;
+           (void) printf("%s:rp_choice wrong %d != %d\n",
+           t_case[tynum].tst_name, Xparm1->rp_choice, Xparm2->rp_choice);
+       }
+       switch (Xparm1->rp_choice) {
+       case RP_INT:
+           if (Xparm1->rp_int != Xparm2->rp_int) {
+               d++;
+               (void) printf("%s:rp_int wrong %d != %d\n",
+               t_case[tynum].tst_name, Xparm1->rp_int, Xparm2->rp_int);
+           }
+           break;
+
+       case RP_BOOL:
+           if (Xparm1->rp_bool && !Xparm2->rp_bool
+            || !Xparm1->rp_bool && Xparm2->rp_bool) {
+               d++;
+               (void) printf("%s:RP_BOOL wrong %d != %d\n",
+               t_case[tynum].tst_name, Xparm1->rp_bool, Xparm2->rp_bool);
+           }
+           break;
+
+       case RP_OSTRING:
+           if (!Xparm1->rp_ostring) {
+               d++;
+               (void) printf("%s:initial rp_ostring missing\n",
+                   t_case[tynum].tst_name);
+           }
+           if (!Xparm2->rp_ostring) {
+               d++;
+               (void) printf("%s:final rp_ostring missing\n",
+                   t_case[tynum].tst_name);
+           }
+           if (strcmp(Xparm1->rp_ostring, Xparm2->rp_ostring)) {
+               d++;
+               (void) printf("%s:rp_ostring not equal %s != %s\n",
+               t_case[tynum].tst_name, Xparm1->rp_ostring, Xparm2->rp_ostring);
+           }
+           break;
+
+       default:
+               d++;
+               (void) printf("%s:bad choice found\n", t_case[tynum].tst_name);
+               break;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_VPDEFINED:
+#define Xparm1 ((struct pepy_refs *)parm1)
+#define Xparm2 ((struct pepy_refs *)parm2)
+       if (Xparm1->t_int != Xparm2->t_int) {
+           d++;
+           (void) printf("%s: t_int mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->t_int, Xparm2->t_int);
+       }
+
+       if (Xparm1->t_enum != Xparm2->t_enum) {
+           d++;
+           (void) printf("%s:t_enum mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->t_enum, Xparm2->t_enum);
+       }
+
+       if (qb_cmp(Xparm1->t_qbuf, Xparm2->t_qbuf)) {
+               (void) printf("t_qbuf octet string different\n");
+               d++;
+       }
+
+       if (Xparm1->t_bool != Xparm2->t_bool) {
+           d++;
+           (void) printf("%s:t_bool mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->t_bool, Xparm2->t_bool);
+       }
+
+#ifdef PEPSY_REALS
+       /* Horrible floating point test for roughly equal */
+       if (fabs(Xparm1->t_real) < F_SMALL/2) {
+            if (fabs(Xparm1->t_real - Xparm2->t_real) > F_SMALL) {
+               (void) printf("%s:t_real %f != %f\n", t_case[tynum].tst_name,
+                   Xparm1->t_real, Xparm2->t_real);
+               d++;
+           }
+       } else if (fabs((Xparm1->t_real - Xparm2->t_real)/Xparm1->t_real) > F_SMALL) {
+           (void) printf("%s:t_real %f != %f\n", t_case[tynum].tst_name,
+               Xparm1->t_real, Xparm2->t_real);
+           d++;
+       }
+#endif
+       if (Xparm1->t_any != NULLPE && Xparm2->t_any != NULLPE) {
+           if (pe_cmp(Xparm1->t_any, Xparm2->t_any)) {
+               (void) printf("%s:t_any different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       }
+       if (Xparm1->t_oid != NULLOID && Xparm2->t_oid != NULLOID) {
+           if (oid_cmp(Xparm1->t_oid, Xparm2->t_oid)) {
+               (void) printf("%s:t_oid OID different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: t_oid one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_bstring != NULLCP && Xparm2->t_bstring != NULLCP) {
+           if (bitstr_cmp(Xparm1->t_bstring, Xparm1->t_blen,
+               Xparm2->t_bstring, Xparm2->t_blen)) {
+                   (void) printf("%s:t_blen string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_bstring == NULLCP) {
+           (void) printf("%s: t_bstring decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_pe != NULLPE && Xparm2->t_pe != NULLPE) {
+           if (bit_cmp(Xparm1->t_pe, Xparm2->t_pe)) {
+                   (void) printf("%s:t_pe bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->t_pe == NULLPE) {
+           (void) printf("%s: t_pe decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_ostring != NULLCP && Xparm2->t_ostring != NULLCP) {
+           if (Xparm1->t_olen != Xparm2->t_olen) {
+                   (void) printf("%s:t_olen string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           } else if (bcmp(Xparm1->t_ostring, Xparm2->t_ostring,
+               Xparm1->t_olen)) {
+                   (void) printf("%s:t_ostring string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else {
+           (void) printf("%s: t_ostring missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->t_string != NULLCP && Xparm2->t_string != NULLCP) {
+           if (strcmp(Xparm1->t_string, Xparm2->t_string)) {
+                   (void) printf("%s:t_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else {
+           (void) printf("%s: t_string decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_FUNC:
+#define Xparm1 ((struct codedata *)parm1)
+#define Xparm2 ((struct codedata *)parm2)
+       if (Xparm1->cd_a != NULLPE && Xparm2->cd_a != NULLPE) {
+           if (pe_cmp(Xparm1->cd_a, Xparm2->cd_a)) {
+               (void) printf("%s:cd_a different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: cd_a missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_b != NULLPE && Xparm2->cd_b != NULLPE) {
+           if (pe_cmp(Xparm1->cd_b, Xparm2->cd_b)) {
+               (void) printf("%s:cd_b different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: cd_b missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_c != NULLPE && Xparm2->cd_c != NULLPE) {
+           if (pe_cmp(Xparm1->cd_c, Xparm2->cd_c)) {
+               (void) printf("%s:cd_c different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: cd_c missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_d != NULLPE && Xparm2->cd_d != NULLPE) {
+           if (pe_cmp(Xparm1->cd_d, Xparm2->cd_d)) {
+               (void) printf("%s:cd_d different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: cd_d missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_int != Xparm2->cd_int) {
+           d++;
+           (void) printf("%s:cd_int mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->cd_int, Xparm2->cd_int);
+       }
+
+       if (Xparm1->cd_string != NULLCP && Xparm2->cd_string != NULLCP) {
+           if (strcmp(Xparm1->cd_string, Xparm2->cd_string)) {
+                   (void) printf("%s:cd_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else {
+           (void) printf("%s: cd_string missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_left && Xparm2->cd_left ) {
+           d += tcmp(TY_OPTFUNC, (char *)Xparm1->cd_left,
+               (char *)Xparm2->cd_left);
+       } else if (Xparm1->cd_left || Xparm2->cd_left) {
+           d++;
+           (void) printf("%s:cd_left missing\n", t_case[tynum].tst_name);
+       }
+       if (Xparm1->cd_right && Xparm2->cd_right ) {
+           d += tcmp(TY_DFTFUNC, (char *)Xparm1->cd_right,
+               (char *)Xparm2->cd_right);
+       } else if (Xparm1->cd_right || Xparm2->cd_right) {
+           d++;
+           (void) printf("%s:cd_right missing\n", t_case[tynum].tst_name);
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_OPTFUNC:
+#define Xparm1 ((struct codedata *)parm1)
+#define Xparm2 ((struct codedata *)parm2)
+       if (Xparm1->cd_a != NULLPE && Xparm2->cd_a != NULLPE) {
+           if (pe_cmp(Xparm1->cd_a, Xparm2->cd_a)) {
+               (void) printf("%s:cd_a different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else if (Xparm1->cd_a != NULLPE || Xparm2->cd_a != NULLPE) {
+           (void) printf("%s: cd_a missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_b != NULLPE && Xparm2->cd_b != NULLPE) {
+           if (pe_cmp(Xparm1->cd_b, Xparm2->cd_b)) {
+               (void) printf("%s:cd_b different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else if (Xparm1->cd_b != NULLPE || Xparm2->cd_b != NULLPE) {
+           (void) printf("%s: cd_b missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       for (i = NCD_OPT - 1; i >= 0; i--) {
+            if (BITTEST(Xparm1->cd_opt_set, i)
+              != BITTEST(Xparm2->cd_opt_set, i)) {
+               d++;
+               (void) printf("%s: flag bit %d differs\n",
+                       t_case[tynum].tst_name, i);
+            }
+       }
+       if (BITTEST(Xparm1->cd_opt_set, CD_C)) {
+           if (Xparm1->cd_c != NULLPE && Xparm2->cd_c != NULLPE) {
+               if (pe_cmp(Xparm1->cd_c, Xparm2->cd_c)) {
+                   (void) printf("%s:cd_c different\n",t_case[tynum].tst_name);
+                   d++;
+               }
+           } else {
+               (void) printf("%s: cd_c missing\n", t_case[tynum].tst_name);
+               d++;
+           }
+       }
+       if (BITTEST(Xparm1->cd_opt_set, CD_D)) {
+           if (Xparm1->cd_d != NULLPE && Xparm2->cd_d != NULLPE) {
+               if (pe_cmp(Xparm1->cd_d, Xparm2->cd_d)) {
+                   (void) printf("%s:cd_d different\n",t_case[tynum].tst_name);
+                   d++;
+               }
+           } else {
+               (void) printf("%s: cd_d missing\n", t_case[tynum].tst_name);
+               d++;
+           }
+       }
+
+       if (BITTEST(Xparm1->cd_opt_set, CD_INT)) {
+           if (Xparm1->cd_int != Xparm2->cd_int) {
+               d++;
+               (void) printf("%s:cd_int mismatch %d != %d",
+                   t_case[tynum].tst_name, Xparm1->cd_int, Xparm2->cd_int);
+           }
+       }
+
+       if (Xparm1->cd_string != NULLCP && Xparm2->cd_string != NULLCP) {
+           if (strcmp(Xparm1->cd_string, Xparm2->cd_string)) {
+                   (void) printf("%s:cd_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm1->cd_string != NULLCP || Xparm2->cd_string != NULLCP) {
+           (void) printf("%s: cd_string missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+    case TY_DFTFUNC:
+#define Xparm1 ((struct codedata *)parm1)
+#define Xparm2 ((struct codedata *)parm2)
+       if (Xparm1->cd_a != NULLPE && Xparm2->cd_a != NULLPE) {
+           if (pe_cmp(Xparm1->cd_a, Xparm2->cd_a)) {
+               (void) printf("%s:cd_a different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else if (Xparm1->cd_a != NULLPE || Xparm2->cd_a != NULLPE) {
+           (void) printf("%s: cd_a missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_b != NULLPE && Xparm2->cd_b != NULLPE) {
+           if (pe_cmp(Xparm1->cd_b, Xparm2->cd_b)) {
+               (void) printf("%s:cd_b different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else if (Xparm1->cd_b != NULLPE || Xparm2->cd_b != NULLPE) {
+           (void) printf("%s: cd_b missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       for (i = NCD_OPT - 1; i >= 0; i--) {
+           if (i == CD_INT)
+               continue;
+
+           if (BITTEST(Xparm1->cd_opt_set,i) !=BITTEST(Xparm2->cd_opt_set,i)) {
+               d++;
+               (void) printf("%s: flag bit %d differs\n",
+                   t_case[tynum].tst_name,i);
+           }
+       }
+       if (BITTEST(Xparm1->cd_opt_set, CD_C)) {
+           if (Xparm1->cd_c != NULLPE && Xparm2->cd_c != NULLPE) {
+               if (pe_cmp(Xparm1->cd_c, Xparm2->cd_c)) {
+                   (void) printf("%s:cd_c different\n",t_case[tynum].tst_name);
+                   d++;
+               }
+           } else {
+               (void) printf("%s: cd_c missing\n", t_case[tynum].tst_name);
+               d++;
+           }
+       }
+       if (BITTEST(Xparm1->cd_opt_set, CD_D)) {
+           if (Xparm1->cd_d != NULLPE && Xparm2->cd_d != NULLPE) {
+               if (pe_cmp(Xparm1->cd_d, Xparm2->cd_d)) {
+                   (void) printf("%s:cd_d different\n",t_case[tynum].tst_name);
+                   d++;
+               }
+           } else {
+               (void) printf("%s: cd_d missing\n", t_case[tynum].tst_name);
+               d++;
+           }
+       }
+
+       if (Xparm1->cd_int != Xparm2->cd_int) {
+           d++;
+           (void) printf("%s:cd_int mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->cd_int, Xparm2->cd_int);
+       }
+
+       if (Xparm1->cd_string != NULLCP && Xparm2->cd_string != NULLCP) {
+           if (strcmp(Xparm1->cd_string, Xparm2->cd_string)) {
+                   (void) printf("%s:cd_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else {
+           (void) printf("%s: cd_string missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+
+#ifdef PEPSY_REALS
+    case TY_ASIMPLE:
+#define Xparm1 ((struct codedata *)parm1)
+#define Xparm2 ((struct codedata *)parm2)
+       if (Xparm1->cd_a != NULLPE && Xparm2->cd_a != NULLPE) {
+           if (pe_cmp(Xparm1->cd_a, Xparm2->cd_a)) {
+               (void) printf("%s:cd_a different\n", t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: cd_a missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_int != Xparm2->cd_int) {
+           d++;
+           (void) printf("%s:cd_int mismatch %d != %d", t_case[tynum].tst_name,
+               Xparm1->cd_int, Xparm2->cd_int);
+       }
+
+       if (Xparm1->cd_string != NULLCP && Xparm2->cd_string != NULLCP) {
+           if (strcmp(Xparm1->cd_string, Xparm2->cd_string)) {
+                   (void) printf("%s:cd_string string different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else {
+           (void) printf("%s: cd_string missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_bool && !Xparm2->cd_bool
+        || !Xparm1->cd_bool && Xparm2->cd_bool) {
+           d++;
+           (void) printf("%s:cd_bool wrong %d != %d\n",
+               t_case[tynum].tst_name, Xparm1->cd_bool, Xparm2->cd_bool);
+       }
+       /* Horrible floating point test for roughly equal */
+       if (fabs(Xparm1->cd_real) < F_SMALL/2) {
+            if (fabs(Xparm1->cd_real - Xparm2->cd_real) > F_SMALL) {
+               (void) printf("%s:cd_real %f != %f\n", t_case[tynum].tst_name,
+                   Xparm1->cd_real, Xparm2->cd_real);
+               d++;
+           }
+       } else if (fabs((Xparm1->cd_real - Xparm2->cd_real)/Xparm1->cd_real)
+               > F_SMALL) {
+           (void) printf("%s:cd_real %f != %f\n", t_case[tynum].tst_name,
+               Xparm1->cd_real, Xparm2->cd_real);
+           d++;
+       }
+       if (Xparm1->cd_oid != NULLOID && Xparm2->cd_oid != NULLOID) {
+           if (oid_cmp(Xparm1->cd_oid, Xparm2->cd_oid)) {
+               (void) printf("%s:cd_oid OID different\n",
+                   t_case[tynum].tst_name);
+               d++;
+           }
+       } else {
+           (void) printf("%s: cd_oid one missing\n", t_case[tynum].tst_name);
+           d++;
+       }
+       if (Xparm1->cd_bit != NULLPE && Xparm2->cd_bit != NULLPE) {
+           if (bit_cmp(Xparm1->cd_bit, Xparm2->cd_bit)) {
+                   (void) printf("%s:cd_bit bitstring different\n",
+                       t_case[tynum].tst_name);
+                   d++;
+           }
+       } else if (Xparm2->cd_bit == NULLPE) {
+           (void) printf("%s: cd_bit decoded version missing\n",
+               t_case[tynum].tst_name);
+           d++;
+       }
+       break;
+#undef Xparm1
+#undef Xparm2
+#endif
+
+    default:
+       ferrd(1, "tcmp:unknown type %d\n", tynum);
+    }
+    if (d) {
+           (void) printf("tcmp:failed on %s\n", t_case[tynum].tst_name);
+    }
+    return (d);
+}
+
+/*
+ * Compare two possible null qbuf lists and return non zero if they are
+ * different
+ * Pretty complex to allow for all sorts of weird cases
+ * Doesn't work for a qbuf which doesn't have a head ! Don't really know what
+ * is the proper form of a queue buf. MArshall's doco doesn't say
+ */
+qb_cmp(qb1, qb2)
+struct qbuf    *qb1, *qb2;
+{
+    struct     qbuf    *qp1, *qp2;
+    char       *po1, *po2;
+    int        len1, len2;
+
+    if (qb1 == NULL && qb2 == NULL)
+       return (0);
+    
+    if (qb1 == NULL || qb2 == NULL)
+       return (1);
+
+    qp1 = qb1->qb_forw;
+    qp2 = qb2->qb_forw;
+    po1 = qp1->qb_data;
+    po2 = qp2->qb_data;
+    len1 = qp1->qb_len;
+    len2 = qp2->qb_len;
+
+    while (qp1 != qb1 && qp2 != qb2) {
+       if (len1 < len2) {
+           if (bcmp(po1, po2, len1))
+                   return (1);
+           len2 -= len1;
+           po2 += len1;
+           qp1 = qp1->qb_forw;
+           po1 = qp1->qb_data;
+           len1 = qp1->qb_len;
+       } else {
+           if (bcmp(po1, po2, len1))
+                   return (1);
+           len1 -= len2;
+           po1 += len2;
+           qp2 = qp2->qb_forw;
+           po2 = qp2->qb_data;
+           len2 = qp2->qb_len;
+       }
+    }
+
+    if (len1 == 0)
+           qp1 = qp1->qb_forw;
+    if (len2 == 0)
+           qp2 = qp2->qb_forw;
+    while (qp1 != qb1 && qp1->qb_len == 0)
+           qp1 = qp1->qb_forw;
+    while (qp2 != qb2 && qp2->qb_len == 0)
+           qp2 = qp2->qb_forw;
+    if (qp1 == qb1 && qp2 == qb2)
+       return (0);     /* perfect match */
+
+    return (1);
+}
+
+/*
+ * compare two bitstrings. Including the little bits left at the end but
+ * not the bits not in the strings
+ */
+bit_cmp(b1, b2)
+PE     b1, b2;
+{
+       int     len1, len2;
+       register char   *cp1, *cp2;
+
+       if (b1 == NULLPE && b2 == NULLPE)
+           return (0);
+       if (b1 == NULLPE || b2 == NULLPE)
+           goto fail;
+
+       if ((cp1 = bitstr2strb(b1, &len1)) == NULL)
+           goto fail;
+       if ((cp2 = bitstr2strb(b2, &len2)) == NULL) {
+           free(cp1);
+           goto fail;
+       }
+
+       if (len1 != len2 || bcmp(cp1, cp2, len1/8)) {
+           free(cp1);
+           free(cp2);
+           goto fail;
+       }
+
+       if (len1 % 8) {
+               int i;
+               int     mask;
+
+               /* Check those last few bits */
+               i = len1/8;
+               mask = (0xff00 >> len1 % 8) & 0xff;
+               if ((cp1[i] & mask) != (cp2[i] & mask)) {
+                   free(cp1);
+                   free(cp2);
+                   goto fail;
+               }
+       }
+
+       free(cp1);
+       free(cp2);
+       return (0);
+
+    fail:
+       return (1);
+}
+
+/*
+ * compare to strings of given number of bits for equality
+ */
+bitstr_cmp(cp1, len1, cp2, len2)
+char   *cp1, *cp2;
+int    len1, len2;
+{
+    int i;
+    int        mask;
+
+    if (len1 != len2 || bcmp(cp1, cp2, len1/8))
+       return (1);
+    
+    if (len1 % 8) {
+
+       /* Check those last few bits */
+       i = len1/8;
+       mask = (0xff00 >> len1 % 8) & 0xff;
+       if ((cp1[i] & mask) != (cp2[i] & mask)) {
+           return (1);
+       }
+    }
+    return (0);
+}
+
+#define MKMASK 0x7
+#define MKSHIFT 6
+/*
+ * Generate a randomish list of PElement s for use as ANY or SET  OF ANY ....
+ */
+PE
+mkpelist(i)
+{
+    PE pe, fpe = NULL;
+
+    fpe = pe_alloc(PE_CLASS_PRIV, PE_FORM_CONS, (PElementID ) i);
+    while (i > 0) {
+       pe = mkpe(i);
+       pe->pe_next = fpe->pe_cons;
+       fpe->pe_cons = pe;
+       i--;
+    }
+    return (fpe);
+}
+
+/*
+ * generate a randomish PElement
+ */
+PE
+mkpe(i)
+int    i;
+{
+    int        id, class;
+    PE         pe;
+
+    id = i * i + 1;
+    class = PE_CLASS_PRIV;
+    switch ((i*i >> MKSHIFT) & MKMASK) {
+    case 5:
+    case 0:
+       pe = flag2prim(i & 0x1, (PElementClass ) class, (PElementID ) id);
+       break;
+    
+    case 6:
+    case 1:
+       pe = num2prim((integer )i, (PElementClass ) class, (PElementID ) id);
+       break;
+
+    case 7:
+    case 2:
+       pe = str2prim("mkpelist:testdata", 17, (PElementClass ) class,
+       (PElementID ) id);
+       break;
+
+    case 3:
+       pe = strb2bitstr("\021\0245\375\0124", 4,
+           (PElementClass ) class, (PElementID ) id);
+       break;
+    
+    case 4:
+       pe = mkpelist(i - 1);
+       break;
+
+    default:
+       ferrd(1, "mkpelist:internal error %d case not handled\n",
+           (i*i >> MKSHIFT) & MKMASK);
+    }
+
+    return (pe);
+}
+
+#define OID_SIZE       6
+/*
+ * make an OID for testing
+ */
+OID
+mkoid(i)
+int    i;
+{
+    OID        oid;
+    int        oid_cnt = i % OID_SIZE;
+
+    if ((oid = new(struct OIDentifier)) == NULL) {
+       (void) printf("mkoid:calloc did not work\n");
+       return NULL;
+    }
+    if (oid_cnt < 2)
+       oid_cnt = 2;    /* At least two integers long */
+    oid->oid_nelem = oid_cnt;
+    if ((oid->oid_elements =
+        (unsigned int *)calloc((unsigned ) oid_cnt, sizeof (int))) == NULL) {
+       (void) printf("mkoid:calloc 2 did not work\n");
+       return NULL;
+    }
+    while (oid_cnt > 2) {
+       oid->oid_elements[oid_cnt - 1] = oid_cnt*i + 33;
+        oid_cnt--;
+    }
+
+    oid->oid_elements[0] = 1;
+    oid->oid_elements[1] = 17;
+
+
+    return (oid);
+}
+
+/*
+ * Produce an External structure initialised to test values
+ * for testing EXTERNAL encoding routines
+ */
+struct type_UNIV_EXTERNAL *
+mkext(i)
+int    i;
+{
+    int        k;
+    struct type_UNIV_EXTERNAL *p;
+
+    k = i + 2;
+    k *= k;    /* generate a more random looking number */
+    k %= 51; /* Keep it in a reasonable bounds to avoid overflow */
+    if ((p = new(struct type_UNIV_EXTERNAL)) == NULL
+    || (p->encoding = new(struct choice_UNIV_0)) == NULL)
+       ferr(1, "mkext:malloc:out of memory\n");
+    
+    if (i & 0x1)
+       p->direct__reference = mkoid(i*3);
+    
+    p->indirect__reference = k & 0x7c;
+
+    p->data__value__descriptor = str2qb("A very wild type of data", 25, 1);
+
+    switch (p->encoding->offset = (k % choice_UNIV_0_arbitrary) + 1) {
+
+    case choice_UNIV_0_arbitrary:
+       p->encoding->un.single__ASN1__type = mkpe(k % 7);
+       break;
+
+    case choice_UNIV_0_single__ASN1__type:
+       p->encoding->un.single__ASN1__type = mkpe(k % 5);
+       break;
+
+    case choice_UNIV_0_octet__aligned:
+       p->encoding->un.octet__aligned = str2qb("Some test data", 15, 1);
+       break;
+
+    default:
+       ferrd(1, "mkext:internal error: bad offset %d\n", p->encoding->offset);
+
+    }
+
+    return (p);
+}
+
+/*
+ * compare two external types to see if they are identical - return zero if
+ * they are and non zero if they are different
+ */
+ext_cmp(e1, e2)
+register struct      type_UNIV_EXTERNAL *e1, *e2;
+{
+     if (e1->direct__reference != NULLOID && e2->direct__reference != NULLOID) {
+        if (oid_cmp(e1->direct__reference, e2->direct__reference))
+               return (1);
+    } else {
+       if (e1->direct__reference != NULLOID || e2->direct__reference != NULLOID)
+           return (1);
+       if (e1->indirect__reference != e2->indirect__reference)
+           return (1);
+    }
+     if (e1->data__value__descriptor != NULLQB
+     && e2->data__value__descriptor != NULLQB) {
+        if (qb_cmp(e1->data__value__descriptor, e2->data__value__descriptor))
+               return (1);
+    } else if (e1->data__value__descriptor != NULLQB
+       || e2->data__value__descriptor != NULLQB)
+           return (1);
+    if (e1->encoding == NULL || e2->encoding == NULL)
+       return (1);
+    if (e1->encoding->offset != e2->encoding->offset)
+       return (1);
+    switch (e1->encoding->offset) {
+    case choice_UNIV_0_single__ASN1__type:
+        if (e1->encoding->un.single__ASN1__type == NULLPE
+        || e2->encoding->un.single__ASN1__type == NULLPE)
+            return (1);
+        if (pe_cmp(e1->encoding->un.single__ASN1__type,
+            e2->encoding->un.single__ASN1__type))
+           return (1);
+       break;
+
+    case choice_UNIV_0_octet__aligned:
+        if (e1->encoding->un.octet__aligned == NULLQB
+        || e2->encoding->un.octet__aligned == NULLQB)
+            return (1);
+        if (qb_cmp(e1->encoding->un.octet__aligned,
+            e2->encoding->un.octet__aligned))
+           return (1);
+       break;
+
+    case choice_UNIV_0_arbitrary:
+        if (e1->encoding->un.arbitrary == NULLPE
+        || e2->encoding->un.arbitrary == NULLPE)
+            return (1);
+        if (pe_cmp(e1->encoding->un.arbitrary,
+            e2->encoding->un.arbitrary))
+           return (1);
+       break;
+
+    default:
+       ferrd(1, "ext_cmp:illegal offset value %d\n", e1->encoding->offset);
+    }
+
+    return (0);
+}
+/*
+ * print the PE structure pointed to by pe
+ */
+print_pe(pe, n)
+PE      pe;
+int     n;
+{
+
+    if (pe == NULL)
+       return;
+    (void) printf("%*s", 4 * n, "");
+    if (pe->pe_errno)
+       (void) printf(" errno = %d", pe->pe_errno);
+    if (pe->pe_class == PE_CLASS_UNIV)
+       (void) printf(" %s", idname( (int )pe->pe_id));
+    else if (pe->pe_class == PE_CLASS_CONT)
+       (void) printf("[%d]", pe->pe_id);
+    else
+       (void) printf("[%s %d]", clname( (int )pe->pe_class), pe->pe_id);
+
+    (void) printf("\n");
+
+    if (pe->pe_form != 0x0) {
+       if (pe->pe_cons != NULLPE)
+           print_pe(pe->pe_cons, n + 1);
+    } else {
+       (void) printf("%*s", 4 * n, "");
+       switch (pe->pe_id) {
+       case PE_PRIM_BOOL:
+           (void) printf("%d", prim2flag(pe));
+           break;
+
+       case PE_PRIM_INT:
+           (void) printf(" %d", prim2num(pe));
+           break;
+       case PE_PRIM_BITS:
+           prntbits(pe);
+           break;
+
+       case PE_PRIM_OCTS:
+           (void) prntos(pe);
+           break;
+
+       case PE_PRIM_NULL:
+           break;
+
+
+       case PE_DEFN_NUMS:
+       case PE_DEFN_PRTS:
+       case PE_DEFN_T61S:
+       case PE_DEFN_VTXS:
+       case PE_DEFN_IA5S:
+       case PE_DEFN_GFXS:
+       case PE_DEFN_VISS:
+       case PE_DEFN_GENS:
+       case PE_DEFN_CHRS:
+           (void) prntstr(pe);
+           break;
+
+
+       case PE_PRIM_OID:
+       case PE_CONS_EXTN:
+       case PE_PRIM_REAL:
+       case PE_PRIM_ENUM:
+       case PE_PRIM_ENCR:
+
+       case PE_CONS_SEQ:
+       case PE_CONS_SET:
+
+       case PE_DEFN_UTCT:
+       case PE_DEFN_GENT:
+       default:
+           (void) printf("Unimplemented %d ", pe->pe_id);
+           break;
+       }
+       (void) printf("\n");
+    }
+    if (pe->pe_next != NULLPE) {
+       (void) printf("%*s", 4 * n, "pe_next:\n");
+       print_pe(pe->pe_next, n);
+    }
+}
+
+/*
+ * return the string describing that class
+ */
+static char   *
+clname(cl)
+int     cl;
+{
+    char   *p;
+    static char buf[30];
+
+    switch (cl) {
+    case PE_CLASS_UNIV:
+       p = "Universal";
+       break;
+
+    case PE_CLASS_APPL:
+       p = "Application";
+       break;
+
+    case PE_CLASS_CONT:
+       p = "Context";
+       break;
+
+    case PE_CLASS_PRIV:
+       p = "Private";
+       break;
+
+    default:
+       (void) sprintf(buf, "Unknown Class %d", cl);
+       p = buf;
+       break;
+    }
+    return (p);
+}
+
+
+/*
+ * return the string describing that identity or the number itself
+ * Assuming a Universal class
+ */
+static char   *
+idname(id)
+int     id;
+{
+    char   *p;
+    static char buf[40];
+
+    switch (id) {
+    case PE_PRIM_BOOL:
+       p = "Boolean";
+       break;
+
+    case PE_PRIM_INT:
+       p = "Integer";
+       break;
+
+    case PE_PRIM_BITS:
+       p = "Bit String";
+       break;
+
+    case PE_PRIM_OCTS:
+       p = "Octet String";
+       break;
+
+    case PE_PRIM_NULL:
+       p = "Null";
+       break;
+
+    case PE_PRIM_OID:
+       p = "Object Descriptor";
+       break;
+
+    case PE_CONS_EXTN:
+       p = "External";
+       break;
+
+    case PE_PRIM_REAL:
+       p = "Real";
+       break;
+
+    case PE_PRIM_ENUM:
+       p = "Enumerated Type";
+       break;
+
+    case PE_PRIM_ENCR:
+       p = "Encrypted Type";
+       break;
+
+    case PE_CONS_SEQ:
+       p = "Sequence";
+       break;
+
+    case PE_CONS_SET:
+       p = "Set";
+       break;
+
+    case PE_DEFN_NUMS:
+       p = "Numeric String";
+       break;
+
+    case PE_DEFN_PRTS:
+       p = "Printable String";
+       break;
+
+    case PE_DEFN_T61S:
+       p = "T.61 String";
+       break;
+
+    case PE_DEFN_VTXS:
+       p = "Videotex String";
+       break;
+
+    case PE_DEFN_IA5S:
+       p = "IA5 String";
+       break;
+
+    case PE_DEFN_UTCT:
+       p = "UTC Time";
+       break;
+
+    case PE_DEFN_GENT:
+       p = "Generalised Time";
+       break;
+
+    case PE_DEFN_GFXS:
+       p = "Graphics String";
+       break;
+
+    case PE_DEFN_VISS:
+       p = "Visable String";
+       break;
+
+    case PE_DEFN_GENS:
+       p = "General String";
+       break;
+
+    case PE_DEFN_CHRS:
+       p = "Character String";
+       break;
+
+    default:
+       (void) sprintf(buf, "Unknown Universal %d", id);
+       p = buf;
+       break;
+    }
+    return (p);
+}
+/*
+ * Print out the value of a bits string
+ */
+static prntbits(pe)
+PE      pe;
+{
+    int     len, i;
+
+    if ((len = pe->pe_nbits) < 0) {
+       (void) printf("prntbits:Bad bistring\n");
+       return;
+    }
+    (void) printf("Bits:");
+    for (i = 0; i < len; i++)
+       if (bit_test(pe, i))
+           (void) printf(" %d", i);
+
+    (void) putchar('\n');
+}
+
+/*
+ * Dump a bunch of hex digits printing out those that are printable
+ * Print out a given length of octets as hex (with the ASCII
+ * characters given if they have any
+ */
+static pclen(s, len)
+register char *s;
+register int len;
+{
+    register int cnt = 0;
+
+    while (len-- > 0) {
+       if (cnt % 8 == 0)
+           (void) printf("\n%d:", cnt / 8 + 1);
+       if (isprint(*s & 0x7f))
+           (void) printf("\t%02x(%c)", *s & 0xff, *s & 0x7f);
+       else
+           (void) printf("\t%02x", *s & 0xff);
+       s++;
+       cnt++;
+    }
+    (void) putchar('\n');
+}
+
+/*
+ * print out an octet string
+ */
+static prntos(pe)
+PE      pe;
+{
+    struct qbuf *qb;
+
+    if ((qb = prim2qb(pe)) == NULL) {
+bad:
+       (void) printf("prntos:bad octet string\n");
+       return (NOTOK);
+    }
+    if (qb_pullup(qb) == NOTOK)
+       goto bad;
+
+    if (qb->qb_forw->qb_data == NULL || qb->qb_forw->qb_len < 0)
+       goto bad;
+
+    pclen(qb->qb_forw->qb_data, qb->qb_forw->qb_len);
+    return (OK);
+}
+
+/*
+ * print out a string which should be printable
+ */
+static prntstr(pe)
+PE      pe;
+{
+    struct qbuf *qb;
+
+    if ((qb = prim2qb(pe)) == NULL) {
+bad:
+       (void) printf("prntstr:bad string\n");
+       return (NOTOK);
+    }
+    if (qb_pullup(qb) == NOTOK)
+       goto bad;
+
+    if (qb->qb_forw->qb_data == NULL || qb->qb_forw->qb_len < 0)
+       goto bad;
+
+    (void) printf("\"%s\"", qb->qb_forw->qb_data);
+    return (OK);
+}
+
+/*
+ * build a link list of struct rep_int containing the speicified number of
+ * elements
+ */
+struct rep_int *
+mkrep_int(cnt)
+int    cnt;
+{
+    struct rep_int     *hd, *tl, *p;
+
+    for (hd = NULLREP_INT, tl = NULL; cnt-- > 0; ) {
+       if ((p = new(struct rep_int)) == NULLREP_INT)
+           ferr(1, "mkrep_int:malloc failed\n");
+       
+       p->i = t_test*cnt + 3;
+       if (tl) {
+           tl->r = p;
+           tl = p;
+       } else
+           hd = tl = p;
+    }
+
+    return (hd);
+}
+
+static char *test_str[] = { "The quick", "brown", "fox jumps over",
+                           "The Lazy", "dog", 0 };
+
+/*
+ * build a link list of struct rep_elem containing the speicified number of
+ * elements
+ */
+struct rep_elem        *
+mkrep_elem(cnt)
+int    cnt;
+{
+    struct rep_elem    *hd, *tl, *p;
+    char       **str;
+
+    for (str = test_str, hd = NULLREP_ELEM, tl = NULL; cnt-- > 0; ) {
+       if ((p = new(struct rep_elem)) == NULLREP_ELEM)
+           ferr(1, "mkrep_elem:malloc failed\n");
+       
+       if (*str == NULLCP)
+           str = test_str;
+       
+       p->r_int = t_test + cnt + 3;
+       p->r_ostring = strdup(*str++);
+       p->r_bstring = strdup("1234567890abcdefghijklmnopqrstuvwxyz");
+       if (tl) {
+           tl->r_next = p;
+           tl = p;
+       } else
+           hd = tl = p;
+    }
+
+    return (hd);
+}
+
+/*
+ * return non zero if the to lists are different - also
+ * prints a message about the difference found
+ */
+ri_cmp(p1, p2)
+struct rep_int *p1, *p2;
+{
+    int        cnt;
+
+
+    for (cnt = 1; p1 && p2; cnt++) {
+       if (p1->i != p2->i) {
+           (void) printf("ri_cmp: Integers differ in %d item (%d != %d)\n",
+               cnt, p1->i, p2->i);
+           return (1);
+       }
+       p1 = p1->r;
+       p2 = p2->r;
+    }
+    if (p1) {
+       (void) printf("ri_cmp: 1st list has more items (> %d)\n", cnt);
+       return(1);
+    }
+    if (p2) {
+       (void) printf("ri_cmp: 2nd list has more items (> %d)\n", cnt);
+       return(1);
+    }
+
+    return (0);
+}
+
+/*
+ * return non zero if the to lists are different - also
+ * prints a message about the difference found
+ */
+re_cmp(p1, p2)
+struct rep_elem        *p1, *p2;
+{
+    int        cnt;
+
+
+    for (cnt = 1; p1 && p2; cnt++) {
+       if (p1->r_int != p2->r_int) {
+           (void) printf("re_cmp: Integers differ in %d item (%d != %d)\n",
+               cnt, p1->r_int, p2->r_int);
+           return (1);
+       }
+       if (strcmp(p1->r_ostring, p2->r_ostring)) {
+           (void) printf("re_cmp: strings differ in %d item (%s != %s)\n",
+               cnt, p1->r_ostring, p2->r_ostring);
+           return (1);
+       }
+       if (bitscmp(p1->r_bstring, p2->r_bstring, p1->r_int)) {
+           (void) printf("re_cmp: bit strings differ in %d item\n", cnt);
+           return (1);
+       }
+       p1 = p1->r_next;
+       p2 = p2->r_next;
+    }
+    if (p1) {
+       (void) printf("re_cmp: 1st list has more items (> %d)\n", cnt);
+       return(1);
+    }
+    if (p2) {
+       (void) printf("re_cmp: 2nd list has more items (> %d)\n", cnt);
+       return(1);
+    }
+
+    return (0);
+}
diff --git a/src/isode/pepsy/mine.h b/src/isode/pepsy/mine.h
new file mode 100644 (file)
index 0000000..83bb8e7
--- /dev/null
@@ -0,0 +1,53 @@
+/* mine.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:50  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:39:42  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:02  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 TABLESIZE 29
+
+typedef struct ID_TABLE {
+       char    *h_value;
+       char    *r_value;
+       int     def_bit;
+       int     def_value;
+       int     count;
+       struct ID_TABLE *next;
+       } id_entry;
+
+typedef struct S_TABLE {
+       char    *name;
+       char    *type;
+       struct S_TABLE  *parent;
+       char    *field;
+       int     defined;
+       struct S_TABLE *next;
+       } s_table;
+
+extern id_entry        *id_table[];
+
+extern char *c_flags();
diff --git a/src/isode/pepsy/mod.c b/src/isode/pepsy/mod.c
new file mode 100644 (file)
index 0000000..69d361b
--- /dev/null
@@ -0,0 +1,173 @@
+/* mod.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:52  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:39:44  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:02  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include "pepsydefs.h"
+#include "pass2.h"
+
+extern char *sysin;
+extern char *proc_name();
+extern char *my_strcat();
+
+char   *calc_arg();
+
+#define MAXLENGTH 30
+
+#ifdef notdef
+/*
+ * output each of the actions associated with yp
+ */
+do_sw_type(name, yp, fp, fpa)
+char   *name;
+YP      yp;
+FILE   *fp;
+FILE   *fpa;
+{
+    char   *s;
+    char   *arg;
+
+    s = proc_name(name, 0);
+    if (yp->yp_action1) {
+       (void) fprintf(fp, "\t\tcase %s%s:\n", s, ACT1);
+       arg = calc_arg(yp, 1);
+       my_do_action(fp, yp->yp_action1, 0, arg, yp->yp_act1_lineno, yp->yp_param_type);
+       (void) fprintf(fp, "\t\t\tbreak;\n");
+    }
+    if (yp->yp_action2) {
+       (void) fprintf(fp, "\t\tcase %s%s:\n", s, ACT2);
+       arg = calc_arg(yp, 2);
+       my_do_action(fp, yp->yp_action2, 0, arg, yp->yp_act2_lineno, yp->yp_param_type);
+       (void) fprintf(fp, "\t\t\tbreak;\n");
+    }
+    if (yp->yp_action05) {
+       (void) fprintf(fp, "\t\tcase %s%s:\n", s, ACT05);
+       arg = calc_arg(yp, 5);
+       my_do_action(fp, yp->yp_action05, 0, arg, yp->yp_act05_lineno, yp->yp_param_type);
+       (void) fprintf(fp, "\t\t\tbreak;\n");
+    }
+}
+#endif
+
+my_do_action(fp, action, level, arg, lineno, new)
+FILE   *fp;
+char   *action;
+int     level;
+char   *arg;
+int     lineno;
+char   *new;
+{
+    int     i;
+    char    t[MAXLENGTH];
+    char    c, d;
+
+    (void) fprintf(fp, "%*s{\n", level * 4, "");
+    Printf(4, ("\n"));
+
+    if (*sysin)
+       (void) fprintf(fp, "# line %d \"%s\"\n", lineno, sysin);
+
+    for (d = NULL; c = *action; d = c, action++) {
+       Printf(4, ("open char is %c\n", *action));
+       for (i = 0; i < MAXLENGTH - 1 && (isalpha(*action) || *action == '_'); action++, i++)
+           t[i] = *action;
+       t[i] = '\0';
+       Printf(4, ("WORD IS %s, %c, %d\n", t, *action, i));
+       if (strcmp(t, "")) {
+           if (!strcmp(t, "parm"))
+               (void) fprintf(fp, "(%s)%s", new, "parm");
+           else
+               (void) fprintf(fp, "%s", t);
+           c = *(action - 1);
+           action--;
+           continue;
+           /*
+            * OR d = *(action - 1); c = *action;
+            */
+       }
+       switch (d) {
+       case '$':
+           if (c == '$') {
+               (void) fprintf(fp, "%s", arg);
+               c = NULL;
+               break;
+           }
+           (void) fputc('$', fp);      /* fall */
+
+       default:
+           if (c != '$')
+               (void) fputc(c, fp);
+           break;
+       }
+    }
+
+    switch (d) {
+    case '\n':
+       break;
+
+    case '$':
+       (void) fputc('$', fp);          /* fall */
+    default:
+       (void) fputc('\n', fp);
+       break;
+    }
+
+    (void) fprintf(fp, "%*s}\n", level * 4, "");
+}
+
+char   *
+calc_arg(yp, actno)
+YP      yp;
+int     actno;
+{
+
+    switch (actno) {
+    case 1:
+       return "";
+
+    case 2:
+       if (yp->yp_direction & YP_ENCODER)
+           return "(pe)";
+       else
+           return "(pe)";
+
+    case 5:
+       if (yp->yp_direction & YP_ENCODER)
+           return "";
+       else
+           return "(pe)";
+    default:
+       return "";
+    }
+}
diff --git a/src/isode/pepsy/pass2.c b/src/isode/pepsy/pass2.c
new file mode 100644 (file)
index 0000000..84b7a57
--- /dev/null
@@ -0,0 +1,1524 @@
+/* pass2.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.2  1994/06/07 23:10:07  eichin
+ * KLUDGE XXX static forward decl for AIX
+ *
+ * Revision 1.1  1994/05/31 20:39:46  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:03  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include "pepsydefs.h"
+#include "pass2.h"
+#include "mine.h"
+#include "sym.h"
+
+extern int doexternals;
+extern int sflag, mflag, fflag, Cflag;
+
+extern char *eval;
+
+extern int Aflag;
+extern SY mysymbols;
+extern char *modsym(), *gfree();
+extern char *my_strcat();
+extern char *notidtoid();
+extern char    *rm_indirect();
+extern char    *getid();
+extern char    *getidordot();
+extern char    *getfield();
+extern char    *sym2type();
+extern YP      lookup_type();
+extern MD      lookup_module ();
+
+char   *tab;   /* mymodule - with - changed to _ */
+
+Action start_action, final_action;
+int    e_actions, d_actions, p_actions; /* number of actions of each type */
+
+FILE   *ffopen();
+
+peri_pass2()
+{
+    char *inc; /* *_pre_defs.h file */
+
+    if (!sflag)
+       (void) fflush(stderr);
+
+    tab = notidtoid(mymodule);
+
+    if (strcmp(mymodule, "UNIV"))
+       (void) lookup_module("UNIV", NULLOID);
+
+    inc = my_strcat (mymodule, HFILE2);
+
+    gen_typesfile(inc);
+
+    gen_tablefile(inc);
+
+}
+static int   ptr_cnt = 0;
+/*
+ * generate the table file which contains:
+ * #include types file
+ * #include - types files for other (external) modules referenced
+ * definitions of data structures used: strings and stuff for defaults
+ *             declaractions of functions referenced.
+ *             tpe tables - one per type assignment for each of
+ *                     encoding, decoding and printing
+ *             tables of pointers to all the above tpe tables - one for
+ *                     type of tpe table
+ *             pointer table - used to hold pointers as tpe table cannot
+ *                hold pointers but only integers which index into this table
+ *             module definition - the key to all the data structures os this
+ *                     module. contains references to all the tables.
+ *             lint declaractions for the "pepy" functions
+ */
+gen_tablefile(inc)
+char   *inc;
+{
+
+    int     nentries;
+    int     encflag = 1, decflag = 1, prntflag = 1;
+    SY      sy;
+    YP      yp;
+    FILE   *fphh, *fptab;
+
+    fptab = ffopen(my_strcat(mymodule, TBLNAME)); /* thing_tables.c */
+
+    /* Only need two files <stdio.h> and our types file which includes
+     * everything else we need
+     * Assumption. types file in the same directory as the _tables
+     */
+    (void) fprintf(fptab, "#include <stdio.h>\n");
+    (void) fprintf(fptab, "#include \"%s%s\"\n\n", mymodule, GENTYPES);
+
+    if (start_action) {
+       (void) fprintf (fptab, "\n# line %d \"%s\"\n",
+                       start_action->a_line ? start_action->a_line : 1,
+                       sysin);
+       fputs (start_action->a_data, fptab);
+    }
+#ifdef _AIX
+    (void) fprintf (fptab, "\nstatic caddr_t %s%s%s[%d];\t/* aix forward decl*/\n",
+                    PREFIX, PTR_TABNAME, tab, 100+ptr_cnt);
+#else
+    (void) fprintf (fptab, "\nextern caddr_t %s%s%s[];\t/* forward decl */\n",
+                   PREFIX, PTR_TABNAME, tab);
+#endif
+    /*
+     * loop through and generate all the default values definitions
+     * and what ever else needs to be processed for all the entries
+     * e.g. external module references and coding function declarations
+     */
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       yp = sy->sy_type;
+       if (yp->yp_flags & YP_IMPORTED)
+           continue;
+       if (yp->yp_direction & (YP_ENCODER | YP_DECODER | YP_PRINTER)
+           || Aflag) {
+           gen_dflts(fptab, sy->sy_type, sy->sy_name);
+       }
+    }
+
+    (void) fprintf(fptab, "\n#define OFFSET(t,f)\t((int ) &(((t *)0)->f))\n\n");
+#ifndef        hpux
+    (void) fprintf(fptab, "\n#define AOFFSET(t,f)\t((int ) (((t *)0)->f))\n\n");
+#else
+    (void) fprintf(fptab, "\n#define AOFFSET(t,f)\t((int ) &(((t *)0)->f[0]))\n\n");
+#endif
+    nentries = 0;
+    /*
+     * generate tpe tables
+     */
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       yp = sy->sy_type;
+       if (yp->yp_flags & YP_IMPORTED)
+           continue;
+       if (yp->yp_direction & YP_ENCODER || Aflag) {
+           nentries++;
+           gen_enctbl(fptab, sy);
+       }
+    }
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       yp = sy->sy_type;
+       if (yp->yp_flags & YP_IMPORTED)
+           continue;
+       if (yp->yp_direction & YP_DECODER || Aflag)
+           gen_dectbl(fptab, sy);
+    }
+
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       yp = sy->sy_type;
+       if (yp->yp_flags & YP_IMPORTED)
+           continue;
+       if (yp->yp_direction & YP_PRINTER || Aflag)
+           gen_prnttbl(fptab, sy);
+    }
+
+    fphh = ffopen(inc); /* thing_pre_defs.h */
+    (void) fprintf(fphh, "\nextern modtyp      %s%s%s;\n",
+           PREFIX, tab, MODTYP_SUFFIX);
+    out_final_defs(fphh);
+    if (fclose(fphh) == EOF) {
+       fprintf (stderr, "Write error to file");
+       perror (inc);
+       exit (1);
+    }
+
+    gen_actfunct(fptab);
+
+    gen_tpe(fptab);  /* generate table of pointers to tpe tables */
+
+    gen_modtype(fptab, nentries, encflag, decflag, prntflag);
+
+    if (final_action) {
+       (void) fprintf (fptab, "\n# line %d \"%s\"\n",
+                       final_action->a_line ? final_action->a_line : 1,
+                       sysin);
+       fputs (final_action->a_data, fptab);
+    }
+
+   gen_lint(fptab);
+
+   if(fclose(fptab) == EOF) {
+       fprintf (stderr, "Write error to file");
+       perror ("");
+       exit (1);
+   }
+}
+
+/*
+ * generate the *-types.h file
+ */
+gen_typesfile(inc)
+char   *inc;
+{
+    char   *buf;
+#ifdef ACT_CODE
+    int     encflag = 1, decflag = 1, prntflag = 1;
+    char *act;
+    FILE   *fpe, *fpd, *fpp, *fpa;
+#endif
+    SY      sy;
+    YP      yp;
+    FILE   *fph;
+
+    fph = ffopen(my_strcat(mymodule, HFILE1)); /* thing_defs.h */
+    if (!Cflag) {
+       if (mflag) {
+           (void) fprintf (fph, "#ifndef\tPEPYPATH\n");
+           (void) fprintf (fph, "#include <isode/pepsy/%s>\n", inc);
+           (void) fprintf (fph, "#else\n");
+           (void) fprintf (fph, "#include \"%s\"\n", inc);
+           (void) fprintf (fph, "#endif\n\n\n");
+       }
+       else {
+           if (is_stand (inc))
+               (void) fprintf (fph, "#include <isode/pepsy/%s>\n", inc);
+           else
+               (void) fprintf (fph, "#include \"%s\"\n", inc);
+       }
+    }
+
+#ifdef ACT_CODE
+    act = my_strcat(mymodule, ACTIONDEFS);
+
+    fpe = ffopen(my_strcat(mymodule, ENCFILENAME));
+    file_header(fpe, act);
+    fpd = ffopen(my_strcat(mymodule, DECFILENAME));
+    file_header(fpd, act);
+    fpp = ffopen(my_strcat(mymodule, PRNTFILENAME));
+    file_header(fpp, act);
+    fpa = ffopen(act);
+#endif
+
+    /* define the macros to support posy functions */
+
+    fprintf(fph, "\n#ifndef\tlint\n");
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       eval = sy->sy_name;
+       yp = sy->sy_type;
+
+       if (sy->sy_module == NULLCP)
+           yyerror("no module name associated with symbol");
+       if (yp->yp_flags & YP_IMPORTED)
+           continue;
+       if (strcmp(sy->sy_module, mymodule)) {
+           fprintf(stderr, "mymodule unsuitable for module name e.g %s and %s(mymodule)\n", sy->sy_module, mymodule);
+           exit(1);
+       }
+       if (yp->yp_direction & YP_ENCODER || Aflag) {
+           buf = modsym (sy -> sy_module, sy -> sy_name, yyencdflt);
+           fprintf(fph, "#define %s", buf);
+           fprintf(fph, "(pe, top, len, buffer, parm) \\\n");
+           fprintf(fph, "    %s(%s%s, ", ENCFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
+           fprintf(fph, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
+           fprintf(fph, "pe, top, len, buffer, (char *) parm)\n\n");
+#ifdef ACT_CODE
+           if (encflag) {
+               fprintf(fpe, "%s%s", ENC_FNCNAME, tab);
+               open_func(fpe);
+               encflag--;
+           }
+#endif
+           if (bflag)
+               init_new_file();
+           if (bflag)
+               end_file();
+       }
+       if (yp->yp_direction & YP_DECODER || Aflag) {
+           buf = modsym (sy -> sy_module, sy -> sy_name, yydecdflt);
+           if (bflag)
+               init_new_file();
+           fprintf(fph, "#define %s", buf);
+           fprintf(fph, "(pe, top, len, buffer, parm) \\\n");
+           fprintf(fph, "    %s(%s%s, ", DECFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
+           fprintf(fph, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
+           fprintf(fph, "pe, top, len, buffer, (char **) parm)\n\n");
+#if ACT_CODE
+           if (decflag) {
+               fprintf(fpd, "%s%s", DEC_FNCNAME, tab);
+               open_func(fpd);
+               decflag--;
+           }
+#endif
+           if (bflag)
+               end_file();
+       }
+       if (yp->yp_direction & YP_PRINTER || Aflag) {
+           buf = modsym (sy -> sy_module, sy -> sy_name, yyprfdflt);
+           if (bflag)
+               init_new_file();
+           fprintf(fph, "#define %s", buf);
+           fprintf(fph, "(pe, top, len, buffer, parm) \\\n");
+           fprintf(fph, "    %s(%s%s, ", PRNTFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
+           fprintf(fph, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
+           fprintf(fph, "pe, top, len, buffer)\n");
+           fprintf(fph, "#define %s_P", buf);
+           fprintf(fph, "    %s%s, ", PREFIX,
+                   proc_name(sy->sy_name, 1));
+           fprintf(fph, "&%s%s%s\n\n", PREFIX, tab, MODTYP_SUFFIX);
+#ifdef  ACT_CODE
+           if (prntflag) {
+               fprintf(fpp, "%s%s", PRNT_FNCNAME, tab);
+               open_func(fpp);
+               prntflag--;
+           }
+#endif
+           if (bflag)
+               end_file();
+       }
+       if (!bflag && ferror(stdout))
+           myyerror("write error - %s", sys_errname(errno));
+    }
+    fprintf(fph, "\n#endif   /* lint */\n");
+
+#ifdef ACT_CODE
+    if (!encflag) {
+       close_func(fpe);
+    }
+    if (!decflag) {
+       close_func(fpd);
+    }
+    if (!prntflag) {
+       close_func(fpp);
+    }
+#endif
+
+    if (fclose(fph) == EOF) {
+       fprintf (stderr, "Write error to file");
+       perror ("");
+       exit (1);
+    }
+#ifdef ACT_CODE
+    fclose(fpe);
+    fclose(fpd);
+    fclose(fpp);
+    fclose(fpa);
+#endif
+}
+
+
+gen_enctbl(fp, sy)
+FILE   *fp;
+SY      sy;
+{
+    YP yp;
+
+    yp = sy->sy_type;
+    fprintf(fp,"static tpe %s%s[] = {\n", ETABLE, proc_name(sy->sy_name, 0));
+    fprintf(fp, "\t{ PE_START, 0, 0, 0 },\n");
+
+    tenc_typ(fp, yp, sy->sy_name, NULLCP);
+
+    fprintf(fp, "\t{ PE_END, 0, 0, 0 }\n");
+    fprintf(fp, "\t};\n");
+    fprintf(fp, "\n");
+}
+
+gen_dectbl(fp, sy)
+FILE   *fp;
+SY      sy;
+{
+    fprintf(fp,"static tpe %s%s[] = {\n", DTABLE, proc_name(sy->sy_name, 0));
+    fprintf(fp, "\t{ PE_START, 0, 0, 0 },\n");
+
+    tdec_typ(fp, sy->sy_type, sy->sy_name, NULLCP);
+
+    fprintf(fp, "\t{ PE_END, 0, 0, 0 }\n");
+    fprintf(fp, "\t};\n");
+    fprintf(fp, "\n");
+}
+
+
+gen_prnttbl(fp, sy)
+FILE   *fp;
+SY      sy;
+{
+    fprintf(fp,"static ptpe %s%s[] = {\n",PTABLE, proc_name(sy->sy_name, 0));
+    fprintf(fp, "\t{ PE_START, 0, 0, 0, (char **)&%s%s%s[%d] },\n",
+           PREFIX, PTR_TABNAME, tab, addsptr(sy->sy_name));
+
+    tprnt_typ(fp, sy->sy_type, sy->sy_name, NULLCP);
+
+    fprintf(fp, "\t{ PE_END, 0, 0, 0, NULLVP }\n");
+    fprintf(fp, "\t};\n");
+    fprintf(fp, "\n");
+}
+
+
+/*
+ * define the tpe index tables and the pointer table
+ */
+gen_tpe(fp)
+FILE   *fp;
+{
+    SY sy;
+    int        empty = 1;
+
+    fprintf(fp, "static tpe *etabl[] = {\n");
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       if (sy->sy_type->yp_flags & YP_IMPORTED)
+           continue;
+       if (sy->sy_type->yp_direction & YP_ENCODER || Aflag) {
+           fprintf(fp, "\t%s%s,\n", ETABLE, proc_name(sy->sy_name, 0));
+           empty = 0;
+       }
+    }
+    if (empty)
+       fprintf(fp, "\t0,\n");
+    fprintf(fp, "\t};\n\n");
+    empty = 1;
+
+    fprintf(fp, "static tpe *dtabl[] = {\n");
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       if (sy->sy_type->yp_flags & YP_IMPORTED)
+           continue;
+       if (sy->sy_type->yp_direction & YP_DECODER || Aflag) {
+           fprintf(fp, "\t%s%s,\n", DTABLE, proc_name(sy->sy_name, 0));
+           empty = 0;
+       }
+    }
+    if (empty)
+       fprintf(fp, "\t0,\n");
+    fprintf(fp, "\t};\n\n");
+    empty = 1;
+
+    fprintf(fp, "static ptpe *ptabl[] = {\n");
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       if (sy->sy_type->yp_flags & YP_IMPORTED)
+           continue;
+       if (sy->sy_type->yp_direction & YP_PRINTER || Aflag) {
+           fprintf(fp, "\t%s%s,\n", PTABLE, proc_name(sy->sy_name, 0));
+           empty = 0;
+       }
+    }
+    if (empty)
+       fprintf(fp, "\t0,\n");
+    fprintf(fp, "\t};\n\n");
+
+    /* produce pointer table */
+    dump_ptrtab(fp);
+}
+
+/*
+ * output the module structure for this module
+ */
+gen_modtype(fp, no, f1, f2, f3)
+FILE   *fp;
+int     no;
+int     f1, f2, f3;
+{
+    if (!f1)
+       fprintf(fp, "extern PE\t%s%s();\n", ENC_FNCNAME, tab);
+    if (!f2)
+       fprintf(fp, "extern PE\t%s%s();\n", DEC_FNCNAME, tab);
+    if (!f3)
+       fprintf(fp, "extern PE\t%s%s();\n", PRNT_FNCNAME, tab);
+    fprintf(fp, "\n");
+    fprintf(fp, "modtyp %s%s%s = {\n", PREFIX, tab, MODTYP_SUFFIX);
+    fprintf(fp, "\t\"%s\",\n", mymodule);      /* name */
+    fprintf(fp, "\t%d,\n", no);                /* number of entries */
+                                       /* coding tables */
+    fprintf(fp, "\tetabl,\n");
+    fprintf(fp, "\tdtabl,\n");
+    fprintf(fp, "\tptabl,\n");
+                                       /* action tables */
+    if (e_actions > 0)
+       fprintf(fp, "\tefn_%s,\n", tab);
+    else
+       fprintf(fp, "\t0,\n");  /* no action code */
+
+    if (d_actions > 0)
+       fprintf(fp, "\tdfn_%s,\n", tab);
+    else
+       fprintf(fp, "\t0,\n");  /* no action code */
+
+    if (p_actions > 0)
+       fprintf(fp, "\tpfn_%s,\n", tab);
+    else
+       fprintf(fp, "\t0,\n");  /* no action code */
+
+    fprintf(fp, "\t%s%s%s,\n", PREFIX, PTR_TABNAME, tab);
+    fprintf(fp, "\t};\n\n");
+}
+
+/*
+ * open a file called name
+ */
+FILE   *
+ffopen(name)
+char   *name;
+{
+    FILE   *fp;
+
+    if ((fp = fopen(name, "w")) == NULL) {
+       fprintf(stderr, "Can't create the file %s", name);
+       exit(1);
+    }
+    return fp;
+}
+
+#ifdef ACT_CODE
+/*
+ * output the file prologue to the file specified by fp
+ */
+file_header(fp, act)
+FILE   *fp;
+char   *act;
+{
+    fprintf(fp, "#include %s\n", PSAP_DOT_H);
+    fprintf(fp, "#include \"%s\"\n", INCFILE1);
+    fprintf(fp, "#include \"%s\"\n", act);
+    fprintf(fp, "#include \"%s%s\"\n\n", mymodule, GENTYPES);
+    fprintf(fp, "#ifndef PEPYPARM\n");
+    fprintf(fp, "#define PEPYPARM char *\n");
+    fprintf(fp, "#endif\n");
+    fprintf(fp, "extern PEPYPARM NullParm;\n\n");
+}
+
+#endif
+
+/*
+ * output the function prologue to the file specified by fp
+ */
+open_func(fp)
+FILE   *fp;
+{
+
+    fprintf(fp, "(pe, parm, p, mod)\n");
+    fprintf(fp, "PE\tpe;\n");
+    fprintf(fp, "PEPYPARM\tparm;\n");
+    fprintf(fp, "tpe\t*p;\n");
+    fprintf(fp, "modtyp\t*mod;\n");
+    fprintf(fp, "{\n");
+    /* action 0 ???? */
+    fprintf(fp, "\tswitch (p->pe_ucode) {\n");
+}
+
+/*
+ * output the function epilogue to the file specified by fp
+ */
+close_func(fp)
+FILE   *fp;
+{
+    fprintf(fp, "\t\tdefault:\n");
+    fprintf(fp, "\t\t\tbreak;\n");
+    fprintf(fp, "\t}\n");
+    fprintf(fp, "\treturn OK;\n}\n\n");
+}
+
+/*
+ * print the table id_table
+ */
+print_table()
+{
+    int     i;
+    id_entry *t;
+
+    for (i = 0; i < TABLESIZE; i++) {
+       for (t = id_table[i]; t != NULL; t = t->next)
+           (void) printf("%s(%d) -->   ", t->r_value, t->def_value);
+       if (id_table[i] != NULL)
+           (void) printf("NULL -- %d\n", i);
+    }
+}
+static struct univ_typ univ_tab[] = {
+    {"EXTERNAL", "struct       type_UNIV_EXTERNAL      *", "EXTERNAL", 8, 0,
+    "UNIV", UNF_EXTMOD|UNF_HASDATA, YP_SEQLIST, },
+    {"GeneralString", "struct  qbuf    *", "OCTETSTRING", 27, 0,
+    "UNIV", 0, YP_OCT, },
+    {"GeneralisedTime", "struct        qbuf    *", "OCTETSTRING", 24, 0,
+    "UNIV", 0, YP_OCT, },
+    {"GeneralizedTime", "struct        qbuf    *", "OCTETSTRING", 24, 0,
+    "UNIV", 0, YP_OCT, },
+    {"GraphicString", "struct  qbuf    *", "OCTETSTRING", 25, 0,
+    "UNIV", 0, YP_OCT, },
+    {"IA5String", "struct      qbuf    *", "OCTETSTRING", 22, 0,
+    "UNIV", 0, YP_OCT, },
+    {"ISO646String", "struct   qbuf    *", "OCTETSTRING", 26, 0,
+    "UNIV", 0, YP_OCT, },
+    {"NumericString", "struct  qbuf    *", "OCTETSTRING", 18, 0,
+    "UNIV", 0, YP_OCT, },
+    {"PrintableString", "struct        qbuf    *", "OCTETSTRING", 19, 0,
+    "UNIV", 0, YP_OCT, },
+    {"TeletexString", "struct  qbuf    *", "OCTETSTRING", 20, 0,
+    "UNIV", 0, YP_OCT, },
+    {"T61String", "struct      qbuf    *", "OCTETSTRING", 20, 0,
+    "UNIV", 0, YP_OCT, },
+    {"UTCTime", "struct        qbuf    *", "OCTETSTRING", 23, 0,
+    "UNIV", 0, YP_OCT, },
+    {"UniversalTime", "struct  qbuf    *", "OCTETSTRING", 23, 0,
+    "UNIV", 0, YP_OCT, },
+    {"VideotexString", "struct qbuf    *", "OCTETSTRING", 21, 0,
+    "UNIV", 0, YP_OCT, },
+    {"VisibleString", "struct  qbuf    *", "OCTETSTRING", 26, 0,
+    "UNIV", 0, YP_OCT, },
+};
+
+extern struct univ_typ *simptyp();
+
+/*
+ * Determine wether the type name matches one of the Universal types
+ * which are to be treated specially. If so return a pointer to the
+ * data structure which contains the parameters describing how it
+ * should be processed
+ */
+struct univ_typ *
+univtyp(name)
+char   *name;
+{
+    int     low, high, i;
+    struct univ_typ *p;
+
+    low = 0;
+    high = NENTRIES(univ_tab) - 1;
+    while (low <= high) {
+       p = univ_tab + (low + high) / 2;
+       if ((i = scmp(name, p->univ_name)) == 0)
+           return (p);
+       if (low == high)
+           return (NULL);
+       if (i < 0)
+           high = p - univ_tab - 1;
+       else
+           low = p - univ_tab + 1;
+    }
+
+#if OPTIMISED
+    if ((p = simptyp(name)) == NULL)
+       return (p);
+#endif
+
+    return (NULL);
+}
+
+/*
+ * Compare two strings returning a number representing the character
+ * where they differ or 0 if are the same - I wrote this because I
+ * couldn't trust strcmp to work the same way between numbers and
+ * letters everywhere. longer strings are greater shorter strings
+ * numbers are greater then all letters lower case are greater then
+ * upper case There must be a better way !
+ */
+scmp(s1, s2)
+char   *s1, *s2;
+{
+    while (*s1 == *s2 && *s2)
+       s1++, s2++;
+    if (*s1 == '\0' && *s2 == '\0')
+       return (0);
+    if (*s1 == '\0')
+       return (-1);
+    if (*s2 == '\0')
+       return (1);
+    if (isalpha(*s1) && isalpha(*s2)) {
+       if (isupper(*s1) && isupper(*s2))
+           return (*s1 - *s2);
+       if (islower(*s1) && islower(*s1))
+           return (*s1 - *s2);
+       if (isupper(*s1))
+           return (-1);
+       if (islower(*s1))
+           return (1);
+    }
+    if (isdigit(*s1) && isdigit(*s2))
+       return (*s1 - *s2);
+    if (isdigit(*s1))
+       return (1);
+    if (isdigit(*s2))
+       return (-1);
+    return (*s1 - *s2);
+}
+
+/*
+ * lookup a symbol and return a pointer to it
+ */
+SY
+syfind(name)
+char   *name;
+{
+    SY      sy;
+
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       if (sy->sy_type->yp_flags & YP_IMPORTED)
+           continue;
+       if (strcmp(name, sy->sy_name) == 0)
+           return (sy);
+    }
+    return (NULL);
+}
+#if OPTIMISED
+/*
+ * determine if the symbol is a simple type that is optimised
+ */
+struct univ_typ *
+simptyp(yp)
+YP      yp;
+{
+    struct univ_typ *p;
+
+    static struct univ_typ bitstring =
+    {"Bitstring", "struct      PElement        *", "BITSTRING", 3, 0},
+            octetstring =
+    {"GeneralString", "struct  qbuf    *", "OCTETSTRING", 4, 0},
+            oid =
+    {"Object Identifier", "struct      OIDentifier     *", "OBJIDENT", 6, 0},
+            obj =
+    {"Module", "struct OIDentifier     *",
+    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", 27, 0};
+
+#define MSTRING 30             /* number of Xs in the above string */
+
+    switch (yp->yp_code) {
+    case YP_BIT:
+    case YP_BITLIST:
+       return (&bitstring);
+
+    case YP_SEQ:
+    case YP_SET:
+    case YP_ANY:
+       return (&bitstring);
+
+    case YP_OCT:
+       return (&octetstring);
+
+    case YP_OID:
+       return (&oid);
+
+    case YP_IDEFINED:
+       (void) strncpy(p->univ_tab, yp->yp_identifier, MSTRING);
+       return (&obj);
+
+
+    case YP_SEQLIST:
+    case YP_SETLIST:
+    case YP_CHOICE:
+
+    default:
+       return (NULL);
+    }
+}
+#endif
+
+/*
+ * lookup a type name until you get something that is not a name
+ */
+YP
+lkup(yp)
+YP     yp;
+{
+    YP yp1;
+
+    if (yp == NULLYP)
+       return (yp);
+    
+    while (yp->yp_code == YP_IDEFINED) {
+        if ((yp1 = lookup_type(yp->yp_module, yp->yp_identifier)) == NULLYP)
+           return (yp);
+       yp = yp1;
+    }
+
+    return (yp);
+}
+/*
+ * compute the type of tag it should be given the tag and the type it is
+ * being applied to
+ */
+comptag(tag, yp)
+int    tag;
+YP     yp;
+{
+    static int warned = 0;
+    YP yp1;
+    struct univ_typ    *p;
+    int        code;
+
+    if (tag == 0)
+       return (0);
+    
+    yp1 = lkup(yp);
+
+    if (yp1->yp_code == YP_IDEFINED) {
+       if ((p = univtyp(yp1->yp_identifier)) == NULL
+         || p->univ_type <= YP_UNDF) {
+               switch (chkil(yp1->yp_identifier)) {
+               case ER_NORMAL:
+                   return (tag);
+
+               case ER_EXPLICIT:
+                   return (0);
+
+               default:
+                   break;
+               }
+                   
+           if (warned++ <= 3) {
+               ferrs(0, "\ncomptag:warning implicit tag of unknown type %s\n",
+                   yp1->yp_identifier);
+               ferr(0, "\tcomptag:treated as implicit\n");
+           }
+           return (tag);
+       }
+       code = p->univ_type;
+    } else {
+       code = yp1->yp_code;
+       if (code == YP_ANY && yp1->yp_flags & YP_WANTIMPLICIT)
+           return (tag);
+    }
+
+    if (code == YP_CHOICE || code == YP_ANY)
+       return (0);
+
+    return (tag);
+}
+
+/*
+ * Generate function definitions for all the macros so that lint
+ * can type check all their uses
+ */
+gen_lint(fp)
+FILE   *fp;
+{
+    char   *buf; 
+    SY      sy;
+    YP      yp;
+
+    fprintf(fp, "\n#if\tdefined(lint) || defined(PEPSY_LINKABLE_FUNCS)\n");
+    for (sy = mysymbols; sy; sy = sy->sy_next) {
+       eval = sy->sy_name;
+       yp = sy->sy_type;
+
+       if (sy->sy_module == NULLCP)
+           yyerror("no module name associated with symbol");
+       if (yp->yp_flags & YP_IMPORTED)
+           continue;
+       if (strcmp(sy->sy_module, mymodule)) {
+           fprintf(stderr,
+             "mymodule unsuitable for module name e.g %s and %s(mymodule)\n",
+             sy->sy_module, mymodule);
+           exit(1);
+       }
+       if (yysection & YP_ENCODER) {
+           /* Encoding routine */
+           buf = modsym (sy -> sy_module, sy -> sy_name, yyencdflt);
+           fprintf(fp, "\n#undef %s\n", buf);
+           fprintf(fp, "int    %s", buf);
+           fprintf(fp, "(pe, top, len, buffer, parm)\n");
+           fprintf(fp, "PE     *pe;\n");
+           fprintf(fp, "int\ttop,\n\tlen;\n");
+           fprintf(fp, "char   *buffer;\n");
+           fprintf(fp, "%s *parm;\n", sym2type(sy));
+           fprintf(fp, "{\n  return (%s(%s%s, ",
+               ENCFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
+           fprintf(fp, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
+           fprintf(fp, "pe, top, len, buffer,\n\t\t(char *) parm));\n}\n");
+       }
+
+       if (yysection & YP_DECODER) {
+           /* Decoding routine */
+           buf = modsym (sy -> sy_module, sy -> sy_name, yydecdflt);
+           fprintf(fp, "\n#undef %s\n", buf);
+           fprintf(fp, "int    %s", buf);
+           fprintf(fp, "(pe, top, len, buffer, parm)\n");
+           fprintf(fp, "PE\tpe;\n");
+           fprintf(fp, "int\ttop,\n       *len;\n");
+           fprintf(fp, "char  **buffer;\n");
+           fprintf(fp, "%s **parm;\n", sym2type(sy));
+           fprintf(fp, "{\n  return (%s(%s%s, ",
+               DECFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
+           fprintf(fp, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
+           fprintf(fp, "pe, top, len, buffer,\n\t\t(char **) parm));\n}\n");
+       }
+
+       if (yysection & YP_PRINTER) {
+           /* Printing routine */
+           buf = modsym (sy -> sy_module, sy -> sy_name, yyprfdflt);
+           fprintf(fp, "\n#undef %s\n/* ARGSUSED */\n", buf);
+           fprintf(fp, "int    %s", buf);
+           fprintf(fp, "(pe, top, len, buffer, parm)\n");
+           fprintf(fp, "PE\tpe;\n");
+           fprintf(fp, "int\ttop,\n       *len;\n");
+           fprintf(fp, "char  **buffer;\n");
+           fprintf(fp, "%s *parm;\n", sym2type(sy));
+           fprintf(fp, "{\n  return (%s(%s%s, ",
+               PRNTFNCNAME, PREFIX, proc_name(sy->sy_name, 1));
+           fprintf(fp, "&%s%s%s, ", PREFIX, tab, MODTYP_SUFFIX);
+           fprintf(fp, "pe, top, len, buffer));\n}\n");
+       }
+
+      if (!fflag)
+          continue;
+
+      switch(yp->yp_code) {
+          /* see do_struct1 in pepsy.c for this list */
+      case YP_BIT:
+      case YP_BITLIST:
+      case YP_SEQ:
+      case YP_SET:
+      case YP_ANY:
+
+      case YP_OCT:
+      case YP_OID:
+          continue;                   /* these are all #defined... */
+      }
+
+      /* Free routine */
+      buf = modsym (sy -> sy_module, sy -> sy_name, "free");
+      fprintf(fp, "\n#undef %s\n", buf);
+      fprintf(fp, "void %s(val)\n", buf);
+      fprintf(fp, "%s *val;\n", sym2type(sy));
+      fprintf(fp, "{\n");
+      fprintf(fp, "%s;\n", gfree(sy->sy_module, sy->sy_name, "val"));
+      fprintf(fp, "}\n");
+
+    }
+
+    fprintf(fp, "\n#endif\t/* lint||PEPSY_LINKABLE_FUNCS */\n");
+
+    if (ferror(fp))
+       myyerror("write error - %s", sys_errname(errno));
+}
+
+/*
+ * pointer table support routines
+ */
+static char    **ptr_tab;      /* reference of the pointer */
+/* static int  ptr_cnt = 0; */
+static int     ptr_max = 0;
+/*
+ * add the given pointer to the pointer table and return its index
+ */
+addptr(p)
+char   *p;
+{
+    int        ind;
+    register int i;
+    register char *s;
+
+    /*
+     * try to eliminate common pointers by returning a ponter if it matches
+     * previously
+     */
+    for (i = 0; i < ptr_cnt; i++)
+       if (strcmp(p, ptr_tab[i]) == 0)
+            return (i);
+
+    if (ptr_max <= ptr_cnt) {
+       if (ptr_max == 0)
+           ptr_tab = (char **) malloc ((unsigned)sizeof(char **) * (ptr_max = 100));
+       else
+           ptr_tab = (char **) realloc ((char *)ptr_tab, (unsigned)sizeof(char **) * (ptr_max *= 2));
+    }
+    if (ptr_tab == NULL) {
+       fprintf(stderr, "\npointer table out of memeory (%d needed)\n",
+               ptr_cnt);
+       exit(1);
+    }
+
+    if ((s = malloc ((unsigned) (strlen (p) + 1))) == NULLCP) {
+       fprintf(stderr, "\naddptr:out of memory\n");
+       exit(1);
+    }
+    (void) strcpy (s, p);
+
+    ptr_tab[ind = ptr_cnt++] = s;
+
+    return (ind);
+}
+
+
+dump_ptrtab(fp)
+FILE   *fp;
+{
+    int                i;
+
+
+    fprintf(fp, "\n/* Pointer table %d entries */\n", ptr_cnt);
+    fprintf(fp, "static caddr_t %s%s%s[] = {\n", PREFIX, PTR_TABNAME, tab);
+
+    for (i = 0; i < ptr_cnt; i++)
+       fprintf(fp, "    (caddr_t ) %s,\n", ptr_tab[i]);
+    
+    if (ptr_cnt <= 0)
+       fprintf(fp, "    (caddr_t ) 0,\n");     /* for fussy C compilers */
+
+    fprintf(fp, "};\n");
+}
+
+/*
+ * routines to parse and analyse C types to support the pepy-like extensions
+ * of pepsy
+ */
+
+/*
+ * remove a level of indirection from the given type. If possible. if not
+ * return NULLCP, otherwise return the new type in a temporary buffer
+ */
+char   *
+rm_indirect(p)
+char   *p;
+{
+    static char        buf[STRSIZE];
+    int                i;
+
+    if (p == NULLCP || *p == '\0' || (i = strlen(p)) >= STRSIZE)
+       return (NULLCP);
+
+    (void) strncpy(buf, p, STRSIZE);
+
+    for (; i >= 0; i--) {
+       if (buf[i] == '*') {
+           buf[i] = '\0';
+           return (buf);
+       }
+    }
+
+    return (NULLCP);
+
+}
+
+/*
+ * extract the field from the C arguement and the following constant
+ * expression for the bit number. 
+ * if it fails return NULLCP
+ */
+char   *
+getfldbit(p, pstr)
+register char *p;
+char **pstr;
+{
+    static char buf[STRSIZE];
+
+    if (p == NULLCP || pstr == (char **)0)
+       return (NULLCP);
+
+    if ((p = getidordot(p, buf, STRSIZE)) == NULLCP)
+       return (NULLCP);
+
+    while (*p && isspace(*p))
+       p++;
+    
+    if (*p != '$') {   /* must be a -> */
+
+       if (strncmp(p, "->", 2) != 0)
+           return (NULLCP);
+       
+       p += 2;
+
+       if ((p = getidordot(p, buf, STRSIZE)) == NULLCP)
+           return (NULLCP);
+
+       while (*p && isspace(*p))
+           p++;
+       
+       if (*p != '$')
+           return (NULLCP);
+    }
+
+    *pstr = p + 1;     /* have to leave it up to the compiler to verify the
+                        * constant expression for the bit number
+                        */
+    return (buf);
+}
+
+/* return a pointer after the current batch of white space if any */
+char   *
+skipspace(p)
+char   *p;
+{
+    if (p == NULLCP)
+        return (NULLCP);
+
+    while (*p && isspace(*p))
+       p++;
+
+    return (p);
+}
+
+/*
+ * extract the field from the C arguement and return it in a static buffer
+ * else return NULLCP
+ */
+char   *
+getfield(p)
+register char *p;
+{
+    static char buf[STRSIZE];
+    char       *buf1;
+
+    if (p == NULLCP)
+       return (NULLCP);
+
+    while (*p && isspace(*p))
+       p++;
+    
+    if (*p == '*')     /* to support *parm field */
+       return (p);
+
+    if ((p = getidordot(p, buf, STRSIZE)) == NULLCP)
+       return (NULLCP);
+
+    while (*p && isspace(*p))
+       p++;
+    
+    if (*p == '\0')
+       return (buf);
+
+    if (strncmp(p, "->", 2) != 0)
+       return (NULLCP);
+    
+    p += 2;
+
+    /* if we have an & keep it on the field */
+    if (*buf == '&')
+       buf1 = buf + 1;
+    else
+       buf1 = buf;
+
+    if ((p = getidordot(p, buf1, STRSIZE)) == NULLCP)
+       return (NULLCP);
+
+    while (*p && isspace(*p))
+       p++;
+    
+    if (*p == '\0')
+       return (buf);
+
+    return (NULLCP);
+}
+
+/*
+ * get an identifier into the given buffer [A-Za-z_] are legal chars
+ */
+char   *
+getid(p, buf, len)
+register char  *p;
+register char  *buf;
+register int   len;
+{
+    char       *fbuf;
+
+    fbuf = buf;
+
+    while (*p && isspace(*p))
+       p++;
+    
+    while (*p && (isalnum(*p) || *p == '_')) {
+       if (len-- >= 0)
+           *buf++ = *p;
+       p++;
+    }
+
+    if (fbuf == buf)
+       return (NULLCP);
+
+    *buf = '\0';
+
+    return (p);
+
+}
+
+/*
+ * get an identifier into the given buffer - '.' are considered part of an 
+ * identifier - should really be called get field reference
+ */
+char   *
+getidordot(p, buf, len)
+register char  *p;
+register char  *buf;
+register int   len;
+{
+    char       *fbuf;
+
+    fbuf = buf;
+
+    while (*p && isspace(*p))
+       p++;
+    
+    if (*p == '&') {
+       len--;
+       *buf++ = *p++;
+
+       while (*p && isspace(*p))
+           p++;
+    }
+
+    while (*p && (isalnum(*p) || *p == '_' || *p == '.')) {
+       if (len-- >= 0)
+           *buf++ = *p;
+       p++;
+    }
+
+    if (fbuf == buf)
+       return (NULLCP);
+
+    *buf = '\0';
+
+    return (p);
+
+}
+static char *noindstr[] = {
+       "*", "*parm", "&", "&parm",
+       NULLCP
+       };
+
+/*
+ * determine if the given field means no indirection wanted and so return 1
+ * else return 0
+ */
+noindirect(f)
+char   *f;
+{
+    char *p, **ps;
+    int                l;
+
+    if (f == NULLCP)
+       return (1);
+
+    f = skipspace(f);
+
+    if (f == NULLCP)
+       return (1);
+
+    if (*f == '&')
+       return (1);
+
+    for (p = f; *p && !isspace(*p); p++)
+       ;
+    l = p - f;
+
+    for (ps = noindstr; *ps; ps++)
+       if (l == strlen(*ps) && strncmp(f, *ps, l) == 0)
+           return (1);
+    
+    return (0);
+}
+
+/*
+ * process the T - the Type and field specifier
+ * the given YP to the appropriate values for VALTYPE string
+ * Namely the yp_parm_type to contain the (Parameter) type string.
+ * then if there is a $ the yp_parm to the part after the $, the field
+ */
+setvaltype(yp, str)
+YP     yp;
+char   *str;
+{
+    char *p;
+
+    if (str == NULLCP || *(str = skipspace(str)) == '\0')
+       return (0);
+    
+    if (p = index(str, '$')) {
+       *p++ = '\0';
+       p = skipspace(p);
+       yp->yp_parm = strdup(p);
+       yp->yp_flags |= YP_PARMVAL;
+    }
+
+    yp->yp_param_type = strdup(str);
+
+    return (1);
+
+}
+
+
+/*
+ * generate the functions that carry out the action statements
+ */
+gen_actfunct(fp)
+FILE   *fp;
+{
+    SY sy;
+    YP yp;
+
+    if (e_actions > 0) {
+       (void) fprintf(fp, "\n/*VARARGS*/");
+       (void) fprintf(fp, "\nstatic\tint\nefn_%s(__p, ppe, _Zp)\ncaddr_t       __p;\n", tab);
+       (void) fprintf(fp, "PE  *ppe;\ntpe      *_Zp;\n{\n");
+       (void) fprintf(fp, "\t\t\n\t/* %d cases */\n    switch(_Zp->pe_ucode) {\n",
+           e_actions);
+       for (sy = mysymbols; sy; sy = sy->sy_next) {
+           yp = sy->sy_type;
+           if (yp->yp_flags & YP_IMPORTED)
+               continue;
+           
+           if (yp->yp_direction & YP_ENCODER || Aflag)
+               gen_actions(fp, yp, G_ENC);
+
+       }
+       (void) fprintf(fp,
+"    default:\n        return (pepsylose(NULLMODTYP, _Zp, *ppe, \"enf_%s:Bad table entry: %%d\",\n             _Zp->pe_ucode));\n",
+               tab);
+       (void) fprintf(fp, "\t\t}\t/* switch */\n    return (OK);\n}\n");
+    }
+    if (d_actions > 0) {
+       (void) fprintf(fp, "\n/*VARARGS*/");
+       (void) fprintf(fp, "\nstatic\tint\ndfn_%s(__p, pe, _Zp, _val)\ncaddr_t  __p;\n", tab);
+       (void) fprintf(fp, "PE  pe;\ntpe        *_Zp;\nint _val;\n{\n");
+       (void) fprintf(fp, "\t\t\n\t/* %d cases */\n    switch(_Zp->pe_ucode) {\n",
+           d_actions);
+       for (sy = mysymbols; sy; sy = sy->sy_next) {
+           yp = sy->sy_type;
+           if (yp->yp_flags & YP_IMPORTED)
+               continue;
+           
+            if (yp->yp_direction & YP_DECODER || Aflag)
+                gen_actions(fp, yp, G_DEC);
+
+       }
+       (void) fprintf(fp,
+"    default:\n        return (pepsylose(NULLMODTYP, _Zp, pe, \"dnf_%s:Bad table entry: %%d\",\n            _Zp->pe_ucode));\n",
+               tab);
+       (void) fprintf(fp, "\t\t}\t/* switch */\n    return (OK);\n}\n");
+    }
+    if (p_actions > 0) {
+       (void) fprintf(fp, "\n/*VARARGS*/");
+       (void) fprintf(fp, "\nstatic\tint\npfn_%s(pe, _Zp)\n", tab);
+       (void) fprintf(fp, "PE  pe;\ntpe        *_Zp;\n{\n");
+       (void) fprintf(fp, "\t\t\n\t/* %d cases */\n    switch(_Zp->pe_ucode) {\n",
+           p_actions);
+       for (sy = mysymbols; sy; sy = sy->sy_next) {
+           yp = sy->sy_type;
+
+           if (yp->yp_flags & YP_IMPORTED)
+               continue;
+           
+           if (yp->yp_direction & YP_PRINTER || Aflag)
+               gen_actions(fp, yp, G_PNT);
+
+       }
+       (void) fprintf(fp,
+"    default:\n        return (pepsylose(NULLMODTYP, _Zp, NULLPE, \"pnf_%s:Bad table entry: %%d\",\n            _Zp->pe_ucode));\n",
+               tab);
+       (void) fprintf(fp, "\t\t}\t/* switch */\n    return (OK);\n}\n");
+    }
+}
+
+#define GEN_RETURN 1
+#define GEN_ASSIGN 2
+/*
+ * generate the actions for this YP unit and all its children
+ */
+gen_actions(fp, oyp, form)
+FILE   *fp;
+YP     oyp;
+int    form;   /* what type of action is it */
+{
+    register YP        yp;
+    register YAL       yal;
+
+    for (yp = oyp; yp; yp = yp->yp_next) {
+
+       /* do its actions first then any of its children */
+       if (yal = yp->yp_bef_alist)
+           dumpact(fp, yal, form, 0);
+       if (yal = yp->yp_aft_alist)
+           dumpact(fp, yal, form, 0);
+       if (yal = yp -> yp_control_act) {
+           if (form == G_ENC)
+               dumpact (fp, yal,form, GEN_RETURN);
+           else if (form == G_DEC)
+               dumpact (fp, yal, form, GEN_ASSIGN);
+       }
+       if (yal = yp -> yp_optional_act) {
+           if (form == G_ENC)
+               dumpact (fp, yal,form, GEN_RETURN);
+           else if (form == G_DEC)
+               dumpact (fp, yal, form, 0);
+       }
+
+       switch (yp->yp_code) {
+       case YP_SEQTYPE:
+       case YP_SEQLIST:
+       case YP_SETTYPE:
+       case YP_SETLIST:
+       case YP_CHOICE:
+           gen_actions(fp, yp->yp_type, form);
+           break;
+
+       default:
+          break;
+       }
+    }
+}
+/*
+ * dump out a single action
+ */
+dumpact(fp, yal, form, ret)
+FILE   *fp;
+YAL    yal;
+int    form;
+int    ret;
+{
+    char       *comm = yal->yal_comment;
+    char       *type = yal->yal_type;
+    Action     act;
+    char       buf[STRSIZE];
+
+    if ((int)strlen(type) > STRSIZE)
+       ferr(1, "dumpact:type too big");
+    (void) strncpy(buf, type, STRSIZE);
+    if (form != G_DEC)
+       (void) strncat(buf, "*", STRSIZE);
+    else
+       (void) strncat(buf, "**", STRSIZE);
+    type = buf;
+    switch (form) {
+    case G_ENC:
+       act = yal->yal_enc;
+       break;
+    case G_DEC:
+       act = yal->yal_dec;
+       break;
+    case G_PNT:
+       act = yal->yal_prn;
+       break;
+    }
+
+    /* can't tell wether this table has the UCODE till here */
+    if (act == NULLAction || act -> a_line == -1)
+       return;
+
+    if (form != G_PNT)
+       (void) fprintf(fp, "\n#define parm      ((%s )__p)\n\tcase %d: /* %s */\n",
+                   type, act->a_num, comm ? comm : "");
+    else 
+       (void) fprintf(fp, "\n\tcase %d: /* %s */\n", act->a_num, comm ? comm : "");
+
+    (void) fprintf(fp, "\t\t{\n# line %d \"%s\"\n",
+                  act->a_line ? act->a_line : 1, sysin);
+
+    switch (ret) {
+    case GEN_ASSIGN:
+       if (control_act (act) == -1)
+           fprintf (fp, "\t\t/* ignored - empty expression */\n");
+       else fprintf (fp, "\t\t(%s) = _val;\n", act -> a_data);
+       break;
+    case GEN_RETURN:
+       fprintf (fp, "\t\treturn (%s);\n",act -> a_data);
+       break;
+    default:
+       fputs (act -> a_data, fp);
+       putc (';', fp);
+       break;
+    }
+
+    (void) fprintf(fp, "\n\t\t}\n\t    break;\n");
+
+    if (form != G_PNT)
+       (void) fprintf(fp, "\n#undef parm\n");
+    act -> a_line = -1;                /* mark as done */
+}
+
+/*
+ * produce a temporary copy of the type specified in the ParameterType
+ * specification
+ * i.e. a [[ P type ]] specification
+ */
+char   *
+partyp2str(yp)
+YP     yp;
+{
+    char *p;
+
+    if (yp->yp_param_type == NULLCP) {
+       fprintf(stderr, "\npartyp2str no param_type field\n");
+       exit(1);
+    }
+
+    if ((p = rm_indirect(yp->yp_param_type)) == NULLCP) {
+       fprintf(stderr, "\npartyp2str can't extract direct type from %s\n",
+           yp->yp_param_type);
+       exit(1);
+    }
+
+    return (p);
+}
+/*
+ * produce a string giving the type of a symbol, in a static buffer
+ */
+char   *
+sym2type(sy)
+SY     sy;
+{
+    static char buffer[STRSIZE];
+
+    if (sy->sy_type && sy->sy_type->yp_param_type)
+       return (partyp2str(sy->sy_type));
+
+    (void) sprintf(buffer, "struct %s", modsym(sy->sy_module, sy->sy_name, "type"));
+
+    return (buffer);
+}
diff --git a/src/isode/pepsy/pass2.h b/src/isode/pepsy/pass2.h
new file mode 100644 (file)
index 0000000..e0eeda9
--- /dev/null
@@ -0,0 +1,140 @@
+/* pass2.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:30:57  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:39:49  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:04  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+/* Change the version number only important features change - so people can
+ * #ifdef on the version number. Also used to provide backwards compatible
+ * macro definitions for posy/pepy.
+ */
+#define PEPSY_VERSION_NUMBER   2
+#define NBPC   8       /* Number of Bits per character - machine dependant */
+#define NBPI   sizeof (int)*NBPC       /* Number of bits per integer */
+
+#define PSAP_DOT_H     "\"psap.h\""
+#define I_PSAP_DOT_H   "<isode/psap.h>"
+#define UNIV_TYPES_DOT_H       "\"UNIV-types.h\""
+#define I_UNIV_TYPES_DOT_H     "<isode/pepsy/UNIV-types.h>"
+#define        HFILE1  "_defs.h"
+#define HFILE2 "_pre_defs.h"
+#define ACTIONDEFS     "_action.h"
+
+#define GENTYPES       "-types.h"
+#define INCFILE1       "pepsy.h"
+/* #define INCFILE2    "pepdefs.h" - not used any more */
+
+#define        ACT1    "_act1"
+#define        ACT2    "_act2"
+#define        ACT3    "_act3"
+#define        ACT4    "_act4"
+#define        ACT05   "_act05"
+
+#define PREFIX "_Z"
+
+#define ETABLE "et_"
+#define DTABLE "dt_"
+#define PTABLE "pt_"
+
+#define        ENCFNCNAME      "enc_f"
+#define        DECFNCNAME      "dec_f"
+#define        PRNTFNCNAME     "prnt_f"
+
+#define        ENC_FNCNAME     "enc_f_"
+#define        DEC_FNCNAME     "dec_f_"
+#define        PRNT_FNCNAME    "prnt_f_"
+
+#define        ENCFILENAME     "_enc.c"
+#define        DECFILENAME     "_dec.c"
+#define        PRNTFILENAME    "_prnt.c"
+
+#define TBLNAME                "_tables.c"
+#define MODTYP_SUFFIX  "_mod"
+
+#define MAXPTRS                200   /* maximum number of pointers in pointer table */
+
+#define PTR_TABNAME    "ptrtab"
+extern int     p_debug;
+
+#define DEB 1
+
+#ifdef DEB
+#define Printf(x, y) if (x <= p_debug) printf y
+#else
+#define Printf(x, y)
+#endif
+
+/*
+ * info for handling a Universal type
+ */
+struct univ_typ        {
+       char    *univ_name;     /* Name of this Universal type */
+       char    *univ_data;     /* type to generate for it */
+       char    *univ_tab;      /* type of table entry it needs */
+       PElementID      univ_id;        /* tag of the type */
+       PElementClass   univ_class;     /* class - probably Universal primative */
+       char    *univ_mod;      /* Name of its module if it has one  */
+       int     univ_flags;     /* Information about entry */
+       int     univ_type;      /* Type we can use for its contents */
+#define UNF_EXTMOD     1       /* Use an external module reference */
+#define UNF_HASDATA    2       /* Has data structure - allocate data for it */
+    };
+
+extern struct univ_typ *univtyp();
+
+/* How many entries in an array */
+#define NENTRIES(x)    (sizeof (x)/sizeof ((x)[0]))
+
+/* used to specify which tables a routine is to generate */
+#define G_ENC  0       /* encoding */
+#define G_DEC  1       /* decoding */
+#define G_PNT  2       /* printing */
+
+#define        hflag   (options[0])
+#define        Hflag   (options[1])
+#define h2flag (options[2])
+#define        NOPTIONS        3
+extern int     options[];
+
+#define STRSIZE 128    /* general buffer size */
+
+extern char   *proc_name();
+
+extern char *getfield(), *getfldbit();
+extern char *class2str();
+
+extern int     gen_ventry();   /* generate a Value Passing Entry */
+extern int     gen_fnentry();  /* generate a function calling entry */
+/* extern Action       start_action, final_action; */
+extern char    *int2tstr();    /* integer to temporary string */
+
+extern char *getfield(), *getfldbit();
+extern char *class2str();
+
+extern int     gen_ventry();   /* generate a Value Passing Entry */
+extern int     gen_fnentry();  /* generate a function calling entry */
+/* extern Action       start_action, final_action; */
diff --git a/src/isode/pepsy/pep.output b/src/isode/pepsy/pep.output
new file mode 100644 (file)
index 0000000..f0f8f9f
--- /dev/null
@@ -0,0 +1,7842 @@
+before encoding INTEGER 7
+before encoding OCTET STRING "The quick"
+before encoding BIT STRING: 0011000
+After Bitstring encoding:'0011000'B
+After Sequence encoding:
+{
+   7,
+   "The quick",
+   '0011000'B
+}
+before encoding INTEGER 6
+before encoding OCTET STRING "brown"
+before encoding BIT STRING: 001100
+After Bitstring encoding:'001100'B
+After Sequence encoding:
+{
+   6,
+   "brown",
+   '001100'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 10
+before encoding OCTET STRING "The quick"
+before encoding BIT STRING: 0011000100
+After Bitstring encoding:'0011000100'B
+After Sequence encoding:
+{
+   10,
+   "The quick",
+   '0011000100'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 9
+before encoding OCTET STRING "brown"
+before encoding BIT STRING: 001100010
+After Bitstring encoding:'001100010'B
+After Sequence encoding:
+{
+   9,
+   "brown",
+   '001100010'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 8
+before encoding OCTET STRING "fox jumps over"
+before encoding BIT STRING: 00110001
+After Bitstring encoding:'00110001'B
+After Sequence encoding:
+{
+   8,
+   "fox jumps over",
+   '00110001'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 7
+before encoding OCTET STRING "The Lazy"
+before encoding BIT STRING: 0011000
+After Bitstring encoding:'0011000'B
+After Sequence encoding:
+{
+   7,
+   "The Lazy",
+   '0011000'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 6
+before encoding OCTET STRING "dog"
+before encoding BIT STRING: 001100
+After Bitstring encoding:'001100'B
+After Sequence encoding:
+{
+   6,
+   "dog",
+   '001100'B
+}
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 7
+r_ostring "The quick"
+r_bstring: 0011000
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 6
+r_ostring "brown"
+r_bstring: 001100
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 10
+r_ostring "The quick"
+r_bstring: 0011000100
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 9
+r_ostring "brown"
+r_bstring: 001100010
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 8
+r_ostring "fox jumps over"
+r_bstring: 00110001
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 7
+r_ostring "The Lazy"
+r_bstring: 0011000
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 6
+r_ostring "dog"
+r_bstring: 001100
+After Decoding CHOICE: chosen 1
+After Decoding UAction
+
+"Action Statements" t_test = 3
+{
+   a {
+      6,
+      3
+   },
+   b {
+      {
+         a 7,
+         b "The quick",
+         c '0011000'B
+      },
+      {
+         a 6,
+         b "brown",
+         c '001100'B
+      }
+   },
+   c {
+      6,
+      3
+   },
+   d {
+      {
+         a 10,
+         b "The quick",
+         c '0011000100'B
+      },
+      {
+         a 9,
+         b "brown",
+         c '001100010'B
+      },
+      {
+         a 8,
+         b "fox jumps over",
+         c '00110001'B
+      },
+      {
+         a 7,
+         b "The Lazy",
+         c '0011000'B
+      },
+      {
+         a 6,
+         b "dog",
+         c '001100'B
+      }
+   },
+   e {
+      -1
+   }
+}
+before encoding INTEGER 5
+before encoding OCTET STRING "The quick"
+before encoding BIT STRING: 00110
+After Bitstring encoding:'00110'B
+After Sequence encoding:
+{
+   5,
+   "The quick",
+   '00110'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 7
+before encoding OCTET STRING "The quick"
+before encoding BIT STRING: 0011000
+After Bitstring encoding:'0011000'B
+After Sequence encoding:
+{
+   7,
+   "The quick",
+   '0011000'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 6
+before encoding OCTET STRING "brown"
+before encoding BIT STRING: 001100
+After Bitstring encoding:'001100'B
+After Sequence encoding:
+{
+   6,
+   "brown",
+   '001100'B
+}
+encoding SET OF Rep-action
+before encoding INTEGER 5
+before encoding OCTET STRING "fox jumps over"
+before encoding BIT STRING: 00110
+After Bitstring encoding:'00110'B
+After Sequence encoding:
+{
+   5,
+   "fox jumps over",
+   '00110'B
+}
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 5
+r_ostring "The quick"
+r_bstring: 00110
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 7
+r_ostring "The quick"
+r_bstring: 0011000
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 6
+r_ostring "brown"
+r_bstring: 001100
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 5
+r_ostring "fox jumps over"
+r_bstring: 00110
+After Decoding CHOICE: chosen 3
+After Decoding UAction
+
+"Action Statements" t_test = 2
+{
+   a {
+      3
+   },
+   b {
+      {
+         a 5,
+         b "The quick",
+         c '00110'B
+      }
+   },
+   c {
+      3
+   },
+   d {
+      {
+         a 7,
+         b "The quick",
+         c '0011000'B
+      },
+      {
+         a 6,
+         b "brown",
+         c '001100'B
+      },
+      {
+         a 5,
+         b "fox jumps over",
+         c '00110'B
+      }
+   },
+   e {
+      "lets go home"
+   }
+}
+encoding SET OF Rep-action
+before encoding INTEGER 4
+before encoding OCTET STRING "The quick"
+before encoding BIT STRING: 0011
+After Bitstring encoding:'0011'B
+After Sequence encoding:
+{
+   4,
+   "The quick",
+   '0011'B
+}
+encoding Boolean 0
+Before Decoding Rep-action
+After Decoding Rep-action:
+rp_int 4
+r_ostring "The quick"
+r_bstring: 0011
+Decoding Boolean
+After Decoding CHOICE: chosen 2
+After Decoding UAction
+
+"Action Statements" t_test = 1
+{
+   a {},
+   b {},
+   c {},
+   d {
+      {
+         a 4,
+         b "The quick",
+         c '0011'B
+      }
+   },
+   e {
+      FALSE
+   }
+}
+
+"All Simple Types" t_test = 3
+{
+   a {
+      a 'ff'H,
+      b "\b",
+      d "\n",
+      "hello there, world\n"
+   },
+   b 5,
+   c 5,
+   d 5,
+   e "hello there, world\n",
+   f "hello world\n",
+   g "hello world\n",
+   h 1.17,
+   i 1.17,
+   j 1.17,
+   k 'ff'H,
+   l '000100100011000100011010001101110'B,
+   m 9.42479,
+   n TRUE
+}
+
+"All Simple Types" t_test = 2
+{
+   a {
+      a 'ff'H,
+      c 'ff'H,
+      e 0
+   },
+   b 3,
+   c 3,
+   d 3,
+   e "hello world\n",
+   f "hello world\n",
+   g "hello world\n",
+   h 1.17.45.49,
+   i 1.17.45.49,
+   j 1.17.45.49,
+   k '00'H,
+   l '00010010001100010001101000110111'B,
+   m 6.28319,
+   n FALSE
+}
+
+"All Simple Types" t_test = 1
+{
+   a {
+      b '00'H,
+      d '00'H,
+      e -1,
+      "hello there, world\n"
+   },
+   b 1,
+   c 1,
+   d 1,
+   e "hello there, world\n",
+   f "hello world\n",
+   g "hello world\n",
+   h 1.17,
+   i 1.17,
+   j 1.17,
+   k 'ff'H,
+   l '0001001000110001000110100011011'B,
+   m 3.1416,
+   n TRUE
+}
+
+"function calling code" t_test = 3
+{
+   a 'ff'H,
+   b '00'H,
+   c "\b",
+   d "\n",
+   e 2,
+   f "hello there, world\n",
+   left {
+      a 'ff'H,
+      b '00'H,
+      d "\n",
+      e 2,
+      "hello there, world\n"
+   },
+   right {
+      a 'ff'H,
+      b "\b",
+      d "\n",
+      "hello there, world\n"
+   }
+}
+
+"function calling code" t_test = 2
+{
+   a '00'H,
+   b 'ff'H,
+   c 'ff'H,
+   d "\t",
+   f "hello world\n",
+   left {
+      a '00'H,
+      c 'ff'H
+   },
+   right {
+      a 'ff'H,
+      c 'ff'H,
+      e 0
+   }
+}
+
+"function calling code" t_test = 1
+{
+   a 'ff'H,
+   b '00'H,
+   c '00'H,
+   d "\b",
+   e 0,
+   f "hello there, world\n",
+   left {
+      b '00'H,
+      d "\b",
+      e 0,
+      "hello there, world\n"
+   },
+   right {
+      b '00'H,
+      d '00'H,
+      e -1,
+      "hello there, world\n"
+   }
+}
+
+"Value Passing Defined types" t_test = 3
+{
+   "hello there, world\n",
+   b "Some one is out there!",
+   '00313233343536'H,
+   '0000000000110001001100100011'B,
+   [PRIVATE 577] '18'H,
+   '000100100011000100011010001101110010'B,
+   9357,
+   1.73205,
+   1.17.42,
+   TRUE,
+   4
+}
+
+"Value Passing Defined types" t_test = 2
+{
+   "hello there, world\n",
+   b "Some one is out there!",
+   '003132333435'H,
+   '00000000001100010011'B,
+   [PRIVATE 16] {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H,
+      [PRIVATE 37] '00'H,
+      [PRIVATE 50] 'ff'H,
+      [PRIVATE 65] "\b",
+      [PRIVATE 82] "\t",
+      [PRIVATE 101] "\n",
+      [PRIVATE 122] '0b'H,
+      [PRIVATE 145] "mkpelist:testdata",
+      [PRIVATE 170] "mkpelist:testdata",
+      [PRIVATE 197] '0010'H,
+      [PRIVATE 226] '0010'H,
+      [PRIVATE 15] {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b",
+         [PRIVATE 82] "\t",
+         [PRIVATE 101] "\n",
+         [PRIVATE 122] '0b'H,
+         [PRIVATE 145] "mkpelist:testdata",
+         [PRIVATE 170] "mkpelist:testdata",
+         [PRIVATE 197] '0010'H,
+         [PRIVATE 226] '0010'H
+      }
+   },
+   '00010010001100010001101000110111001'B,
+   9356,
+   1.41421,
+   1.17,
+   FALSE,
+   3
+}
+
+"Value Passing Defined types" t_test = 1
+{
+   "hello there, world\n",
+   b "Some one is out there!",
+   '0031323334'H,
+   '000000000011'B,
+   [PRIVATE 101] "\n",
+   '0001001000110001000110100011011100'B,
+   9355,
+   1,
+   1.17,
+   TRUE,
+   2
+}
+
+"Repeating pepy elements" t_test = 3
+{
+   a {
+      6,
+      3
+   },
+   b {
+      {
+         a 7,
+         b "The quick",
+         c '0011000'B
+      },
+      {
+         a 6,
+         b "brown",
+         c '001100'B
+      }
+   },
+   c {
+      6,
+      3
+   },
+   d {
+      {
+         a 10,
+         b "The quick",
+         c '0011000100'B
+      },
+      {
+         a 9,
+         b "brown",
+         c '001100010'B
+      },
+      {
+         a 8,
+         b "fox jumps over",
+         c '00110001'B
+      },
+      {
+         a 7,
+         b "The Lazy",
+         c '0011000'B
+      },
+      {
+         a 6,
+         b "dog",
+         c '001100'B
+      }
+   },
+   e {
+      -1
+   }
+}
+
+"Repeating pepy elements" t_test = 2
+{
+   a {
+      3
+   },
+   b {
+      {
+         a 5,
+         b "The quick",
+         c '00110'B
+      }
+   },
+   c {
+      3
+   },
+   d {
+      {
+         a 7,
+         b "The quick",
+         c '0011000'B
+      },
+      {
+         a 6,
+         b "brown",
+         c '001100'B
+      },
+      {
+         a 5,
+         b "fox jumps over",
+         c '00110'B
+      }
+   },
+   e {
+      "lets go home"
+   }
+}
+
+"Repeating pepy elements" t_test = 1
+{
+   a {},
+   b {},
+   c {},
+   d {
+      {
+         a 4,
+         b "The quick",
+         c '0011'B
+      }
+   },
+   e {
+      FALSE
+   }
+}
+
+"Compound S-types" t_test = 3
+{
+   a {},
+   b {
+      [2] 12357
+   },
+   c {},
+   d {
+      [4] 4
+   }
+}
+
+"Compound S-types" t_test = 2
+{
+   a {
+      12356
+   },
+   b {},
+   c {
+      3
+   },
+   d {}
+}
+
+"Compound S-types" t_test = 1
+{
+   a {},
+   b {
+      [2] 12355
+   },
+   c {},
+   d {
+      [4] 2
+   }
+}
+
+"Pepy Stuff" t_test = 3
+{
+   12357,
+   4,
+   "Some is out there!",
+   "hello, world\n",
+   '00313233343536'H,
+   '00010010001100010001101000110111001010100'B,
+   '0000000000110001001100100011'B,
+   TRUE,
+   1.17.42,
+   3.06998,
+   [PRIVATE 730] '0010'H,
+   {
+      [1] 12357,
+      12357,
+      4,
+      [4] 4,
+      "hello, world\n",
+      [8] "hello, world\n",
+      '00313233343536'H,
+      [10] '00313233343536'H,
+      1.17.42,
+      [18] 1.17.42,
+      3.06998,
+      [20] 3.06998,
+      [21] '0010'H
+   },
+   [13] {
+      [2] 12357,
+      [4] 4,
+      "Some is out there!",
+      [6] "Some is out there!",
+      "hello, world\n",
+      [8] "hello, world\n",
+      '00313233343536'H,
+      [10] '00313233343536'H,
+      '00010010001100010001101000110111001010101'B,
+      [12] '00010010001100010001101000110111001010101'B,
+      '00000000001100010011001000110011'B,
+      [16] TRUE,
+      1.17.42,
+      3.06998,
+      [PRIVATE 730] '0010'H
+   }
+}
+
+"Pepy Stuff" t_test = 2
+{
+   12356,
+   3,
+   "Some is out there!",
+   "hello, world\n",
+   '003132333435'H,
+   '00010010001100010001101000110111001010100'B,
+   '00000000001100010011'B,
+   FALSE,
+   1.17,
+   2.50663,
+   [PRIVATE 362] 'ff'H,
+   {
+      [1] 12356,
+      12356,
+      "hello, world\n",
+      [8] "hello, world\n",
+      '003132333435'H,
+      [10] '003132333435'H,
+      '000000000011000100110010'B,
+      FALSE,
+      [16] FALSE,
+      1.17,
+      [18] 1.17,
+      2.50663,
+      [20] 2.50663,
+      [21] 'ff'H
+   },
+   [13] {
+      12356,
+      3,
+      "Some is out there!",
+      [6] "Some is out there!",
+      "hello, world\n",
+      [8] "hello, world\n",
+      '003132333435'H,
+      [10] '003132333435'H,
+      '00010010001100010001101000110111001010101'B,
+      [12] '00010010001100010001101000110111001010101'B,
+      '000000000011000100110010'B,
+      FALSE,
+      1.17,
+      [19] 2.50663,
+      [PRIVATE 362] 'ff'H
+   }
+}
+
+"Pepy Stuff" t_test = 1
+{
+   12355,
+   2,
+   "Some is out there!",
+   "hello, world\n",
+   '0031323334'H,
+   '00010010001100010001101000110111001010100'B,
+   '000000000011'B,
+   TRUE,
+   1.17,
+   1.77245,
+   [PRIVATE 122] '0b'H,
+   {
+      [1] 12355,
+      12355,
+      2,
+      [4] 2,
+      "hello, world\n",
+      [8] "hello, world\n",
+      '0031323334'H,
+      [10] '0031323334'H,
+      '0000000000110001'B,
+      1.17,
+      [18] 1.17,
+      1.77245,
+      [20] 1.77245,
+      [21] '0b'H
+   },
+   [13] {
+      [2] 12355,
+      [4] 2,
+      "Some is out there!",
+      [6] "Some is out there!",
+      "hello, world\n",
+      [8] "hello, world\n",
+      '0031323334'H,
+      [10] '0031323334'H,
+      '00010010001100010001101000110111001010101'B,
+      [12] '00010010001100010001101000110111001010101'B,
+      '0000000000110001'B,
+      [16] TRUE,
+      1.17,
+      1.77245,
+      [PRIVATE 122] '0b'H
+   }
+}
+
+"Tests of Real type" t_test = 4
+{
+   r1 927640,
+   r2 0,
+   r3 -2.28789,
+   r4 927640
+}
+
+"Tests of Real type" t_test = 3
+{
+   r1 -2.28789,
+   r2 927640,
+   r3 0,
+   r4 3.1416,
+   r5 927640
+}
+
+"Tests of Real type" t_test = 2
+{
+   r1 0,
+   r2 -2.28789,
+   r3 927640,
+   r4 0,
+   r5 -2.28789
+}
+
+"Tests of Real type" t_test = 1
+{
+   r1 927640,
+   r2 0,
+   r3 -2.28789,
+   r4 3.1416
+}
+
+"Real" t_test = 3
+-2.28789
+
+"Real" t_test = 2
+0
+
+"Real" t_test = 1
+927640
+
+"Tests of Enumerated type" t_test = 4
+{
+   ae1 0,
+   ae2 1,
+   ae3 3,
+   ae4 -1,
+   ae5 -1
+}
+
+"Tests of Enumerated type" t_test = 3
+{
+   ae1 -1,
+   ae2 0,
+   ae3 1,
+   ae4 3
+}
+
+"Tests of Enumerated type" t_test = 2
+{
+   ae1 3,
+   ae2 -1,
+   ae3 0,
+   ae4 3,
+   ae5 1
+}
+
+"Tests of Enumerated type" t_test = 1
+{
+   ae1 1,
+   ae2 3,
+   ae3 -1,
+   ae4 0
+}
+
+"Enumerated Type" t_test = 4
+0
+
+"Enumerated Type" t_test = 3
+-1
+
+"Enumerated Type" t_test = 2
+3
+
+"Enumerated Type" t_test = 1
+1
+
+"Single Objects" t_test = 4
+{
+   st2 "xxxxxxx, world"
+}
+
+"Single Objects" t_test = 3
+{}
+
+"Single Objects" t_test = 2
+{
+   st2 "xxxxxxx, world"
+}
+
+"Single Objects" t_test = 1
+{
+   st2 "xxxxxxx, world"
+}
+
+"Explicit Tagged Objects" t_test = 3
+{
+   bE 40986
+}
+
+"Explicit Tagged Objects" t_test = 2
+{
+   aE 10283
+}
+
+"Explicit Tagged Objects" t_test = 1
+{
+   bE 40986
+}
+
+"Single EXTERNAL" t_test = 1
+{
+   direct-reference 1.17.222,
+   indirect-reference 16,
+   data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+   encoding {
+      octet-aligned '536f6d652074657374206461746100'H
+   }
+}
+
+"EXTERNAL" t_test = 6
+{
+   ext {
+      direct-reference 1.17.474,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type '00'H
+      }
+   },
+   a-ny 'ff'H,
+   ext-impl {
+      direct-reference 1.17.366,
+      indirect-reference 40,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type '00'H
+      }
+   },
+   any-impl 'ff'H,
+   ext-expl {
+      direct-reference 1.17.258,
+      indirect-reference 12,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type '00'H
+      }
+   },
+   any-expl '0010'H
+}
+
+"EXTERNAL" t_test = 5
+{
+   ext {
+      direct-reference 1.17.402,
+      indirect-reference 12,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   a-ny "mkpelist:testdata",
+   ext-impl {
+      direct-reference 1.17.312,
+      indirect-reference 16,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type 'ff'H
+      }
+   },
+   any-impl {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H,
+      [PRIVATE 37] '00'H,
+      [PRIVATE 50] 'ff'H,
+      [PRIVATE 65] "\b",
+      [PRIVATE 82] "\t",
+      [PRIVATE 101] "\n",
+      [PRIVATE 122] '0b'H,
+      [PRIVATE 145] "mkpelist:testdata",
+      [PRIVATE 170] "mkpelist:testdata",
+      [PRIVATE 197] '0010'H,
+      [PRIVATE 226] '0010'H,
+      [PRIVATE 15] {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b",
+         [PRIVATE 82] "\t",
+         [PRIVATE 101] "\n",
+         [PRIVATE 122] '0b'H,
+         [PRIVATE 145] "mkpelist:testdata",
+         [PRIVATE 170] "mkpelist:testdata",
+         [PRIVATE 197] '0010'H,
+         [PRIVATE 226] '0010'H
+      },
+      [PRIVATE 16] {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b",
+         [PRIVATE 82] "\t",
+         [PRIVATE 101] "\n",
+         [PRIVATE 122] '0b'H,
+         [PRIVATE 145] "mkpelist:testdata",
+         [PRIVATE 170] "mkpelist:testdata",
+         [PRIVATE 197] '0010'H,
+         [PRIVATE 226] '0010'H,
+         [PRIVATE 15] {
+            [PRIVATE 2] 'ff'H,
+            [PRIVATE 5] '00'H,
+            [PRIVATE 10] 'ff'H,
+            [PRIVATE 17] '00'H,
+            [PRIVATE 26] 'ff'H,
+            [PRIVATE 37] '00'H,
+            [PRIVATE 50] 'ff'H,
+            [PRIVATE 65] "\b",
+            [PRIVATE 82] "\t",
+            [PRIVATE 101] "\n",
+            [PRIVATE 122] '0b'H,
+            [PRIVATE 145] "mkpelist:testdata",
+            [PRIVATE 170] "mkpelist:testdata",
+            [PRIVATE 197] '0010'H,
+            [PRIVATE 226] '0010'H
+         }
+      },
+      [PRIVATE 325] '00'H,
+      [PRIVATE 362] 'ff'H,
+      [PRIVATE 401] '14'H,
+      [PRIVATE 442] '15'H,
+      [PRIVATE 485] "mkpelist:testdata",
+      [PRIVATE 530] 'ff'H,
+      [PRIVATE 577] '18'H,
+      [PRIVATE 626] '19'H,
+      [PRIVATE 677] "mkpelist:testdata",
+      [PRIVATE 730] '0010'H,
+      [PRIVATE 27] {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b",
+         [PRIVATE 82] "\t",
+         [PRIVATE 101] "\n",
+         [PRIVATE 122] '0b'H,
+         [PRIVATE 145] "mkpelist:testdata",
+         [PRIVATE 170] "mkpelist:testdata",
+         [PRIVATE 197] '0010'H,
+         [PRIVATE 226] '0010'H,
+         [PRIVATE 15] {
+            [PRIVATE 2] 'ff'H,
+            [PRIVATE 5] '00'H,
+            [PRIVATE 10] 'ff'H,
+            [PRIVATE 17] '00'H,
+            [PRIVATE 26] 'ff'H,
+            [PRIVATE 37] '00'H,
+            [PRIVATE 50] 'ff'H,
+            [PRIVATE 65] "\b",
+            [PRIVATE 82] "\t",
+            [PRIVATE 101] "\n",
+            [PRIVATE 122] '0b'H,
+            [PRIVATE 145] "mkpelist:testdata",
+            [PRIVATE 170] "mkpelist:testdata",
+            [PRIVATE 197] '0010'H,
+            [PRIVATE 226] '0010'H
+         },
+         [PRIVATE 16] {
+            [PRIVATE 2] 'ff'H,
+            [PRIVATE 5] '00'H,
+            [PRIVATE 10] 'ff'H,
+            [PRIVATE 17] '00'H,
+            [PRIVATE 26] 'ff'H,
+            [PRIVATE 37] '00'H,
+            [PRIVATE 50] 'ff'H,
+            [PRIVATE 65] "\b",
+            [PRIVATE 82] "\t",
+            [PRIVATE 101] "\n",
+            [PRIVATE 122] '0b'H,
+            [PRIVATE 145] "mkpelist:testdata",
+            [PRIVATE 170] "mkpelist:testdata",
+            [PRIVATE 197] '0010'H,
+            [PRIVATE 226] '0010'H,
+            [PRIVATE 15] {
+               [PRIVATE 2] 'ff'H,
+               [PRIVATE 5] '00'H,
+               [PRIVATE 10] 'ff'H,
+               [PRIVATE 17] '00'H,
+               [PRIVATE 26] 'ff'H,
+               [PRIVATE 37] '00'H,
+               [PRIVATE 50] 'ff'H,
+               [PRIVATE 65] "\b",
+               [PRIVATE 82] "\t",
+               [PRIVATE 101] "\n",
+               [PRIVATE 122] '0b'H,
+               [PRIVATE 145] "mkpelist:testdata",
+               [PRIVATE 170] "mkpelist:testdata",
+               [PRIVATE 197] '0010'H,
+               [PRIVATE 226] '0010'H
+            }
+         },
+         [PRIVATE 325] '00'H,
+         [PRIVATE 362] 'ff'H,
+         [PRIVATE 401] '14'H,
+         [PRIVATE 442] '15'H,
+         [PRIVATE 485] "mkpelist:testdata",
+         [PRIVATE 530] 'ff'H,
+         [PRIVATE 577] '18'H,
+         [PRIVATE 626] '19'H,
+         [PRIVATE 677] "mkpelist:testdata",
+         [PRIVATE 730] '0010'H
+      },
+      [PRIVATE 842] 'ff'H,
+      [PRIVATE 901] '1e'H,
+      [PRIVATE 962] "mkpelist:testdata",
+      [PRIVATE 1025] '00'H,
+      [PRIVATE 1090] "!",
+      [PRIVATE 1157] "mkpelist:testdata",
+      [PRIVATE 1226] '0010'H,
+      [PRIVATE 35] {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b",
+         [PRIVATE 82] "\t",
+         [PRIVATE 101] "\n",
+         [PRIVATE 122] '0b'H,
+         [PRIVATE 145] "mkpelist:testdata",
+         [PRIVATE 170] "mkpelist:testdata",
+         [PRIVATE 197] '0010'H,
+         [PRIVATE 226] '0010'H,
+         [PRIVATE 15] {
+            [PRIVATE 2] 'ff'H,
+            [PRIVATE 5] '00'H,
+            [PRIVATE 10] 'ff'H,
+            [PRIVATE 17] '00'H,
+            [PRIVATE 26] 'ff'H,
+            [PRIVATE 37] '00'H,
+            [PRIVATE 50] 'ff'H,
+            [PRIVATE 65] "\b",
+            [PRIVATE 82] "\t",
+            [PRIVATE 101] "\n",
+            [PRIVATE 122] '0b'H,
+            [PRIVATE 145] "mkpelist:testdata",
+            [PRIVATE 170] "mkpelist:testdata",
+            [PRIVATE 197] '0010'H,
+            [PRIVATE 226] '0010'H
+         },
+         [PRIVATE 16] {
+            [PRIVATE 2] 'ff'H,
+            [PRIVATE 5] '00'H,
+            [PRIVATE 10] 'ff'H,
+            [PRIVATE 17] '00'H,
+            [PRIVATE 26] 'ff'H,
+            [PRIVATE 37] '00'H,
+            [PRIVATE 50] 'ff'H,
+            [PRIVATE 65] "\b",
+            [PRIVATE 82] "\t",
+            [PRIVATE 101] "\n",
+            [PRIVATE 122] '0b'H,
+            [PRIVATE 145] "mkpelist:testdata",
+            [PRIVATE 170] "mkpelist:testdata",
+            [PRIVATE 197] '0010'H,
+            [PRIVATE 226] '0010'H,
+            [PRIVATE 15] {
+               [PRIVATE 2] 'ff'H,
+               [PRIVATE 5] '00'H,
+               [PRIVATE 10] 'ff'H,
+               [PRIVATE 17] '00'H,
+               [PRIVATE 26] 'ff'H,
+               [PRIVATE 37] '00'H,
+               [PRIVATE 50] 'ff'H,
+               [PRIVATE 65] "\b",
+               [PRIVATE 82] "\t",
+               [PRIVATE 101] "\n",
+               [PRIVATE 122] '0b'H,
+               [PRIVATE 145] "mkpelist:testdata",
+               [PRIVATE 170] "mkpelist:testdata",
+               [PRIVATE 197] '0010'H,
+               [PRIVATE 226] '0010'H
+            }
+         },
+         [PRIVATE 325] '00'H,
+         [PRIVATE 362] 'ff'H,
+         [PRIVATE 401] '14'H,
+         [PRIVATE 442] '15'H,
+         [PRIVATE 485] "mkpelist:testdata",
+         [PRIVATE 530] 'ff'H,
+         [PRIVATE 577] '18'H,
+         [PRIVATE 626] '19'H,
+         [PRIVATE 677] "mkpelist:testdata",
+         [PRIVATE 730] '0010'H,
+         [PRIVATE 27] {
+            [PRIVATE 2] 'ff'H,
+            [PRIVATE 5] '00'H,
+            [PRIVATE 10] 'ff'H,
+            [PRIVATE 17] '00'H,
+            [PRIVATE 26] 'ff'H,
+            [PRIVATE 37] '00'H,
+            [PRIVATE 50] 'ff'H,
+            [PRIVATE 65] "\b",
+            [PRIVATE 82] "\t",
+            [PRIVATE 101] "\n",
+            [PRIVATE 122] '0b'H,
+            [PRIVATE 145] "mkpelist:testdata",
+            [PRIVATE 170] "mkpelist:testdata",
+            [PRIVATE 197] '0010'H,
+            [PRIVATE 226] '0010'H,
+            [PRIVATE 15] {
+               [PRIVATE 2] 'ff'H,
+               [PRIVATE 5] '00'H,
+               [PRIVATE 10] 'ff'H,
+               [PRIVATE 17] '00'H,
+               [PRIVATE 26] 'ff'H,
+               [PRIVATE 37] '00'H,
+               [PRIVATE 50] 'ff'H,
+               [PRIVATE 65] "\b",
+               [PRIVATE 82] "\t",
+               [PRIVATE 101] "\n",
+               [PRIVATE 122] '0b'H,
+               [PRIVATE 145] "mkpelist:testdata",
+               [PRIVATE 170] "mkpelist:testdata",
+               [PRIVATE 197] '0010'H,
+               [PRIVATE 226] '0010'H
+            },
+            [PRIVATE 16] {
+               [PRIVATE 2] 'ff'H,
+               [PRIVATE 5] '00'H,
+               [PRIVATE 10] 'ff'H,
+               [PRIVATE 17] '00'H,
+               [PRIVATE 26] 'ff'H,
+               [PRIVATE 37] '00'H,
+               [PRIVATE 50] 'ff'H,
+               [PRIVATE 65] "\b",
+               [PRIVATE 82] "\t",
+               [PRIVATE 101] "\n",
+               [PRIVATE 122] '0b'H,
+               [PRIVATE 145] "mkpelist:testdata",
+               [PRIVATE 170] "mkpelist:testdata",
+               [PRIVATE 197] '0010'H,
+               [PRIVATE 226] '0010'H,
+               [PRIVATE 15] {
+                  [PRIVATE 2] 'ff'H,
+                  [PRIVATE 5] '00'H,
+                  [PRIVATE 10] 'ff'H,
+                  [PRIVATE 17] '00'H,
+                  [PRIVATE 26] 'ff'H,
+                  [PRIVATE 37] '00'H,
+                  [PRIVATE 50] 'ff'H,
+                  [PRIVATE 65] "\b",
+                  [PRIVATE 82] "\t",
+                  [PRIVATE 101] "\n",
+                  [PRIVATE 122] '0b'H,
+                  [PRIVATE 145] "mkpelist:testdata",
+                  [PRIVATE 170] "mkpelist:testdata",
+                  [PRIVATE 197] '0010'H,
+                  [PRIVATE 226] '0010'H
+               }
+            },
+            [PRIVATE 325] '00'H,
+            [PRIVATE 362] 'ff'H,
+            [PRIVATE 401] '14'H,
+            [PRIVATE 442] '15'H,
+            [PRIVATE 485] "mkpelist:testdata",
+            [PRIVATE 530] 'ff'H,
+            [PRIVATE 577] '18'H,
+            [PRIVATE 626] '19'H,
+            [PRIVATE 677] "mkpelist:testdata",
+            [PRIVATE 730] '0010'H
+         },
+         [PRIVATE 842] 'ff'H,
+         [PRIVATE 901] '1e'H,
+         [PRIVATE 962] "mkpelist:testdata",
+         [PRIVATE 1025] '00'H,
+         [PRIVATE 1090] "!",
+         [PRIVATE 1157] "mkpelist:testdata",
+         [PRIVATE 1226] '0010'H
+      },
+      [PRIVATE 1370] 'ff'H,
+      [PRIVATE 1445] "&",
+      [PRIVATE 1522] "mkpelist:testdata",
+      [PRIVATE 1601] "(",
+      [PRIVATE 1682] "mkpelist:testdata",
+      [PRIVATE 1765] '0010'H
+   },
+   ext-expl {
+      direct-reference 1.17.222,
+      indirect-reference 16,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   any-expl "mkpelist:testdata"
+}
+
+"EXTERNAL" t_test = 4
+{
+   ext {
+      direct-reference 1.17.330,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   a-ny "!",
+   ext-impl {
+      direct-reference 1.17.258,
+      indirect-reference 12,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type '00'H
+      }
+   },
+   any-impl '0010'H,
+   ext-expl {
+      direct-reference 1.17.186,
+      indirect-reference 4,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   any-expl 'ff'H
+}
+
+"EXTERNAL" t_test = 3
+{
+   ext {
+      direct-reference 1.17.258,
+      indirect-reference 12,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type '00'H
+      }
+   },
+   a-ny '19'H,
+   ext-impl {
+      direct-reference 1.17.204,
+      indirect-reference 32,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type 'ff'H
+      }
+   },
+   any-impl '0010'H,
+   ext-expl {
+      direct-reference 1.17.150,
+      indirect-reference 20,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type 'ff'H
+      }
+   },
+   any-expl 'ff'H
+}
+
+"EXTERNAL" t_test = 2
+{
+   ext {
+      direct-reference 1.17.186,
+      indirect-reference 4,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   a-ny {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H,
+      [PRIVATE 37] '00'H,
+      [PRIVATE 50] 'ff'H,
+      [PRIVATE 65] "\b",
+      [PRIVATE 82] "\t",
+      [PRIVATE 101] "\n",
+      [PRIVATE 122] '0b'H,
+      [PRIVATE 145] "mkpelist:testdata",
+      [PRIVATE 170] "mkpelist:testdata",
+      [PRIVATE 197] '0010'H,
+      [PRIVATE 226] '0010'H,
+      [PRIVATE 15] {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b",
+         [PRIVATE 82] "\t",
+         [PRIVATE 101] "\n",
+         [PRIVATE 122] '0b'H,
+         [PRIVATE 145] "mkpelist:testdata",
+         [PRIVATE 170] "mkpelist:testdata",
+         [PRIVATE 197] '0010'H,
+         [PRIVATE 226] '0010'H
+      }
+   },
+   ext-impl {
+      direct-reference 1.17.150,
+      indirect-reference 20,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type 'ff'H
+      }
+   },
+   any-impl 'ff'H,
+   ext-expl {
+      direct-reference 1.17.114,
+      indirect-reference 16,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   any-expl '15'H
+}
+
+"EXTERNAL" t_test = 1
+{
+   ext {
+      direct-reference 1.17.114,
+      indirect-reference 16,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   a-ny "\t",
+   ext-impl {
+      direct-reference 1.17.96,
+      indirect-reference 28,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         single-ASN1-type '00'H
+      }
+   },
+   any-impl '0b'H,
+   ext-expl {
+      direct-reference 1.17.78,
+      indirect-reference 48,
+      data-value-descriptor '4120766572792077696c642074797065206f66206461746100'H,
+      encoding {
+         octet-aligned '536f6d652074657374206461746100'H
+      }
+   },
+   any-expl "mkpelist:testdata"
+}
+
+"Optimised" t_test = 8
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H,
+      [PRIVATE 37] '00'H,
+      [PRIVATE 50] 'ff'H,
+      [PRIVATE 65] "\b"
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b"
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H,
+         [PRIVATE 65] "\b"
+      },
+      o7 1.17
+   }
+}
+
+"Optimised" t_test = 7
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H,
+      [PRIVATE 37] '00'H,
+      [PRIVATE 50] 'ff'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H,
+         [PRIVATE 50] 'ff'H
+      },
+      o7 1.17
+   }
+}
+
+"Optimised" t_test = 6
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H,
+      [PRIVATE 37] '00'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H,
+         [PRIVATE 37] '00'H
+      },
+      o7 1.17
+   }
+}
+
+"Optimised" t_test = 5
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H,
+      [PRIVATE 26] 'ff'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H,
+         [PRIVATE 26] 'ff'H
+      },
+      o7 1.17.48.53.58
+   }
+}
+
+"Optimised" t_test = 4
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H,
+      [PRIVATE 17] '00'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H,
+         [PRIVATE 17] '00'H
+      },
+      o7 1.17.45.49
+   }
+}
+
+"Optimised" t_test = 3
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H,
+      [PRIVATE 10] 'ff'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H,
+         [PRIVATE 10] 'ff'H
+      },
+      o7 1.17.42
+   }
+}
+
+"Optimised" t_test = 2
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H,
+      [PRIVATE 5] '00'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H,
+         [PRIVATE 5] '00'H
+      },
+      o7 1.17
+   }
+}
+
+"Optimised" t_test = 1
+{
+   o1 '0001010000110001000100100011011100011010'B,
+   o2 "Peckling Worsley!!!!",
+   o3 {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   o4 {
+      [PRIVATE 2] 'ff'H
+   },
+   {
+      o5 {
+         [PRIVATE 2] 'ff'H
+      },
+      o6 {
+         [PRIVATE 2] 'ff'H
+      },
+      o7 1.17
+   }
+}
+
+"External References" t_test = 6
+{
+   a-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   b-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   c-ref {
+      c1 {
+         o-c1 '416e6472657720576f72736c657921212100'H
+      },
+      c2 {
+         b-c2 '0000001000000001000000010000011100111111'B
+      },
+      c3 {
+         seq-c3 {
+            seq-c3-in {
+               i-expl 35051,
+               o-expl "explicit tagged octet string",
+               b-expl '00111000001110000011100000111111'B,
+               f-expl TRUE,
+               obj-expl {
+                  atest 2001,
+                  btest "Good bye",
+                  ctest '000000110000100010101010'B,
+                  big-test {
+                     ostring '3132fe00ff6136'H,
+                     bstring '10111000000011110000100000010000001000000100000000'B,
+                     nstring "123456",
+                     pstring "hello, world",
+                     tstring "teletex",
+                     t61string "T.61",
+                     vstring "visible",
+                     vis-string "visible again",
+                     i646string "who knows what this is",
+                     ia5string "This is ASCII\n\r",
+                     graphstring "This is a graphic string",
+                     genstring "This is a general string"
+                  },
+                  emb-test {
+                     em-int -101,
+                     em-oct "Embedded octet string",
+                     em-bit '1111111110101010010101011111100000000001'B
+                  }
+               },
+               i-exp-test {
+                  i-ex-int -9,
+                  i-ex-oct '4578706c6963697420456d62656464656400'H,
+                  i-ex-bit '0000001100000011000000110000001110111111'B
+               }
+            },
+            seq-c3-i 40938,
+            seq-c3-o '4a616d657320576f72736c65792121212100'H
+         }
+      },
+      c4 {
+         c4-choice {
+            sc-b-i 13151
+         }
+      }
+   }
+}
+
+"External References" t_test = 5
+{
+   a-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   b-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   c-ref {
+      c1 {
+         i-c1 10101
+      },
+      c2 {
+         o-c2 '5269636861726420576f72736c6579212100'H
+      },
+      c3 {
+         i-c3 689364
+      },
+      c4 {
+         c4-choice {
+            sc-a-i 16891
+         }
+      }
+   },
+   e-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   }
+}
+
+"External References" t_test = 4
+{
+   a-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   b-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   c-ref {
+      c1 {
+         obj-c1 {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         }
+      },
+      c2 {
+         i-c2 1212
+      },
+      c3 {
+         set-c3 {
+            set-c3-in {
+               i-expl 35051,
+               o-expl "explicit tagged octet string",
+               b-expl '00111000001110000011100000111111'B,
+               f-expl TRUE,
+               obj-expl {
+                  atest 2001,
+                  btest "Good bye",
+                  ctest '000000110000100010101010'B,
+                  big-test {
+                     ostring '3132fe00ff6136'H,
+                     bstring '10111000000011110000100000010000001000000100000000'B,
+                     nstring "123456",
+                     pstring "hello, world",
+                     tstring "teletex",
+                     t61string "T.61",
+                     vstring "visible",
+                     vis-string "visible again",
+                     i646string "who knows what this is",
+                     ia5string "This is ASCII\n\r",
+                     graphstring "This is a graphic string",
+                     genstring "This is a general string"
+                  },
+                  emb-test {
+                     em-int -101,
+                     em-oct "Embedded octet string",
+                     em-bit '1111111110101010010101011111100000000001'B
+                  }
+               },
+               i-exp-test {
+                  i-ex-int -9,
+                  i-ex-oct '4578706c6963697420456d62656464656400'H,
+                  i-ex-bit '0000001100000011000000110000001110111111'B
+               }
+            },
+            set-c3-i 264504,
+            set-c3-o '5061747269636b20576f72736c6579212100'H
+         }
+      },
+      c4 {
+         c4-choice {
+            c4-obj {
+               i-expl 35051,
+               o-expl "explicit tagged octet string",
+               b-expl '00111000001110000011100000111111'B,
+               f-expl TRUE,
+               obj-expl {
+                  atest 2001,
+                  btest "Good bye",
+                  ctest '000000110000100010101010'B,
+                  big-test {
+                     ostring '3132fe00ff6136'H,
+                     bstring '10111000000011110000100000010000001000000100000000'B,
+                     nstring "123456",
+                     pstring "hello, world",
+                     tstring "teletex",
+                     t61string "T.61",
+                     vstring "visible",
+                     vis-string "visible again",
+                     i646string "who knows what this is",
+                     ia5string "This is ASCII\n\r",
+                     graphstring "This is a graphic string",
+                     genstring "This is a general string"
+                  },
+                  emb-test {
+                     em-int -101,
+                     em-oct "Embedded octet string",
+                     em-bit '1111111110101010010101011111100000000001'B
+                  }
+               },
+               i-exp-test {
+                  i-ex-int -9,
+                  i-ex-oct '4578706c6963697420456d62656464656400'H,
+                  i-ex-bit '0000001100000011000000110000001110111111'B
+               }
+            }
+         }
+      }
+   }
+}
+
+"External References" t_test = 3
+{
+   a-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   b-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   c-ref {
+      c1 {
+         f-c1 TRUE
+      },
+      c2 {
+         obj-c2 {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         }
+      },
+      c3 {
+         seq-c3 {
+            seq-c3-in {
+               i-expl 35051,
+               o-expl "explicit tagged octet string",
+               b-expl '00111000001110000011100000111111'B,
+               f-expl TRUE,
+               obj-expl {
+                  atest 2001,
+                  btest "Good bye",
+                  ctest '000000110000100010101010'B,
+                  big-test {
+                     ostring '3132fe00ff6136'H,
+                     bstring '10111000000011110000100000010000001000000100000000'B,
+                     nstring "123456",
+                     pstring "hello, world",
+                     tstring "teletex",
+                     t61string "T.61",
+                     vstring "visible",
+                     vis-string "visible again",
+                     i646string "who knows what this is",
+                     ia5string "This is ASCII\n\r",
+                     graphstring "This is a graphic string",
+                     genstring "This is a general string"
+                  },
+                  emb-test {
+                     em-int -101,
+                     em-oct "Embedded octet string",
+                     em-bit '1111111110101010010101011111100000000001'B
+                  }
+               },
+               i-exp-test {
+                  i-ex-int -9,
+                  i-ex-oct '4578706c6963697420456d62656464656400'H,
+                  i-ex-bit '0000001100000011000000110000001110111111'B
+               }
+            },
+            seq-c3-i 40938,
+            seq-c3-o '4a616d657320576f72736c65792121212100'H
+         }
+      },
+      c4 {
+         c4-choice {
+            c4-i 10938
+         }
+      }
+   },
+   e-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   }
+}
+
+"External References" t_test = 2
+{
+   a-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   b-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   c-ref {
+      c1 {
+         b-c1 '0000001000000010000000100000011100111111'B
+      },
+      c2 {
+         f-c2 TRUE
+      },
+      c3 {
+         i-c3 689364
+      },
+      c4 {
+         c4-choice {
+            sc-b-i 13151
+         }
+      }
+   }
+}
+
+"External References" t_test = 1
+{
+   a-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   b-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   },
+   c-ref {
+      c1 {
+         o-c1 '416e6472657720576f72736c657921212100'H
+      },
+      c2 {
+         b-c2 '0000001000000001000000010000011100111111'B
+      },
+      c3 {
+         set-c3 {
+            set-c3-in {
+               i-expl 35051,
+               o-expl "explicit tagged octet string",
+               b-expl '00111000001110000011100000111111'B,
+               f-expl TRUE,
+               obj-expl {
+                  atest 2001,
+                  btest "Good bye",
+                  ctest '000000110000100010101010'B,
+                  big-test {
+                     ostring '3132fe00ff6136'H,
+                     bstring '10111000000011110000100000010000001000000100000000'B,
+                     nstring "123456",
+                     pstring "hello, world",
+                     tstring "teletex",
+                     t61string "T.61",
+                     vstring "visible",
+                     vis-string "visible again",
+                     i646string "who knows what this is",
+                     ia5string "This is ASCII\n\r",
+                     graphstring "This is a graphic string",
+                     genstring "This is a general string"
+                  },
+                  emb-test {
+                     em-int -101,
+                     em-oct "Embedded octet string",
+                     em-bit '1111111110101010010101011111100000000001'B
+                  }
+               },
+               i-exp-test {
+                  i-ex-int -9,
+                  i-ex-oct '4578706c6963697420456d62656464656400'H,
+                  i-ex-bit '0000001100000011000000110000001110111111'B
+               }
+            },
+            set-c3-i 264504,
+            set-c3-o '5061747269636b20576f72736c6579212100'H
+         }
+      },
+      c4 {
+         c4-choice {
+            sc-a-i 16891
+         }
+      }
+   },
+   e-ref {
+      a1 101910,
+      a2 -304985,
+      a3 13,
+      a4 {
+         a-seq {
+            fred 998877
+         }
+      }
+   }
+}
+
+"Default test" t_test = 12
+{
+   a-def 1,
+   okay FALSE,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-def {
+      colour 1,
+      version { basic }
+   },
+   st-def {
+      beer 2,
+      spirit 0
+   }
+}
+
+"Default test" t_test = 11
+{
+   a-def 1,
+   c-def '100000000'B,
+   okay FALSE,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   }
+}
+
+"Default test" t_test = 10
+{
+   a-def 1,
+   b-def '537573616e20536962656c202121212100'H,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-def {
+      colour 1,
+      oem-oct '4a756c696120447a75696b6173202121212100'H,
+      version { basic }
+   }
+}
+
+"Default test" t_test = 9
+{
+   a-def 1,
+   okay FALSE,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   st-def {}
+}
+
+"Default test" t_test = 8
+{
+   a-def 1,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-def {
+      colour 1,
+      version { basic }
+   },
+   st-def {
+      beer 2,
+      spirit 0
+   }
+}
+
+"Default test" t_test = 7
+{
+   a-def 1,
+   okay FALSE,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   st-def {
+      wine 2,
+      beer 2
+   }
+}
+
+"Default test" t_test = 6
+{
+   a-def 1,
+   b-def '537573616e20536962656c202121212100'H,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   st-def {}
+}
+
+"Default test" t_test = 5
+{
+   a-def 1,
+   c-def '100000000'B,
+   okay FALSE,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   }
+}
+
+"Default test" t_test = 4
+{
+   a-def 1,
+   okay FALSE,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-def {
+      colour 1,
+      version { basic }
+   },
+   st-def {
+      beer 2,
+      spirit 0
+   }
+}
+
+"Default test" t_test = 3
+{
+   a-def 1,
+   c-def '100000000'B,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   st-def {}
+}
+
+"Default test" t_test = 2
+{
+   a-def 1,
+   b-def '537573616e20536962656c202121212100'H,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-def {
+      colour 1,
+      version { basic }
+   },
+   st-def {
+      spirit 0
+   }
+}
+
+"Default test" t_test = 1
+{
+   a-def 1,
+   big-def {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-def {
+      version { basic }
+   },
+   st-def {
+      beer 2,
+      spirit 0
+   }
+}
+
+"Optional test" t_test = 8
+{
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   etag-opt 2983461
+}
+
+"Optional test" t_test = 7
+{
+   a-opt 192837,
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   d-opt TRUE,
+   e-opt NULL,
+   big-opt {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-opt {
+      oem-int 197336,
+      oem-oct '4c696e6720576f72736c657900'H
+   },
+   st-opt {
+      st-int0 85659,
+      st-int2 967768
+   },
+   obj-opt {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   ch-opt {
+      ch-2 28828
+   }
+}
+
+"Optional test" t_test = 6
+{
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   c-opt '0000101000001111000000100000011100111111'B,
+   d-opt TRUE,
+   e-opt NULL
+}
+
+"Optional test" t_test = 5
+{
+   a-opt 192837,
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   c-opt '0000101000001111000000100000011100111111'B,
+   e-opt NULL,
+   big-opt {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-opt {
+      oem-int 197336,
+      oem-oct '4c696e6720576f72736c657900'H
+   },
+   st-opt {
+      st-int0 85659,
+      st-int2 967768
+   },
+   obj-opt {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   ch-opt {
+      ch-2 28828
+   }
+}
+
+"Optional test" t_test = 4
+{
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   e-opt NULL
+}
+
+"Optional test" t_test = 3
+{
+   a-opt 192837,
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   d-opt TRUE,
+   big-opt {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-opt {
+      oem-int 197336,
+      oem-oct '4c696e6720576f72736c657900'H
+   },
+   st-opt {
+      st-int0 85659,
+      st-int2 967768
+   },
+   obj-opt {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   ch-opt {
+      ch-2 28828
+   }
+}
+
+"Optional test" t_test = 2
+{
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   c-opt '0000101000001111000000100000011100111111'B,
+   d-opt TRUE
+}
+
+"Optional test" t_test = 1
+{
+   a-opt 192837,
+   b-opt '537573616e2048616e6e616820536962656c00'H,
+   c-opt '0000101000001111000000100000011100111111'B,
+   big-opt {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-opt {
+      oem-int 197336,
+      oem-oct '4c696e6720576f72736c657900'H
+   },
+   st-opt {
+      st-int0 85659,
+      st-int2 967768
+   },
+   obj-opt {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   ch-opt {
+      ch-2 28828
+   }
+}
+
+"Choice" t_test = 7
+{
+   c1 {
+      b-c1 '0000001000000010000000100000011100111111'B
+   },
+   c2 {
+      f-c2 TRUE
+   },
+   c3 {
+      set-c3 {
+         set-c3-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         set-c3-i 264504,
+         set-c3-o '5061747269636b20576f72736c6579212100'H
+      }
+   },
+   c4 {
+      c4-choice {
+         c4-i 10938
+      }
+   }
+}
+
+"Choice" t_test = 6
+{
+   c1 {
+      o-c1 '416e6472657720576f72736c657921212100'H
+   },
+   c2 {
+      b-c2 '0000001000000001000000010000011100111111'B
+   },
+   c3 {
+      seq-c3 {
+         seq-c3-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         seq-c3-i 40938,
+         seq-c3-o '4a616d657320576f72736c65792121212100'H
+      }
+   },
+   c4 {
+      c4-choice {
+         sc-b-i 13151
+      }
+   }
+}
+
+"Choice" t_test = 5
+{
+   c1 {
+      i-c1 10101
+   },
+   c2 {
+      o-c2 '5269636861726420576f72736c6579212100'H
+   },
+   c3 {
+      i-c3 689364
+   },
+   c4 {
+      c4-choice {
+         sc-a-i 16891
+      }
+   }
+}
+
+"Choice" t_test = 4
+{
+   c1 {
+      obj-c1 {
+         atest 2001,
+         btest "Good bye",
+         ctest '000000110000100010101010'B,
+         big-test {
+            ostring '3132fe00ff6136'H,
+            bstring '10111000000011110000100000010000001000000100000000'B,
+            nstring "123456",
+            pstring "hello, world",
+            tstring "teletex",
+            t61string "T.61",
+            vstring "visible",
+            vis-string "visible again",
+            i646string "who knows what this is",
+            ia5string "This is ASCII\n\r",
+            graphstring "This is a graphic string",
+            genstring "This is a general string"
+         },
+         emb-test {
+            em-int -101,
+            em-oct "Embedded octet string",
+            em-bit '1111111110101010010101011111100000000001'B
+         }
+      }
+   },
+   c2 {
+      i-c2 1212
+   },
+   c3 {
+      set-c3 {
+         set-c3-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         set-c3-i 264504,
+         set-c3-o '5061747269636b20576f72736c6579212100'H
+      }
+   },
+   c4 {
+      c4-choice {
+         c4-obj {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         }
+      }
+   }
+}
+
+"Choice" t_test = 3
+{
+   c1 {
+      f-c1 TRUE
+   },
+   c2 {
+      obj-c2 {
+         atest 2001,
+         btest "Good bye",
+         ctest '000000110000100010101010'B,
+         big-test {
+            ostring '3132fe00ff6136'H,
+            bstring '10111000000011110000100000010000001000000100000000'B,
+            nstring "123456",
+            pstring "hello, world",
+            tstring "teletex",
+            t61string "T.61",
+            vstring "visible",
+            vis-string "visible again",
+            i646string "who knows what this is",
+            ia5string "This is ASCII\n\r",
+            graphstring "This is a graphic string",
+            genstring "This is a general string"
+         },
+         emb-test {
+            em-int -101,
+            em-oct "Embedded octet string",
+            em-bit '1111111110101010010101011111100000000001'B
+         }
+      }
+   },
+   c3 {
+      seq-c3 {
+         seq-c3-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         seq-c3-i 40938,
+         seq-c3-o '4a616d657320576f72736c65792121212100'H
+      }
+   },
+   c4 {
+      c4-choice {
+         c4-i 10938
+      }
+   }
+}
+
+"Choice" t_test = 2
+{
+   c1 {
+      b-c1 '0000001000000010000000100000011100111111'B
+   },
+   c2 {
+      f-c2 TRUE
+   },
+   c3 {
+      i-c3 689364
+   },
+   c4 {
+      c4-choice {
+         sc-b-i 13151
+      }
+   }
+}
+
+"Choice" t_test = 1
+{
+   c1 {
+      o-c1 '416e6472657720576f72736c657921212100'H
+   },
+   c2 {
+      b-c2 '0000001000000001000000010000011100111111'B
+   },
+   c3 {
+      set-c3 {
+         set-c3-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         set-c3-i 264504,
+         set-c3-o '5061747269636b20576f72736c6579212100'H
+      }
+   },
+   c4 {
+      c4-choice {
+         sc-a-i 16891
+      }
+   }
+}
+
+"SEQ OF and SET OF" t_test = 10
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 9
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 8
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 7
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 6
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 5
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 4
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 3
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 2
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"SEQ OF and SET OF" t_test = 1
+{
+   sqof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   stof-test1 {
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      },
+      {
+         i-expl 35051,
+         o-expl "explicit tagged octet string",
+         b-expl '00111000001110000011100000111111'B,
+         f-expl TRUE,
+         obj-expl {
+            atest 2001,
+            btest "Good bye",
+            ctest '000000110000100010101010'B,
+            big-test {
+               ostring '3132fe00ff6136'H,
+               bstring '10111000000011110000100000010000001000000100000000'B,
+               nstring "123456",
+               pstring "hello, world",
+               tstring "teletex",
+               t61string "T.61",
+               vstring "visible",
+               vis-string "visible again",
+               i646string "who knows what this is",
+               ia5string "This is ASCII\n\r",
+               graphstring "This is a graphic string",
+               genstring "This is a general string"
+            },
+            emb-test {
+               em-int -101,
+               em-oct "Embedded octet string",
+               em-bit '1111111110101010010101011111100000000001'B
+            }
+         },
+         i-exp-test {
+            i-ex-int -9,
+            i-ex-oct '4578706c6963697420456d62656464656400'H,
+            i-ex-bit '0000001100000011000000110000001110111111'B
+         }
+      }
+   },
+   i-test1 33,
+   sqof-test2 {
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      },
+      {
+         sqof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         sqof-i 212121,
+         sqof-o '456c656d656e743820456d62656464656400'H
+      }
+   },
+   stof-test2 {
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      },
+      {
+         stof-in {
+            i-expl 35051,
+            o-expl "explicit tagged octet string",
+            b-expl '00111000001110000011100000111111'B,
+            f-expl TRUE,
+            obj-expl {
+               atest 2001,
+               btest "Good bye",
+               ctest '000000110000100010101010'B,
+               big-test {
+                  ostring '3132fe00ff6136'H,
+                  bstring '10111000000011110000100000010000001000000100000000'B,
+                  nstring "123456",
+                  pstring "hello, world",
+                  tstring "teletex",
+                  t61string "T.61",
+                  vstring "visible",
+                  vis-string "visible again",
+                  i646string "who knows what this is",
+                  ia5string "This is ASCII\n\r",
+                  graphstring "This is a graphic string",
+                  genstring "This is a general string"
+               },
+               emb-test {
+                  em-int -101,
+                  em-oct "Embedded octet string",
+                  em-bit '1111111110101010010101011111100000000001'B
+               }
+            },
+            i-exp-test {
+               i-ex-int -9,
+               i-ex-oct '4578706c6963697420456d62656464656400'H,
+               i-ex-bit '0000001100000011000000110000001110111111'B
+            }
+         },
+         stof-i -12345,
+         stof-o '58595a616263646520456d62656464656400'H
+      }
+   },
+   i-test2 99
+}
+
+"Explicit tags" t_test = 1
+{
+   i-expl 35051,
+   o-expl "explicit tagged octet string",
+   b-expl '00111000001110000011100000111111'B,
+   f-expl TRUE,
+   obj-expl {
+      atest 2001,
+      btest "Good bye",
+      ctest '000000110000100010101010'B,
+      big-test {
+         ostring '3132fe00ff6136'H,
+         bstring '10111000000011110000100000010000001000000100000000'B,
+         nstring "123456",
+         pstring "hello, world",
+         tstring "teletex",
+         t61string "T.61",
+         vstring "visible",
+         vis-string "visible again",
+         i646string "who knows what this is",
+         ia5string "This is ASCII\n\r",
+         graphstring "This is a graphic string",
+         genstring "This is a general string"
+      },
+      emb-test {
+         em-int -101,
+         em-oct "Embedded octet string",
+         em-bit '1111111110101010010101011111100000000001'B
+      }
+   },
+   i-exp-test {
+      i-ex-int -9,
+      i-ex-oct '4578706c6963697420456d62656464656400'H,
+      i-ex-bit '0000001100000011000000110000001110111111'B
+   }
+}
+
+"Implicit tags" t_test = 1
+{
+   i-impl -1,
+   o-impl '49276d20616e20696d706c6963697420746167676564206f6374657420737472696e6700'H,
+   b-impl '0000000000000000000000011001100000000001'B,
+   f-impl TRUE,
+   obj-impl {
+      atest 2001,
+      btest "Good bye",
+      ctest '000000110000100010101010'B,
+      big-test {
+         ostring '3132fe00ff6136'H,
+         bstring '10111000000011110000100000010000001000000100000000'B,
+         nstring "123456",
+         pstring "hello, world",
+         tstring "teletex",
+         t61string "T.61",
+         vstring "visible",
+         vis-string "visible again",
+         i646string "who knows what this is",
+         ia5string "This is ASCII\n\r",
+         graphstring "This is a graphic string",
+         genstring "This is a general string"
+      },
+      emb-test {
+         em-int -101,
+         em-oct "Embedded octet string",
+         em-bit '1111111110101010010101011111100000000001'B
+      }
+   },
+   i-emb-test {
+      i-em-int -101,
+      i-em-oct '496d706c6963697420456d62656464656400'H,
+      i-em-bit '10000000100000001000000010000000'B
+   }
+}
+
+"Embedded Strings" t_test = 1
+{
+   atest 2001,
+   btest "Good bye",
+   ctest '000000110000100010101010'B,
+   big-test {
+      ostring '3132fe00ff6136'H,
+      bstring '10111000000011110000100000010000001000000100000000'B,
+      nstring "123456",
+      pstring "hello, world",
+      tstring "teletex",
+      t61string "T.61",
+      vstring "visible",
+      vis-string "visible again",
+      i646string "who knows what this is",
+      ia5string "This is ASCII\n\r",
+      graphstring "This is a graphic string",
+      genstring "This is a general string"
+   },
+   emb-test {
+      em-int -101,
+      em-oct "Embedded octet string",
+      em-bit '1111111110101010010101011111100000000001'B
+   }
+}
+
+"Strings" t_test = 1
+{
+   ostring '3132fe00ff6136'H,
+   bstring '10111000000011110000100000010000001000000100000000'B,
+   nstring "123456",
+   pstring "hello, world",
+   tstring "teletex",
+   t61string "T.61",
+   vstring "visible",
+   vis-string "visible again",
+   i646string "who knows what this is",
+   ia5string "This is ASCII\n\r",
+   graphstring "This is a graphic string",
+   genstring "This is a general string"
+}
+
+"Embedded" t_test = 1
+{
+   anMPDU {
+      a-seq {
+         fred 10,
+         george TRUE
+      }
+   },
+   ei 6966
+}
+
+"MPDU" t_test = 1
+{
+   a-seq {
+      fred 10,
+      george TRUE
+   }
+}
+Total 107  = 107 successes 0 failures
diff --git a/src/isode/pepsy/pepsy-driver.h b/src/isode/pepsy/pepsy-driver.h
new file mode 100644 (file)
index 0000000..aeffc8e
--- /dev/null
@@ -0,0 +1,53 @@
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:08  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:39:58  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:07  isode
+ * Release 7.0
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+/*
+ * common definitions for the pepsy driver routines
+ */
+#define PEPSY_VERSION  2
+
+/* find the default entry for this entry - for decoding
+ * - assumes its the next or the one after or the one after that.
+ * old version
+#define FDFLT_B(p)     ((((p) + 1)->pe_type == DFLT_B) ? ((p) + 1) : \
+                       ((((p) + 2)->pe_type == DFLT_B) ? ((p) + 2): ((p) + 3)))
+ */
+#define FDFLT_B(p)     fdflt_b(p)      /* try a function */
+
+/* find the entry for this default entry - for encoding
+ * call a function - to keep looking till it finds it, this is the
+ * alternative to the above scheme.
+ */
+#define FDFLT_F(p)     fdflt_f(p)      /* have to use a function */
+
+/* assumes encoding tables */
+#define OPT_PRESENT(p, parm)   (BITTEST(parm + p->pe_ucode, p->pe_tag))
+
+/* assumes decoding tables */
+#define SET_OPT_PRESENT(p, parm)       (BITSET(*parm + p->pe_ucode, p->pe_tag))
+#define CLR_OPT_PRESENT(p, parm)       (BITCLR(*parm + p->pe_ucode, p->pe_tag))
+
+#define NO_DATA_USED   (OK + 1)
diff --git a/src/isode/pepsy/pepsy.1 b/src/isode/pepsy/pepsy.1
new file mode 100644 (file)
index 0000000..d056069
--- /dev/null
@@ -0,0 +1,75 @@
+.TH PEPSY 1 "24 Jun 1990"
+.\" $Header$
+.\"
+.\"
+.\" $Log$
+.\" Revision 1.1  1994/06/10 03:31:11  eichin
+.\" autoconfed isode for kerberos work
+.\"
+# Revision 1.1  1994/05/31 20:40:03  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+.\" Revision 8.0  91/07/17  12:43:07  isode
+.\" Release 7.0
+.\" 
+.\" 
+.SH NAME
+pepsy \- table driven replacement for posy/pepy
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B pepsy
+\%[\-A]
+\%[\-a]
+\%[\-C]
+\%[\-f]
+\%[\-h\fIoption\fP]
+\%[\-s]
+\fImodule.py\fR
+.in -.5i
+.SH DESCRIPTION
+The \fIpepsy\fR program reads a description of a \fIpresentation\fR module and
+produces definitions and tables for use with the \fIC\fR programming language.
+It is meant to be backwards-compatible with the \fIposy\fR system.
+(So, \fIpepsy\fR will ignore any \fIpepy\fR-style augmentations in the
+input file.)
+.PP
+The `\-A' (All) switch directs \fIpepsy\fR to generate tables for encoders,
+decoders, and printers.
+.PP
+The `\-a' switch directs \fIpepsy\fR to augment the #include file with
+commentary text.
+.PP
+The '\-C' switch directs \fIpepsy\fR to produce backwards compatible
+code which generates three .h files rather than one.
+.PP
+The `\-f' switch directs \fIpepsy\fR to generate \fIC\fR macros to deallocate
+the structures it defines.
+.PP
+The `\-h' switch enables additional heuristics when \fIpepsy\fR generates a
+\fIC\fR language structure definition.
+Option `0' enables the default heuristics.
+Enabling any other option also results in enabling option `0'.
+Option `1' enables \*(lqclever\*(rq but non\-unique structure naming.
+Option `2' enables the generation of arrays rather than linked-lists
+whenever possible.
+.PP
+Normally, \fIpepsy\fR prints the name of each type as it works.
+The `\-s' switch disables this behavior.
+.SH FILES
+.nf
+.ta \w'\fImodule\fR_pre_defs.h  'u
+\fImodule\fR.ph        extern type definitions from \fImodule\fR
+\fImodule\fR_tables.c  initialised tables for processing \fImodule\fR
+\fImodule\fR-types.h   \fIC\fR structure definitions from \fImodule\fR
+\fImodule\fR_pre_defs.h        Preprocessor constants for each type in \fImodule\fR
+\fImodule\fR_defs.h    macros to support pepy routines for \fImodule\fR's types
+.re
+.fi
+.SH "SEE ALSO"
+pepy(1), posy(1),
+.br
+\fIThe ISO Development Environment: User's Manual\fR
+.SH AUTHOR
+Andrew Worsley,
+CSIRO and UCL
diff --git a/src/isode/pepsy/pepsy.c b/src/isode/pepsy/pepsy.c
new file mode 100644 (file)
index 0000000..4bae33e
--- /dev/null
@@ -0,0 +1,3731 @@
+/* pepsy.c - table driven posy/pepy replacement system */
+
+/* OPEN QUESTIONS:
+
+       How to do smarter DEFAULT determination for the other types and NULLs
+
+       Perhaps pull-up primitive IDentifiers
+
+       Abort a CHOICE encoding if the structure is empty
+
+
+                                 HEURISTICS
+
+   1. LANGUAGE SIMPLIFICATIONS:
+
+
+       Pull-up uni-member SEQUENCEs/SETs/CHOICEs
+
+
+   2. LANGUAGE ASSUMPTIONS:
+
+       Unique tags to avoid conflicts for internal structures (-h1 option)
+
+
+   3. STYLE ISSUES:
+
+       SEQUENCE/SET OF Type should have Type be an ID for nicer naming
+ */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:15  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.2  1994/06/07 03:45:37  eichin
+ * mips doesn't have yylineno either
+ *
+ * Revision 1.1  1994/05/31 20:40:05  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:08  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <varargs.h>
+#include "pepsydefs.h"
+#include "pass2.h"
+
+#if defined(USING_BISON) || defined(mips)
+int yylineno = 0;              /* Bison doesn't have yylineno, sigh */
+                               /* ultrix doesn't either */
+#endif
+
+
+#define        SVAL(s)         ((s) ? (s) : "")
+#define PARVAL(s)      ((s) ? (s) : "parm")
+
+/* \f   DATA */
+
+static int aflag = 0;
+int    Aflag = 0;      /* Don't so all modes by default */
+int    Cflag = 1;      /* combine H files */
+int    dflag = 0;
+int    Pflag = 0;              /* pepy compat ... */
+char    *bflag = NULL;         /*  .. */
+char   *iflag = NULL;          /* -i file => #include users file */
+char    *module_actions = NULL;
+int    pepydebug = 0;
+int    doexternals = 1;
+int fflag = 0;
+static int linepos = 0;
+int mflag = 0;
+int sflag = 0;
+
+int p_debug = 3;
+int options[NOPTIONS];
+
+char *eval = NULLCP;
+
+char   *mymodule = "";
+OID    mymoduleid = NULLOID;
+static char modulename[BUFSIZ];
+
+int yysection = YP_DECODER;
+char *yyencpref = "encode";
+char *yydecpref = "decode";
+char *yyprfpref = "print";
+char *yyencdflt = "encode";
+char *yydecdflt = "decode";
+char *yyprfdflt = "print";
+
+static char *classes[] = {
+    "UNIVERSAL ",
+    "APPLICATION ",
+    "",
+    "PRIVATE "
+};
+
+static char *tags[] = {
+    "", "BOOLEAN", "INTEGER", "INTEGER", "BIT STRING", "BIT STRING",
+    "OCTET STRING", "NULL", "SEQUENCE", "SEQUENCE OF", "SEQUENCE",  "SET",
+    "SET OF", "SET", "CHOICE", "ANY", "OBJECT IDENTIFIER", "", "ENUMERATED",
+    "REAL", "",
+
+    NULL
+};
+
+struct tuple tuples[] = {
+       YP_BOOL, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_BOOL",
+               PE_CLASS_UNIV, PE_PRIM_BOOL,
+       YP_INT, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_INT",
+               PE_CLASS_UNIV, PE_PRIM_INT,
+       YP_INTLIST, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_INT",
+               PE_CLASS_UNIV, PE_PRIM_INT,
+       YP_BIT, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_BITS",
+               PE_CLASS_UNIV, PE_PRIM_BITS,
+       YP_BITLIST, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_BITS",
+               PE_CLASS_UNIV, PE_PRIM_BITS,
+       YP_OCT, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_OCTS",
+               PE_CLASS_UNIV, PE_PRIM_OCTS,
+       YP_NULL, "PE_CLASS_UNIV", NULLCP, "PE_PRIM_NULL",
+               PE_CLASS_UNIV, PE_PRIM_NULL,
+       YP_OID, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_OID",
+               PE_CLASS_UNIV, PE_PRIM_OID,
+       YP_SEQ, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SEQ",
+               PE_CLASS_UNIV, PE_CONS_SEQ,
+       YP_SEQTYPE, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SEQ",
+               PE_CLASS_UNIV, PE_CONS_SEQ,
+       YP_SEQLIST, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SEQ",
+               PE_CLASS_UNIV, PE_CONS_SEQ,
+       YP_SET, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SET",
+               PE_CLASS_UNIV, PE_CONS_SET,
+       YP_SETTYPE, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SET",
+               PE_CLASS_UNIV, PE_CONS_SET,
+       YP_SETLIST, "PE_CLASS_UNIV", "PE_FORM_CONS", "PE_CONS_SET",
+               PE_CLASS_UNIV, PE_CONS_SET,
+       YP_ENUMLIST, "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_ENUM",
+               PE_CLASS_UNIV, PE_PRIM_ENUM,
+       YP_REAL,     "PE_CLASS_UNIV", "PE_FORM_PRIM", "PE_PRIM_REAL",
+               PE_CLASS_UNIV, PE_PRIM_REAL,
+
+       YP_UNDF
+};
+
+
+static char autogen[BUFSIZ];
+
+char   *sysin = NULLCP;
+static char sysout[BUFSIZ];
+static char sysdef[BUFSIZ];
+static char sysact[BUFSIZ];
+
+static FILE *fdef;
+
+
+static  MD     mymodules = NULLMD;
+
+typedef struct symlist {
+    char   *sy_encpref;
+    char   *sy_decpref;
+    char   *sy_prfpref;
+    char   *sy_module;
+    char   *sy_name;
+
+    YP     sy_type;
+
+    struct symlist *sy_next;
+}              symlist, *SY;
+#define        NULLSY  ((SY) 0)
+
+SY     mysymbols = NULLSY;
+
+
+char   *gensym (), *modsym (), *array ();
+extern char    *my_strcat(), *gfree(), *concat(), *my_new_str();
+extern char    *getid();
+MD     lookup_module ();
+SY     new_symbol (), add_symbol ();
+static double val2real ();
+static void prime_default ();
+static void merge_files ();
+
+static yyerror_aux ();
+static do_struct0 ();
+static do_struct1 ();
+static do_struct2 ();
+static printag ();
+static xalloc ();
+static balloc ();
+static choice_pullup ();
+static components_pullup ();
+static int  val2int ();
+static val2prf ();
+static dump_real ();
+static int  dfl2int ();
+static print_value ();
+static modsym_aux ();
+static read_ph_file ();
+static write_ph_file ();
+
+extern void exit();    /* to keep lint happy */
+
+FILE   *open_ph_file ();
+
+YP     lookup_type ();
+
+YT  lookup_tag ();
+
+/* \f   MAIN */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int    argc;
+char  **argv,
+      **envp;
+{
+    int            i;
+    register char  *cp,
+                  *dp;
+
+    dp = pepsyversion + strlen ("pepsy ");
+    (void) fprintf (stderr, "pepsy %s\n", dp);
+
+    sysout[0] = sysdef[0] = sysact[0] = NULL;
+    for (argc--, argv++; argc > 0; argc--, argv++) {
+       cp = *argv;
+
+       if (strcmp (cp, "-A") == 0) {
+           Aflag++;
+           continue;
+       }
+       if (strcmp (cp, "-a") == 0) {
+           aflag++;
+           continue;
+       }
+       if (strcmp (cp, "-C") == 0) {
+           Cflag = 0;
+           continue;
+       }
+       if (strcmp (cp, "-d") == 0) {
+           dflag++;
+           continue;
+       }
+       if (strcmp (cp, "-f") == 0) {
+           dflag++, fflag++;
+           continue;
+       }
+       if (strncmp (cp, "-h", 2) == 0) {
+           if (cp[2] == NULL) {
+               hflag++;
+               continue;
+           }
+           if (sscanf (cp + 2, "%d", &i) != 1 || i >= NOPTIONS)
+               goto usage;
+           hflag++, options[i]++;
+           continue;
+       }
+       if (strcmp (cp, "-m") == 0) {
+           mflag++;
+           continue;
+       }
+       if (strcmp (cp, "-s") == 0) {
+           sflag++;
+           continue;
+       }
+       if (strcmp (cp, "-i") == 0) {
+           argv++;
+           if (argc-- > 0)
+               iflag = *argv;
+           continue;
+       }
+
+       if (sysin) {
+    usage:  ;
+           (void) fprintf (stderr,
+                   "usage: pepsy [-A] [-a] [-C] [-d] [-f] [-h] [-s] module.py\n");
+           exit (1);
+       }
+
+       if (*cp == '-') {
+           if (*++cp != NULL)
+               goto usage;
+           sysin = "";
+       }
+       sysin = cp;
+    }
+
+    switch (pepydebug = (cp = getenv ("PEPSYTEST")) && *cp ? atoi (cp) : 0) {
+       case 2: 
+           yydebug++;          /* fall */
+       case 1: 
+           sflag++;            /*   .. */
+       case 0: 
+           break;
+    }
+
+    if (sysin == NULLCP)
+       sysin = "";
+
+    if (*sysin && freopen (sysin, "r", stdin) == NULL) {
+       (void) fprintf (stderr, "unable to read "), perror (sysin);
+       exit (1);
+    }
+
+    if (strcmp (sysout, "-") == 0)
+       sysout[0] = NULL;
+    if (*sysout && freopen (sysout, "w", stdout) == NULL) {
+       (void) fprintf (stderr, "unable to write "), perror (sysout);
+       exit (1);
+    }
+
+    if (cp = index (dp, ')')) {
+       for (cp++; *cp != ' '; cp++)
+           if (*cp == NULL)
+               break;
+       if (*cp == NULL)
+           cp = NULL;
+    }
+    if (cp == NULL)
+       cp = dp + strlen (dp);
+    (void) sprintf (autogen, "pepsy %*.*s", cp - dp, cp - dp, dp);
+
+    initoidtbl ();
+
+    exit (yyparse ());         /* NOTREACHED */
+}
+
+/* \f   ERRORS */
+
+yyerror (s)
+register char   *s;
+{
+    yyerror_aux (s);
+
+    if (*sysout)
+       (void) unlink (sysout);
+    if (*sysdef)
+       (void) unlink (sysdef);
+    if (*sysact)
+       (void) unlink (sysact);
+
+    exit (1);
+}
+
+#ifndef lint
+warning (va_alist)
+va_dcl
+{
+    char       buffer[BUFSIZ];
+    char       buffer2[BUFSIZ];
+    va_list    ap;
+
+    va_start (ap);
+
+    _asprintf (buffer, NULLCP, ap);
+
+    va_end (ap);
+
+    (void) sprintf (buffer2, "Warning: %s", buffer);
+    yyerror_aux (buffer2);
+}
+
+#else
+
+/* VARARGS1 */
+warning (fmt)
+char   *fmt;
+{
+    warning (fmt);
+}
+#endif
+
+static yyerror_aux (s)
+register char   *s;
+{
+    if (linepos)
+       (void) fprintf (stderr, "\n"), linepos = 0;
+
+    if (eval)
+       (void) fprintf (stderr, "type %s: ", eval);
+    else
+       (void) fprintf (stderr, "line %d: ", yylineno);
+    (void) fprintf (stderr, "%s\n", s);
+    if (!eval)
+       (void) fprintf (stderr, "last token read was \"%s\"\n", yytext);
+}
+
+/* \f */
+
+#ifndef        lint
+myyerror (va_alist)
+va_dcl
+{
+    char    buffer[BUFSIZ];
+    va_list ap;
+
+    va_start (ap);
+
+    _asprintf (buffer, NULLCP, ap);
+
+    va_end (ap);
+
+    yyerror (buffer);
+}
+#else
+/* VARARGS */
+
+myyerror (fmt)
+char   *fmt;
+{
+    myyerror (fmt);
+}
+#endif
+
+
+#ifndef        lint
+static pyyerror (va_alist)
+va_dcl
+{
+    char    buffer[BUFSIZ];
+    register YP        yp;
+    va_list    ap;
+
+    va_start (ap);
+
+    yp = va_arg (ap, YP);
+
+    _asprintf (buffer, NULLCP, ap);
+
+    va_end (ap);
+
+    yyerror_aux (buffer);
+    print_type (yp, 0);
+
+
+    if (*sysout)
+       (void) unlink (sysout);
+    if (*sysdef)
+       (void) unlink (sysdef);
+    if (*sysact)
+       (void) unlink (sysact);
+
+    exit (1);
+}
+#else
+/* VARARGS */
+
+static pyyerror (yp, fmt)
+YP     yp;
+char   *fmt;
+{
+    pyyerror (yp, fmt);
+}
+#endif
+
+/* \f */
+
+yywrap () {
+    if (linepos)
+       (void) fprintf (stderr, "\n"), linepos = 0;
+
+    return 1;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+yyprint (s, f, top)
+char    *s;
+int    f;
+int    top;
+{
+    int     len;
+    static int  nameoutput = 0;
+    static int  outputlinelen = 79;
+    static int didf = 0;
+
+    if (sflag || !s)
+       return;
+
+    if (f && didf == 0) {
+       if (linepos)
+           fprintf (stderr, "\n\n");
+       else fprintf (stderr, "\n");
+
+        fprintf (stderr, "%s includes:", mymodule);
+        linepos = (nameoutput = strlen (mymodule) + 10) + 1;
+
+        didf = 1;
+    }
+
+    if (!nameoutput || top) {
+       if (linepos)
+           (void) fprintf (stderr, "\n\n");
+
+       (void) fprintf (stderr, "%s", mymodule);
+       nameoutput = (linepos = strlen (mymodule)) + 1;
+
+#define section(flag,prefix) \
+        if (yysection & (flag)) { \
+            fprintf (stderr, " %s", (prefix)); \
+            linepos += strlen (prefix) + 1; \
+        } \
+        else \
+            fprintf (stderr, " none"), linepos += 5
+        section (YP_ENCODER, yyencpref);
+        section (YP_DECODER, yydecpref);
+        section (YP_PRINTER, yyprfpref);
+
+
+       (void) fprintf (stderr, ":");
+       linepos += 2;
+
+       if (top)
+           return;
+    }
+
+    len = strlen (s) + (f ? 2 : 0);
+    if (linepos != nameoutput)
+       if (len + linepos + 1 > outputlinelen)
+           (void) fprintf (stderr, "\n%*s", linepos = nameoutput, "");
+       else
+           (void) fprintf (stderr, " "), linepos++;
+    (void) fprintf (stderr, f ? "(%s)" : "%s", s);
+    linepos += len;
+}
+
+/* \f   PASS1 */
+
+pass1 ()
+{
+}
+
+/* \f */
+
+pass1_type (encpref, decpref, prfpref, mod, id, yp)
+register char  *encpref,
+              *decpref,
+              *prfpref,
+              *mod,
+              *id;
+register YP    yp;
+{
+    register SY            sy;
+
+    if (lookup_type (mod, id)) /* no duplicate entries, please... */
+       return;
+
+    if (pepydebug) {
+       if (linepos)
+           (void) fprintf (stderr, "\n"), linepos = 0;
+
+       (void) fprintf (stderr, "%s.%s\n", mod ? mod : mymodule, id);
+       print_type (yp, 0);
+       (void) fprintf (stderr, "--------\n");
+    }
+    else
+       if (!(yp -> yp_flags & YP_IMPORTED))
+           yyprint (id, 0, 0);
+
+    sy = new_symbol (encpref, decpref, prfpref, mod, id, yp);
+    mysymbols = add_symbol (mysymbols, sy);
+}
+
+static void hprologue (fp)
+FILE *fp;
+{
+#define NFILES         5
+    char *files[NFILES];
+    /* { "psap.h", "pepsy.h", "UNIV-types.h", (char *)0 }; */
+
+    int last = 0;              /* last slot available in files */
+    (void) fprintf (fp, "/* automatically generated by %s, do not edit! */\n\n",
+                   autogen);
+    (void) fprintf (fp, "#ifndef\t_module_%s_defined_\n", modulename);
+    (void) fprintf (fp, "#define\t_module_%s_defined_\n\n", modulename);
+
+    (void) fprintf (fp, "#ifndef\tPEPSY_VERSION\n");
+    (void) fprintf (fp, "#define\tPEPSY_VERSION\t\t%d\n", PEPSY_VERSION_NUMBER);
+    (void) fprintf (fp, "#endif\n\n");
+
+    files[last++] = "psap.h";
+    files[last++] = "pepsy.h";
+
+    if (strcmp (mymodule, "UNIV")) {
+       files[last++] = "pepsy/UNIV-types.h";
+    }
+
+    files[last++] = (char *)0;
+
+    doincl(fp, files);
+
+#undef NFILES
+}
+
+/* \f   PASS2 */
+
+pass2 () {
+    register SY            sy;
+    register YP            yp;
+
+
+    modsym_aux (mymodule, modulename);
+
+    (void) sprintf (sysdef, "%s%s", mymodule, Cflag ? "-t.tmp" : "-types.h");
+    if ((fdef = fopen (sysdef, "w")) == NULL)
+       myyerror ("unable to write %s", sysdef);
+    if (!Cflag)
+       hprologue (fdef);
+
+
+    if (!Cflag) {
+       if (mflag) {
+           (void) fprintf (fdef, "#ifndef\tPEPYPATH\n");
+           (void) fprintf (fdef, "#include <isode/pepsy/%s%s>\n", mymodule, HFILE1);
+           (void) fprintf (fdef, "#else\n");
+           (void) fprintf (fdef, "#include \"%s%s\"\n", mymodule, HFILE1);
+           (void) fprintf (fdef, "#endif\n");
+       }
+       else
+           (void) fprintf (fdef, "#include \"%s%s\"\n", mymodule, HFILE1);
+    }
+    /* User's #include file */
+    if (iflag) {
+       (void) fprintf (fdef, "#include \"%s\"\n", iflag);
+    }
+
+    /*
+     * pull up some symbols 
+     */
+    for (sy = mysymbols; sy; sy = sy -> sy_next) {
+       eval = sy -> sy_name;
+       yp = sy -> sy_type;
+       if (sy -> sy_module == NULLCP)
+           yyerror ("no module name associated with symbol");
+       if (yp -> yp_flags & YP_IMPORTED)
+           continue;
+
+       do_struct0 (yp, eval);
+       if (ferror (stdout) || ferror (fdef))
+           myyerror ("write error - %s", sys_errname (errno));
+    }
+    /* dump out the references to the external types */
+    proc_extmod(fdef);
+
+    /*
+     * generate the #define's for simple type definitions
+     */
+    for (sy = mysymbols; sy; sy = sy -> sy_next) {
+       eval = sy -> sy_name;
+       yp = sy -> sy_type;
+       if (yp -> yp_flags & YP_IMPORTED)
+           continue;
+
+       do_struct1 (yp, eval, NULLCP);
+       if (ferror (stdout) || ferror (fdef))
+           myyerror ("write error - %s", sys_errname (errno));
+    }
+
+    /*
+     * generate the C structure definitions
+     */
+    for (sy = mysymbols; sy; sy = sy -> sy_next) {
+       eval = sy -> sy_name;
+       yp = sy -> sy_type;
+       if (yp -> yp_flags & YP_IMPORTED)
+           continue;
+
+       do_struct2 (yp, eval, NULLCP);
+       if (ferror (stdout) || ferror (fdef))
+           myyerror ("write error - %s", sys_errname (errno));
+    }
+
+    peri_pass2();
+
+    (void) fprintf (fdef, "#endif\n");
+    (void) fflush (fdef);
+    (void) fflush (stdout);
+    if (ferror (stdout) || ferror (fdef))
+       myyerror ("write error - %s", sys_errname (errno));
+    (void) fclose (fdef);
+
+    if (Cflag)
+       merge_files (mymodule);
+
+    write_ph_file();
+    if (!sflag) {
+       if (linepos) fprintf (stderr, "\n"), linepos = 0;
+       (void) fflush (stderr);
+    }
+}
+
+static void copy_file (fp1, fp2)
+FILE *fp1, *fp2;
+{
+    char buf[BUFSIZ];
+    int n;
+
+    while ((n = fread (buf, 1, BUFSIZ, fp1)) > 0) {
+       if (fwrite (buf, 1, n, fp2) != n) {
+           fprintf (stderr, "Write error\n");
+           exit (1);
+       }
+    }
+}
+
+static void merge_files (stem)
+char *stem;
+{
+    FILE *fpin, *fpout;
+    char fname[BUFSIZ];
+    char buf[BUFSIZ];
+
+    (void) sprintf (fname, "%s-types.h", stem);
+    if ((fpout = fopen (fname, "w")) == NULL)
+       myyerror ("unable to write %s", fname);
+
+    hprologue (fpout);
+    (void) sprintf (buf, "%s%s", stem, HFILE2);
+    if ((fpin = fopen (buf, "r")) == NULL)
+       myyerror ("unable to read file %s", buf);
+    copy_file (fpin, fpout);
+    (void) fclose (fpin);
+    (void) unlink (buf);
+
+    (void) sprintf (buf, "%s%s", stem, HFILE1);
+    if ((fpin = fopen (buf, "r")) == NULL)
+       myyerror ("unable to read file %s", buf);
+    copy_file (fpin, fpout);
+    (void) fclose (fpin);
+    (void) unlink (buf);
+
+    (void) sprintf (buf, "%s-t.tmp", stem);
+    if ((fpin = fopen (buf, "r")) == NULL)
+       myyerror ("unable to read file %s", buf);
+    copy_file (fpin, fpout);
+    (void) fclose (fpin);
+    (void) unlink (buf);
+
+    if (fclose (fpout) == EOF) {
+       fprintf (stderr, "Write error to file");
+       perror ("");
+       exit (1);
+    }
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static do_struct0 (yp, id)
+register YP    yp;
+char   *id;
+{
+    register YP            y;
+    MD md;
+
+    switch (yp -> yp_code) {
+       case YP_SEQLIST:
+       case YP_SETLIST:
+           components_pullup (yp);
+           break;
+
+       default:
+           break;
+    }
+
+    switch (yp -> yp_code) {
+       case YP_SEQTYPE: 
+       case YP_SETTYPE: 
+           do_struct0 (yp -> yp_type, id);
+           break;
+
+       case YP_CHOICE: 
+       case YP_SETLIST: 
+           choice_pullup (yp, yp -> yp_code == YP_CHOICE ? CH_FULLY
+                                                         : CH_PARTIAL);
+           /* and fall */
+       case YP_SEQLIST: 
+           for (y = yp -> yp_type; y; y = y -> yp_next)
+               do_struct0 (y, id);
+           break;
+
+       case YP_IDEFINED: 
+           if (yp -> yp_module && strcmp (yp -> yp_module, mymodule)) {
+               if ((md = lookup_module (yp -> yp_module, yp -> yp_modid))
+                 == NULLMD || (md->md_flags & MDF_SEEN) == 0) {
+                       addextmod(yp -> yp_module);
+                   if (md)
+                       md->md_flags |= MDF_SEEN;
+               }
+           }
+           /* correct for IMPLICIT Tag of a CHOICE or ANY if possible */
+           if ((yp->yp_flags & (YP_IMPLICIT|YP_TAG)) == (YP_IMPLICIT|YP_TAG)) {
+               yp->yp_flags &= ~YP_IMPLICIT; /* clear it */
+               yp->yp_flags |= comptag(YP_IMPLICIT, yp);
+           }
+           break;
+
+       default: 
+           break;
+    }
+}
+
+/* \f */
+
+static do_struct1 (yp, id, pullup)
+register YP    yp;
+char   *id,
+       *pullup;
+{
+    register int    i,
+                    j;
+    char    buf1[BUFSIZ];
+    register YP            y;
+    register YV            yv;
+
+    switch (yp -> yp_code) {
+       case YP_BIT: 
+       case YP_BITLIST: 
+       case YP_SEQ: 
+       case YP_SET: 
+       case YP_ANY: 
+           (void) fprintf (fdef, "\n");
+           if (aflag)
+               printag (yp, 4, pullup);
+           (void) fprintf (fdef, "#define\t%s\tPElement\n",
+                   modsym (mymodule, id, "type"));
+           if (yp -> yp_code == YP_BITLIST) {
+               i = -1;
+               for (yv = yp -> yp_value; yv; yv = yv -> yv_next)
+                   if ((j = val2int (yv)) < 0)
+                       pyyerror (yp, "invalid bit number in BIT STRING");
+                   else
+                       if (j > i)
+                           i = j;
+               if (i < sizeof (int) * 8) {     /* NBBY */
+                   (void) fprintf (fdef, "#define\t%s\t\"\\020",
+                           modsym (mymodule, eval, "bits"));
+                   for (yv = yp -> yp_value; yv; yv = yv -> yv_next)
+                       if (yv -> yv_flags & YV_NAMED)
+                           (void) fprintf (fdef, "\\0%o%s",
+                                   val2int (yv) + 1, yv -> yv_named);
+                       else
+                           (void) fprintf (fdef, "\\0%oBIT%d",
+                                   val2int (yv) + 1, val2int (yv));
+                   (void) fprintf (fdef, "\"\n");
+               }
+               for (yv = yp -> yp_value; yv; yv = yv -> yv_next) {
+                   modsym_aux (yv -> yv_named, buf1);
+                   (void) fprintf (fdef, "#define\t%s_%s\t%d\n",
+                           modsym (mymodule, eval, "bit"),
+                           buf1, val2int (yv));
+               }
+           }
+           if (fflag)
+               (void) fprintf (fdef, "#define\t%s\tpe_free\n",
+                       modsym (mymodule, id, "free"));
+           break;
+
+       case YP_OCT: 
+           (void) fprintf (fdef, "\n");
+           if (aflag)
+               printag (yp, 4, pullup);
+           (void) fprintf (fdef, "#define\t%s\tqbuf\n",
+                   modsym (mymodule, id, "type"));
+           if (fflag)
+               (void) fprintf (fdef, "#define\t%s\tqb_free\n",
+                       modsym (mymodule, id, "free"));
+           break;
+
+       case YP_OID: 
+           (void) fprintf (fdef, "\n");
+           if (aflag)
+               printag (yp, 4, pullup);
+           (void) fprintf (fdef, "#define\t%s\tOIDentifier\n",
+                   modsym (mymodule, id, "type"));
+           if (fflag)
+               (void) fprintf (fdef, "#define\t%s\toid_free\n",
+                       modsym (mymodule, id, "free"));
+           break;
+
+       case YP_IDEFINED: 
+           (void) fprintf (fdef, "\n");
+           if (aflag)
+               printag (yp, 4, pullup);
+           (void) fprintf (fdef, "#define\t%s\t",
+                   modsym (mymodule, id, "type"));
+           (void) fprintf (fdef, "%s\n",
+                   modsym (yp -> yp_module, yp -> yp_identifier, "type"));
+           if (fflag) {
+               (void) fprintf (fdef, "#define\t%s\t",
+                       modsym (mymodule, id, "free"));
+               (void) fprintf (fdef, "%s\n",
+                       modsym (yp -> yp_module, yp -> yp_identifier, "free"));
+           }
+           break;
+
+       case YP_SEQLIST: 
+       case YP_SETLIST: 
+       case YP_CHOICE: 
+           if (hflag && (y = yp -> yp_type) && !y -> yp_next) {
+               do_struct1 (y, id, tags[yp -> yp_code]);
+               break;
+           }
+       /* else fall */
+
+       default: 
+           break;
+    }
+}
+
+/* \f */
+
+static do_struct2 (yp, id, pullup)
+register YP    yp;
+char   *id,
+       *pullup;
+{
+    register YP            y;
+    int        flg = (yp -> yp_code == YP_SEQTYPE || yp -> yp_code == YP_SETTYPE);
+
+    switch (yp -> yp_code) {
+       case YP_BIT: 
+       case YP_BITLIST: 
+       case YP_SEQ: 
+       case YP_SET: 
+       case YP_ANY: 
+       case YP_OCT: 
+       case YP_OID: 
+       case YP_IDEFINED: 
+           break;
+
+       case YP_SEQLIST: 
+       case YP_SETLIST: 
+       case YP_CHOICE: 
+           if (hflag && (y = yp -> yp_type) && !y -> yp_next) {
+               do_struct2 (y, id, tags[yp -> yp_code]);
+               break;
+           }
+           /* else fall */
+
+       default: 
+           (void) fprintf (fdef, "\n");
+           if (aflag)
+               printag (yp, 4, pullup);
+           (void) fprintf (fdef, "struct %s {\n", modsym (mymodule, id, "type"));
+           pepsy (yp, 1, 1, "parm", id, "parm", flg && h2flag);
+           (void) fprintf (fdef, "};\n");
+           (void) fprintf (fdef, "#define\t%s(parm)\\\n\t%s\n", modsym (mymodule, id, "free"), gfree(mymodule, id, "parm"));
+               
+           break;
+    }
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static do_type1 (yp, top, level, id, var, action2, direction)
+register YP yp;
+int    top,
+       level;
+char   *id,
+       *var,
+       *action2;
+int    direction;
+{
+    int            i;
+    char   *cp,
+          *ep,
+           buffer[BUFSIZ],
+           varbuf[BUFSIZ];
+    register YP            y;
+    register YV            yv;
+    register YT            yt;
+
+    (void) printf ("%*s", level * 4, "");
+
+    if (yp -> yp_flags & YP_ID) {
+       (void) printf ("%s", yp -> yp_id);
+       if (!(yp -> yp_flags & YP_TAG))
+           (void) printf ("\n%*s", ++level * 4, "");
+    }
+
+    if (yp -> yp_flags & YP_TAG) {
+       yt = yp -> yp_tag;
+       (void) printf ("[%s%d]\n", classes[yt -> yt_class], val2int (yt -> yt_value));
+       level++;
+       (void) printf ("%*s", level * 4, "");
+    }
+    if (yp -> yp_flags & YP_OPTIONAL && yp -> yp_varexp) {
+       if ((ep = index (yp -> yp_varexp, ' ')) == NULL)
+           yyerror ("Bug in varexp!");
+
+       (void) sprintf (varbuf, "%*.*s", ep - yp -> yp_varexp,
+                       ep - yp -> yp_varexp, yp -> yp_varexp);
+    }
+
+    switch (yp -> yp_code) {
+       case YP_BOOL: 
+           if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) &&
+               direction == YP_DECODER) {
+               if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG)))
+                   (void) printf ("dummy-for-default\n%*s", ++level * 4, "");
+               if (yp -> yp_flags & YP_OPTIONAL)
+                   (void) printf ("%%{ %s -> optionals |= %s; %%}\n%*s",
+                           varbuf, yp -> yp_optcontrol, level * 4, "");
+               else
+                   (void) printf ("%%{ %s%s = %d; %%}\n%*s",
+                           var, SVAL (yp -> yp_varexp),
+                           val2int (yp -> yp_default) ? 1 : 0, level * 4, "");
+           }
+           break;
+
+       case YP_INT: 
+           if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) &&
+               direction == YP_DECODER) {
+               if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG)))
+                   (void) printf ("dummy-for-default\n%*s", ++level * 4, "");
+               if (yp -> yp_flags & YP_OPTIONAL)
+                   (void) printf ("%%{ %s -> optionals |= %s; %%}\n%*s",
+                           varbuf, yp -> yp_optcontrol, level * 4, "");
+               else
+                   (void) printf ("%%{ %s%s = %d; %%}\n%*s",
+                           var, SVAL (yp -> yp_varexp),
+                           val2int (yp -> yp_default), level * 4, "");
+           }
+           break;
+
+       case YP_INTLIST:
+       case YP_ENUMLIST:
+           if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) &&
+               direction == YP_DECODER) {
+               if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG)))
+                   (void) printf ("dummy-for-default\n%*s", ++level * 4, "");
+               if (yp -> yp_flags & YP_OPTIONAL)
+                   (void) printf ("%%{ %s -> optionals |= %s; %%}\n%*s",
+                           varbuf, yp -> yp_optcontrol, level * 4, "");
+               else
+                   (void) printf ("%%{ %s%s = %d; %%}\n%*s",
+                           var, SVAL (yp -> yp_varexp), dfl2int (yp),
+                           level * 4, "");
+           }
+           break;
+
+       case YP_REAL: 
+           if ((yp -> yp_flags & (YP_OPTIONAL|YP_DEFAULT)) &&
+               direction == YP_DECODER) {
+               if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG)))
+                   (void) printf ("dummy-for-default\n%*s", ++level * 4, "");
+               if (yp -> yp_flags & YP_OPTIONAL)
+                   (void) printf ("%%{ %s -> optionals |= %s; %%}\n%*s",
+                           varbuf, yp -> yp_optcontrol, level * 4, "");
+               else
+                   (void) printf ("%%{ %s%s = %g; %%}\n%*s",
+                           var, SVAL (yp -> yp_varexp),
+                           val2real (yp -> yp_default), level * 4, "");
+           }
+           break;
+
+       case YP_NULL:
+           if ((yp -> yp_flags & YP_OPTIONAL) && direction == YP_DECODER) {
+               if (!top && !(yp -> yp_flags & (YP_ID | YP_TAG)))
+                   (void) printf ("dummy-for-default\n%*s", ++level * 4, "");
+               (void) printf ("%%{ %s -> optionals |= %s; %%}\n%*s",
+                       varbuf, yp -> yp_optcontrol, level * 4, "");
+           }
+           break;
+    }
+
+    if ((yp -> yp_flags & (YP_TAG | YP_IMPLICIT)) == (YP_TAG | YP_IMPLICIT))
+       (void) printf ("IMPLICIT ");
+    if (yp -> yp_flags & YP_BOUND)
+       (void) printf ("%s < ", yp -> yp_bound);
+    if (yp -> yp_flags & YP_COMPONENTS)
+       (void) printf ("COMPONENTS OF ");
+    if (yp -> yp_flags & YP_ENCRYPTED)
+       (void) printf ("ENCRYPTED ");
+
+    switch (yp -> yp_code) {
+       case YP_BOOL: 
+           (void) printf ("BOOLEAN");
+           switch (direction) {
+               case YP_ENCODER: 
+               case YP_DECODER: 
+                   (void) printf (top ? "\n%*s[[b %s -> %s ]]" : "\n%*s[[b %s%s ]]",
+                           level * 4, "", var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+           break;
+
+       case YP_INT: 
+           (void) printf ("INTEGER");
+           switch (direction) {
+               case YP_ENCODER: 
+               case YP_DECODER: 
+                   (void) printf (top ? "\n%*s[[i %s -> %s ]]" : "\n%*s[[i %s%s ]]",
+                           level * 4, "", var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+           break;
+
+       case YP_INTLIST:
+       case YP_ENUMLIST:
+           if (yp -> yp_code == YP_ENUMLIST)
+               (void) printf ("ENUMERATED");
+           else
+               (void) printf ("INTEGER");
+           switch (direction) {
+               case YP_ENCODER: 
+               case YP_DECODER: 
+                   (void) printf (top ? "\n%*s[[i %s -> %s ]]\n%*s{\n"
+                           : "\n%*s[[i %s%s ]]\n%*s{\n",
+                           level * 4, "", var, SVAL (yp -> yp_varexp),
+                           level * 4, "");
+                   break;
+
+               default: 
+                   (void) printf (" {\n");
+                   break;
+           }
+           level++;
+           for (yv = yp -> yp_value; yv; yv = yv -> yv_next)
+               (void) printf ("%*s%s(%d)%s\n", level * 4, "", yv -> yv_named,
+                       val2int (yv), yv -> yv_next ? "," : "");
+           level--;
+           (void) printf ("%*s}", level * 4, "");
+           break;
+
+       case YP_BIT: 
+           (void) printf ("BIT STRING");
+           switch (direction) {
+               case YP_ENCODER: 
+                   (void) printf ("\n%*s[[x bit_parm = bitstr2strb (%s%s, &len) $ len]]",
+                           level * 4, "", var, SVAL (yp -> yp_varexp));
+                   (void) printf ("\n%*s%%{\n%*sfree (bit_parm);\n", level * 4, "",
+                           (level + 1) * 4, "");
+                   if (action2)
+                       (void) printf ("%*s%s\n", (level + 1) * 4, "", action2);
+                   (void) printf ("%*s%%}\n", level * 4, "");
+                   break;
+
+               case YP_DECODER: 
+                   balloc (yp, var, action2, level);
+                   break;
+           }
+           break;
+
+       case YP_BITLIST: 
+           (void) printf ("BIT STRING");
+           switch (direction) {
+               case YP_ENCODER: 
+                   (void) printf ("\n%*s[[x bit_parm = bitstr2strb (%s%s, &len) $ len]]\n%*s{\n",
+                           level * 4, "", var, SVAL (yp -> yp_varexp),
+                           level * 4, "");
+                   break;
+
+               case YP_DECODER: 
+               default: 
+                   (void) printf (" {\n");
+                   break;
+           }
+           level++;
+           for (yv = yp -> yp_value; yv; yv = yv -> yv_next)
+               (void) printf ("%*s%s(%d)%s\n", level * 4, "", yv -> yv_named,
+                       val2int (yv), yv -> yv_next ? "," : "");
+           level--;
+           (void) printf ("%*s}", level * 4, "");
+           switch (direction) {
+               case YP_DECODER: 
+                   balloc (yp, var, action2, level);
+                   break;
+
+               case YP_ENCODER:
+                   (void) printf ("\n%*s%%{\n%*sfree (bit_parm);\n", level * 4, "",
+                           (level + 1) * 4, "");
+                   if (action2)
+                       (void) printf ("%*s%s\n", (level + 1) * 4, "", action2);
+                   (void) printf ("%*s%%}\n", level * 4, "");
+                   break;
+           }
+           break;
+
+       case YP_OCT: 
+           (void) printf ("OCTET STRING");
+           switch (direction) {
+               case YP_ENCODER: 
+                   (void) printf ("\n%*s[[q %s%s ]]", level * 4, "",
+                           var, SVAL (yp -> yp_varexp));
+                   break;
+
+               case YP_DECODER: 
+                   (void) printf ("\n%*s[[q %s%s ]]", level * 4, "",
+                           var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+           break;
+
+       case YP_REAL:
+           (void) printf ("REAL");
+           (void) printf (top ? "\n%*s[[r %s -> %s ]]" : "\n%*s[[r %s%s ]]",
+                   level * 4, "", var, SVAL (yp -> yp_varexp));
+           break;
+
+       case YP_NULL: 
+           (void) printf ("NULL");
+           break;
+
+       case YP_SEQ: 
+       case YP_SET:
+       case YP_ANY:
+           (void) printf ("%s", tags[yp -> yp_code]);
+           switch (direction) {
+               case YP_ENCODER:
+               case YP_DECODER:
+                       (void) printf ("\n%*s[[a %s%s ]]",
+                               level * 4, "", var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+           break;
+
+       case YP_SEQTYPE: 
+       case YP_SETTYPE: 
+           ep = yp -> yp_code != YP_SETTYPE ? "element" : "member";
+           (void) printf ("%s\n", tags [yp -> yp_code]);
+           switch (direction) {
+               case YP_ENCODER: 
+                   if ((y = yp -> yp_type) -> yp_declexp) {
+                       (void) printf ("%*s%%{ %s = %s; %%}\n",
+                               (level + 1) * 4, "", y -> yp_declexp,
+                               SVAL (y -> yp_varexp));
+                   }
+                   if (h2flag) {
+                       if (top) {
+                           (void) printf ("%*s<<n_parm = 0; ", (level + 1) * 4, "");
+                           (void) printf ("n_parm < parm -> nelem; n_parm++>>\n");
+                       }
+                       else {
+                           (void) printf ("%*s<<n_%s = 0;\n%*sn_%s < %s -> nelem;\n",
+                                   (level + 1) * 4, "", yp -> yp_declexp,
+                                   (level + 3) * 4, "", yp -> yp_declexp,
+                                   yp -> yp_declexp);
+                           (void) printf ("%*sn_%s++>>\n",
+                                   (level + 3) * 4, "", yp -> yp_declexp);
+                       }
+                   }
+                   else {
+                       if (top)
+                           (void) printf ("%*s<<; parm; parm = parm -> next>>\n",
+                                   (level + 1) * 4, "");
+                       else
+                           (void) printf ("%*s<<%s = %s%s;\n%*s%s;\n%*s%s = %s -> next>>\n",
+                                   (level + 1) * 4, "", yp -> yp_declexp,
+                                   var, SVAL (yp -> yp_varexp),
+                                   (level + 3) * 4, "", yp -> yp_declexp,
+                                   (level + 3) * 4, "", yp -> yp_declexp,
+                                   yp -> yp_declexp);
+                   }
+                   break;
+
+               case YP_DECODER: 
+                   if (h2flag) {
+                       y = yp -> yp_type;
+                       xalloc (y, 0, level + 2, y -> yp_declexp,
+                               y -> yp_declexp, 1);
+                   }
+                   else
+                       xalloc (yp, 0, level + 1,
+                               top ? "parm" : yp -> yp_declexp,
+                               top ? modsym (mymodule, eval, "type")
+                               : yp -> yp_declexp, 1);
+                   break;
+           }
+           do_type1 (yp -> yp_type, 0, level + 1, ep, "", NULLCP, direction);
+           switch (direction) {
+               case YP_DECODER:
+                   (void) printf ("\n%*s%%{ ", (level + 1) * 4, "");
+                   if (h2flag)
+                       (void) printf ("n_%s++;", top ? "parm" : yp -> yp_declexp);
+                   else
+                       if (top)
+                           (void) printf ("parm = &((*parm) -> next);");
+                       else
+                           (void) printf ("%s = &((*%s) -> next);",
+                                   yp -> yp_declexp, yp -> yp_declexp);
+                   if (action2)
+                       (void) printf (" %s", action2);
+                   (void) printf (" %%}");
+                   break;
+           }
+           break;
+
+       case YP_SEQLIST: 
+       case YP_SETLIST: 
+           ep = yp -> yp_code != YP_SETLIST ? "element" : "member";
+           (void) printf ("%s", tags [yp -> yp_code]);
+           (void) printf ("\n%*s%%{\n", (level + 1) * 4, "");
+           if (direction == YP_DECODER)
+               xalloc (yp, 1, level + 2, yp -> yp_declexp,
+                       yp -> yp_declexp, 0);
+           for (y = yp -> yp_type; y; y = y -> yp_next) {
+               if (y -> yp_declexp)
+                   switch (direction) {
+                   case YP_ENCODER: 
+                       (void) printf ("%*s%s = %s;\n",
+                               (level + 2) * 4, "",
+                               y -> yp_declexp, y -> yp_varexp);
+                       break;
+
+                   case YP_DECODER:
+                       (void) printf ("%*s%s = &(%s);\n",
+                               (level + 2) * 4, "",
+                               y -> yp_declexp, y -> yp_varexp);
+                       break;
+                   }
+               if (direction == YP_DECODER &&
+                        y -> yp_flags & YP_DEFAULT) {
+                   prime_default (y, level + 2);
+               }
+           }
+           (void) printf ("%*s%%}\n%*s{\n", (level + 1) * 4, "",
+                   level * 4, "");
+           
+           if (!hflag || !(y = yp -> yp_type) || y -> yp_next) {
+               var = "";
+               top = 0;
+           }
+           for (y = yp -> yp_type; y; y = y -> yp_next) {
+               do_type1 (y, top,
+                       level + ((y -> yp_flags & (YP_ID | YP_TAG)) ? 1 : 2),
+                       ep, var, NULLCP, direction);
+               (void) printf ("%s\n", y -> yp_next ? ",\n" : "");
+           }
+           (void) printf ("%*s}", level * 4, "");
+           break;
+
+       case YP_CHOICE: 
+           (void) printf ("CHOICE");
+           if (!hflag || !(y = yp -> yp_type) || y -> yp_next)
+               var = "";
+           i = 0;
+           for (y = yp -> yp_type; y; y = y -> yp_next)
+               if (y -> yp_declexp)
+                   i++;
+           switch (direction) {
+               case YP_ENCODER: 
+                   if (i) {
+                       (void) printf ("\n%*s%%{\n", (level + 1) * 4, "");
+                       for (y = yp -> yp_type; y; y = y -> yp_next)
+                           if (y -> yp_declexp)
+                               (void) printf ("%*s%s = %s;\n", (level + 2) * 4, "",
+                                       y -> yp_declexp, y -> yp_varexp);
+                       (void) printf ("%*s%%}\n%*s", (level + 1) * 4, "",
+                               (level + 1) * 4 - 1, "" );
+                   }
+                   if (*var)
+                       (void) printf (" <<1>>");
+                   else
+                       if (top)
+                           (void) printf (" <<parm -> offset>>");
+                       else
+                           (void) printf (" <<%s -> offset>>",
+                                   yp -> yp_declexp);
+                   (void) printf (i ? "\n%*s{\n" : " {\n", level * 4, "");
+                   break;
+
+               case YP_DECODER: 
+                   (void) printf ("\n");
+                   xalloc (yp, 0, level + 1, yp -> yp_declexp,
+                           yp -> yp_declexp, 1);
+                   (void) printf ("%*s{\n", level * 4, "");
+                   break;
+
+               default: 
+                   (void) printf (" {\n");
+                   break;
+           }
+           if (direction == YP_DECODER) {
+               (void) sprintf (cp = buffer, "(*(%s)) -> offset = ",
+                           top ? "parm" : yp -> yp_declexp);
+               cp += strlen (cp);
+           }
+           else
+               cp = NULL;
+           if (!hflag || !(y = yp -> yp_type) || y -> yp_next)
+               top = 0;
+           else
+               if (top)
+                   cp = NULL;
+           for (y = yp -> yp_type; y; y = y -> yp_next) {
+               if (cp)
+                   (void) sprintf (cp, "%s;", y -> yp_offset);
+               do_type1 (y, top, level + 1, "choice", var,
+                       cp ? buffer : NULLCP, direction);
+               (void) printf ("%s\n", y -> yp_next ? ",\n" : "");
+           }
+           (void) printf ("%*s}", level * 4, "");
+           break;
+       
+       case YP_OID: 
+           (void) printf ("OBJECT IDENTIFIER");
+           switch (direction) {
+               case YP_ENCODER: 
+               case YP_DECODER: 
+                   (void) printf ("\n%*s[[O %s%s ]]",
+                           level * 4, "", var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+           break;
+
+       case YP_IDEFINED: 
+           if (yp -> yp_module && strcmp (yp -> yp_module, mymodule))
+               (void) printf ("%s.", yp -> yp_module);
+           (void) printf ("%s", yp -> yp_identifier);
+           switch (direction) {
+               case YP_ENCODER: 
+                   (void) printf ("\n%*s[[p %s%s ]]",
+                           level * 4, "", var, SVAL (yp -> yp_varexp));
+                   break;
+
+               case YP_DECODER: 
+                   (void) printf ("\n%*s[[p &(%s%s)]]",
+                           level * 4, "", var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+           break;
+
+       default: 
+           myyerror ("unknown type: %d", yp -> yp_code);
+    }
+
+    if (action2)
+       switch (yp -> yp_code) {
+           case YP_BIT:
+           case YP_BITLIST:
+               if (direction == YP_ENCODER)
+                   break;
+           case YP_SEQTYPE:
+           case YP_SETTYPE:
+               if (direction == YP_DECODER)
+                   break;
+               /* else fall */
+
+           default:            
+               (void) printf ("\n%*s%%{ %s %%}", level * 4, "", action2);
+               break;
+       }
+
+    if (yp -> yp_flags & YP_OPTIONAL) {
+       (void) printf ("\n%*sOPTIONAL", level * 4, "");
+
+       if (direction == YP_ENCODER)
+           switch (yp -> yp_code) {
+               case YP_BOOL: 
+               case YP_INT: 
+               case YP_INTLIST:
+               case YP_ENUMLIST:
+               case YP_NULL:
+               case YP_REAL:
+                   (void) printf (" <<%s -> optionals & %s >>",
+                           varbuf, yp -> yp_optcontrol);
+               default: 
+                   break;
+
+               case YP_BIT: 
+               case YP_BITLIST: 
+               case YP_OCT: 
+               case YP_SEQ: 
+               case YP_SEQTYPE: 
+               case YP_SEQLIST: 
+               case YP_SET: 
+               case YP_SETTYPE: 
+               case YP_SETLIST: 
+               case YP_CHOICE: 
+               case YP_ANY: 
+               case YP_OID: 
+               case YP_IDEFINED: 
+                   (void) printf (" <<%s%s>>", var, SVAL (yp -> yp_varexp));
+                   break;
+           }
+    }
+    else
+       if (yp -> yp_flags & YP_DEFAULT) {
+           (void) printf ("\n%*sDEFAULT ", level * 4, "");
+           val2prf (yp -> yp_default, level + 2);
+
+           if (direction == YP_ENCODER)
+               switch (yp -> yp_code) {
+                   case YP_BOOL: 
+                       (void) printf (" <<%s%s%s>>",
+                               val2int (yp -> yp_default) ? "!" : "",
+                               var, SVAL (yp -> yp_varexp));
+                       break;
+
+                   case YP_INT: 
+                   case YP_INTLIST:
+                   case YP_ENUMLIST:
+                       (void) printf (" <<%s%s != %d>>", var, SVAL (yp -> yp_varexp),
+                               dfl2int (yp));
+                       break;
+
+                   case YP_REAL:
+                       (void) printf (" << %s%s != %g >>",
+                               var, SVAL (yp -> yp_varexp),
+                               val2real (yp -> yp_default));
+                       break;
+
+                   case YP_NULL: 
+                   default: 
+                       break;
+
+                   case YP_BIT: 
+                   case YP_BITLIST: 
+                   case YP_OCT: 
+                   case YP_SEQ: 
+                   case YP_SEQTYPE: 
+                   case YP_SEQLIST: 
+                   case YP_SET: 
+                   case YP_SETTYPE: 
+                   case YP_SETLIST: 
+                   case YP_CHOICE: 
+                   case YP_ANY: 
+                   case YP_OID: 
+                   case YP_IDEFINED: 
+                       (void) printf (" <<%s%s>>", var, SVAL (yp -> yp_varexp));
+                       break;
+               }
+       }
+
+    if (direction == YP_ENCODER
+           && yp -> yp_varexp
+           && (cp = index (yp -> yp_varexp, ' '))
+           && strncmp (cp + 1, "-> ", 3) == 0) {
+       *cp = NULL;
+       (void) sprintf (buffer, "(*%s) -> %s", yp -> yp_varexp, cp + 4);
+       yp -> yp_varexp = new_string (buffer);
+    }
+}
+
+/* \f   TYPE HANDLING */
+
+YP  lookup_type (mod, id)
+register char *mod,
+             *id;
+{
+    register SY            sy;
+
+    for (sy = mysymbols; sy; sy = sy -> sy_next) {
+       if (mod) {
+           if (strcmp (sy -> sy_module, mod))
+               continue;
+       }
+       else
+           if (strcmp (sy -> sy_module, mymodule)
+                   && strcmp (sy -> sy_module, "UNIV"))
+               continue;
+
+       if (strcmp (sy -> sy_name, id) == 0)
+           return sy -> sy_type;
+    }
+
+    return NULLYP;
+}
+
+/* \f */
+
+pepsy (yp, top, level, id, val, var, arrayflg)
+register YP    yp;
+int    top,
+       level,
+        arrayflg;
+char   *id,
+       *val,
+       *var;
+{
+    register int    i,
+                   j;
+    register char  *bp;
+    char   *cp,
+          *dp,
+           *ep,
+          *newid,
+            buf1[BUFSIZ],
+           buf2[BUFSIZ],
+           buf3[BUFSIZ];
+    register YP            y;
+    register YV            yv;
+
+    (void) strcpy (bp = buf2, var);
+    bp += strlen (bp);
+    /* Preserve the name of the field */
+    yp->yp_varexp = new_string(yp -> yp_ptrname ? yp -> yp_ptrname : id);
+
+    switch (yp -> yp_code) {
+       case YP_BOOL: 
+           if (aflag)
+               printag (yp, level + 4, NULLCP);
+           (void) fprintf (fdef, "%*schar    %s;\n", level * 4, "",
+                    array(id, arrayflg));
+           break;
+
+       case YP_INT: 
+       case YP_INTLIST:
+       case YP_ENUMLIST:
+           if (aflag)
+               printag (yp, level + 4, NULLCP);
+           (void) fprintf (fdef, "%*sinteger     %s;\n", level * 4, "",
+                    array(id, arrayflg));
+           if (yp -> yp_code == YP_INT)
+               break;
+           for (yv = yp -> yp_value; yv; yv = yv -> yv_next) {
+               modsym_aux (yv -> yv_named, buf1);
+               (void) fprintf (fdef, "#define\t%s_%s\t%d\n",
+                       modsym (mymodule, top ? eval : id, "int"),
+                       buf1, val2int (yv));
+           }
+           break;
+
+       case YP_BIT: 
+       case YP_BITLIST: 
+           if (!top) {
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sPE      %s;\n", level * 4, "",
+                        array(id, arrayflg));
+           }
+           if (yp -> yp_code != YP_BITLIST)
+               break;
+           i = -1;
+           for (yv = yp -> yp_value; yv; yv = yv -> yv_next)
+               if ((j = val2int (yv)) < 0)
+                   pyyerror (yp, "invalid bit number in BIT STRING");
+               else
+                   if (j > i)
+                       i = j;
+           if (i < sizeof (int) * 8) {         /* NBBY */
+               (void) fprintf (fdef, "#define\t%s\t\"\\020",
+                       modsym (mymodule, top ? eval : id, "bits"));
+               for (yv = yp -> yp_value; yv; yv = yv -> yv_next)
+                   if (yv -> yv_flags & YV_NAMED)
+                       (void) fprintf (fdef, "\\0%o%s",
+                               val2int (yv) + 1, yv -> yv_named);
+                   else
+                       (void) fprintf (fdef, "\\0%oBIT%d",
+                               val2int (yv) + 1, val2int (yv));
+               (void) fprintf (fdef, "\"\n");
+           }
+           for (yv = yp -> yp_value; yv; yv = yv -> yv_next) {
+               modsym_aux (yv -> yv_named, buf1);
+               (void) fprintf (fdef, "#define\t%s_%s\t%d\n",
+                       modsym (mymodule, top ? eval : id, "bit"),
+                       buf1, val2int (yv));
+           }
+           break;
+
+       case YP_REAL: 
+           if (aflag)
+               printag (yp, level + 4, NULLCP);
+           (void) fprintf (fdef, "%*sdouble    %s;\n", level * 4, "",
+                    array(id, arrayflg));
+           yp -> yp_varexp = new_string (buf2);
+           break;
+
+       case YP_OCT: 
+           if (!top) {
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sstruct qbuf *%s;\n", level * 4, "",
+                        array(id, arrayflg));
+           }
+           break;
+
+       case YP_NULL: 
+           if (aflag)
+               printag (yp, level + 4, NULLCP);
+           (void) fprintf (fdef, "%*schar    %s;\n", level * 4, "",
+                    array(id, arrayflg));
+           break;
+
+       case YP_SEQ: 
+       case YP_SET: 
+       case YP_ANY: 
+           if (!top) {
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sPE      %s;\n", level * 4, "",
+                        array(id, arrayflg));
+           }
+           break;
+
+       case YP_SEQTYPE: 
+       case YP_SETTYPE: 
+           ep = yp -> yp_code != YP_SETTYPE ? "element" : "member";
+           if ((cp = rindex (buf2, ' ')) && *++cp) {
+               if ((dp = rindex (cp, '.')) && *++dp)
+                   cp = dp;
+               (void) sprintf (dp = buf1, "%*.*s",
+                       cp - buf2, cp - buf2, buf2);
+               dp += strlen (dp);
+           }
+           else {
+               (void) strcpy (buf1, buf2);
+               dp = NULL;
+           }
+           newid = yp -> yp_ptrname ? yp -> yp_ptrname : id;
+           if (h2flag && top)
+               (void) fprintf (fdef, "%*sinteger\tnelem;\n", level * 4, "");
+           if (!top) {
+               if (yp -> yp_structname)
+                   id = yp -> yp_structname;
+               else if (!Hflag)
+                   id = gensym (ep, NULLCP);
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sstruct %s {\n", level * 4, "", id);
+               if (h2flag)
+                   (void) fprintf (fdef, "%*sinteger\tnelem;\n", (level + 1) * 4, "");
+           }
+           if (dp)
+               (void) strcpy (dp, newid);
+           (void) strcpy (bp = buf2, id);
+           bp += strlen (bp);
+
+           if (!top)
+               yp -> yp_declexp = new_string (id);
+
+           if (dp)
+               (void) strcpy (dp, newid);
+           if ((y = yp -> yp_type) -> yp_code == YP_IDEFINED && hflag) {
+               modsym_aux (y -> yp_identifier, cp = buf3);
+               if (h2flag) {
+                   cp += strlen(cp);
+                   (void) sprintf (cp, "[n_%s]", PARVAL (yp->yp_declexp));
+                   cp = buf3;
+               }
+           }
+           else {
+               switch (y -> yp_code) {
+               case YP_SEQLIST:
+               case YP_SETLIST:
+               case YP_SETTYPE:
+               case YP_SEQTYPE:
+               case YP_CHOICE:
+               case YP_IDEFINED:
+                   cp = gensym (ep, h2flag ? PARVAL(yp->yp_declexp) : NULLCP);
+                   break;
+               default:
+                   cp = gensym (ep, NULLCP);
+                   break;
+               }
+           }
+           (void) sprintf (bp, " -> %s", cp);
+           level++;
+           pepsy (y, 0, level, cp, ep, buf2, h2flag);
+           *bp = NULL;
+           if (y -> yp_code != YP_IDEFINED)
+               free (cp);
+           if (!h2flag)
+               (void) fprintf (fdef, "\n%*sstruct %s *next;\n", level * 4, "",
+                        top ? modsym (mymodule, val, "type") : id);
+
+           level--;
+
+           (void) strcpy (bp = buf2, var);
+           bp += strlen (bp);
+
+           if (!top) {
+               (void) fprintf (fdef, "%*s} *%s;\n", level * 4, "",
+                        array(newid, arrayflg));
+               if (!Hflag)
+                   free (id);
+           }
+           break;
+
+       case YP_SEQLIST: 
+       case YP_SETLIST: 
+           ep = yp -> yp_code != YP_SETLIST ? "element" : "member";
+           if ((cp = rindex (buf2, ' ')) && *++cp) {
+               if ((dp = rindex (cp, '.')) && *++dp)
+                   cp = dp;
+               (void) sprintf (dp = buf1, "%*.*s",
+                       cp - buf2, cp - buf2, buf2);
+               dp += strlen (dp);
+           }
+           else {
+               (void) strcpy (buf1, buf2);
+               dp = NULL;
+           }
+           newid = yp -> yp_ptrname ? yp -> yp_ptrname : id;
+           if (!top) {
+               if (yp -> yp_structname)
+                   id = yp -> yp_structname;
+               else if (!Hflag)
+                   id = gensym (ep, NULLCP);
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sstruct %s {\n", level * 4, "", id);
+
+               if (dp)
+                   (void) strcpy (dp, newid);
+
+               (void) strcpy (bp = buf2, id);
+               bp += strlen (bp);
+               yp -> yp_declexp = new_string (id);
+
+               level++;
+           }
+           if (dp)
+               (void) strcpy (dp, newid);
+           for (y = yp -> yp_type, i = 0; y; y = y -> yp_next) {
+               if (y -> yp_flags & YP_OPTIONAL)
+                   switch (y -> yp_code) {
+                       case YP_BOOL:
+                       case YP_INT:
+                       case YP_INTLIST:
+                       case YP_ENUMLIST:
+                       case YP_REAL:
+                       case YP_NULL:
+                           {
+                               char obuf[BUFSIZ];
+                               
+                               if (i == 0)
+                                   (void) fprintf (fdef, "%*sinteger     optionals;\n",
+                                            level * 4, "");
+                               if (y -> yp_flags & YP_ID)
+                                   modsym_aux (y -> yp_id, cp = buf1);
+                               else {
+                                   cp = gensym (ep, NULLCP);
+                                   (void) strcpy (buf1, cp);
+                                   free (cp);
+                                   cp = buf1;
+                               }
+                               (void) sprintf (obuf, "%s_%s",
+                                               modsym (mymodule,
+                                                       top ? eval : id,
+                                                       "opt"), cp);
+                               (void) fprintf (fdef, "#define\t%s (0%08o)\n", obuf,
+                                        1 << i);
+#ifdef ASN1_OUTPUT
+                               y -> yp_optcontrol = new_string (obuf);
+                               y -> yp_flags |= YP_OPTCONTROL;
+#endif
+
+                               i ++;
+                               if (i >= 8 * sizeof (int))
+                                   yyerror ("too many optionals in structure");
+                           }
+                           break;
+                       }
+           }
+           if (i > 0) (void) fprintf (fdef, "\n");
+
+           for (y = yp -> yp_type, i = 1; y; y = y -> yp_next, i++) {
+               if (y -> yp_flags & YP_ID)
+                   modsym_aux (y -> yp_id, cp = buf1);
+               else
+                   cp = gensym (ep, NULLCP);
+               (void) sprintf (bp, " -> %s", cp);
+               pepsy (y, 0, level, cp, ep, buf2, 0);
+               *bp = NULL;
+               if (!(y -> yp_flags & YP_ID))
+                   free (cp);
+               if (y -> yp_next)
+                   (void) fprintf (fdef, "\n");
+           }
+           if (i == 1)
+               (void) fprintf (fdef, "%*schar    dummy;\n", level * 4, "");
+           if (!top) {
+               level--;
+
+               (void) strcpy (bp = buf2, var);
+               bp += strlen (bp);
+
+               (void) fprintf (fdef, "%*s} *%s;\n", level * 4, "",
+                        array(newid, arrayflg));
+               if (!Hflag)
+                   free (id);
+           }
+           break;
+
+       case YP_CHOICE: 
+           if ((cp = rindex (buf2, ' ')) && *++cp) {
+               if ((dp = rindex (cp, '.')) && *++dp)
+                   cp = dp;
+               (void) sprintf (dp = buf1, "%*.*s",
+                       cp - buf2, cp - buf2, buf2);
+               dp += strlen (dp);
+           }
+           else {
+               (void) strcpy (buf1, buf2);
+               dp = NULL;
+           }
+           newid = yp -> yp_ptrname ? yp -> yp_ptrname : id;
+           if (!top) {
+               if (yp -> yp_structname)
+                   id = yp -> yp_structname;
+               else if (!Hflag)
+                   id = gensym ("choice", NULLCP);
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sstruct %s {\n", level * 4, "", id);
+
+               if (dp)
+                   (void) strcpy (dp, newid);
+               (void) strcpy (bp = buf2, id);
+               bp += strlen (bp);
+               yp -> yp_declexp = new_string (id);
+
+               level++;
+           }
+           if (dp)
+               (void) strcpy (dp, newid);
+           (void) fprintf (fdef, "%*sint         offset;\n", level * 4, "");
+           if (top)
+               cp = modsym (mymodule, val, "type");
+           else
+               cp = id;
+           (void) sprintf (ep = buf1, "%s_", cp);
+           ep += strlen (ep);
+           for (y = yp -> yp_type, i = 1; y; y = y -> yp_next, i++) {
+               if (y -> yp_flags & YP_ID)
+                   modsym_aux (y -> yp_id, ep);
+               else
+                   (void) sprintf (ep, "%d", i);
+               y -> yp_offset = new_string (buf1);
+               (void) fprintf (fdef, "#define\t%s\t%d\n", y -> yp_offset, i);
+           }
+           (void) fprintf (fdef, "\n%*sunion {\n", level * 4, "");
+           level++;
+           for (y = yp -> yp_type; y; y = y -> yp_next) {
+               char    *t;
+
+               if (y -> yp_flags & YP_ID)
+                   modsym_aux (y -> yp_id, cp = buf1);
+               else
+                   cp = gensym ("choice", NULLCP);
+               (void) sprintf (bp, " -> un.%s", cp);
+               pepsy (y, 0, level, cp, "choice", buf2, 0);
+    /* prefix yp_varexp (field name) with un. so we will generate offsets that
+     * allow for the union all the CHOICE fields are imbedded in
+     */
+               t = y->yp_varexp;
+               y->yp_varexp = my_strcat("un.",  t);
+               free(t);
+
+               *bp = NULL;
+               if (!(y -> yp_flags & YP_ID))
+                   free (cp);
+               if (y -> yp_next)
+                   (void) fprintf (fdef, "\n");
+           }
+           level--;
+           (void) fprintf (fdef, "%*s}       un;\n", level * 4, "");
+           if (!top) {
+               level--;
+
+               (void) strcpy (bp = buf2, var);
+               bp += strlen (bp);
+
+               (void) fprintf (fdef, "%*s} *%s;\n", level * 4, "",
+                        array(newid, arrayflg));
+               if (!Hflag)
+                   free (id);
+           }
+           break;
+
+       case YP_OID: 
+           if (!top) {
+               if (aflag)
+                   printag (yp, level + 4, NULLCP);
+               (void) fprintf (fdef, "%*sOID     %s;\n", level * 4, "",
+                        array(id, arrayflg));
+           }
+           break;
+
+       case YP_IDEFINED: 
+           if (aflag)
+               printag (yp, level + 4, NULLCP);
+           {
+               /* Predefined Universal Type */
+               struct univ_typ *p;
+               if ((p = univtyp(yp->yp_identifier))) {
+                   (void) fprintf (fdef, "%*s%s%s;\n", level * 4, "",
+                       p->univ_data, array(id, arrayflg));
+                   /*
+                    if (fflag)
+                        ferr(1, "pepsy:YP_IDEFINED:fflag not implemented\n");
+                   */
+                   break;
+               }
+           }
+           (void) fprintf (fdef, "%*sstruct %s *%s;\n", level * 4, "",
+                   modsym (yp -> yp_module, yp -> yp_identifier, "type"),
+                   array(id, arrayflg));
+           break;
+
+       default: 
+           myyerror ("unknown type: %d", yp -> yp_code);
+    }
+}
+
+/* \f */
+
+static printag (yp, level, pullup)
+register YP    yp;
+int    level;
+char   *pullup;
+{
+    (void) fprintf (fdef, "%*s/* ", level * 4, "");
+    switch (yp -> yp_code) {
+       case YP_IDEFINED: 
+           if (yp -> yp_module && strcmp (yp -> yp_module, mymodule))
+               (void) fprintf (fdef, "%s.", yp -> yp_module);
+           (void) fprintf (fdef, "%s", yp -> yp_identifier);
+           break;
+
+       default: 
+           (void) fprintf (fdef, "%s", tags[yp -> yp_code]);
+           break;
+    }
+    if (pullup)
+       (void) fprintf (fdef, " pulled up from %s", pullup);
+    (void) fprintf (fdef, " */\n");
+}
+
+/* \f */
+
+static xalloc (yp, top, level, arg, type, brackets)
+register YP    yp;
+int    top,
+       level,
+       brackets;
+char   *arg,
+       *type;
+{
+    int            didone;
+    register YP            y;
+
+    if (hflag && !arg && !type)
+       return;
+
+    didone = 0;
+
+    if (arg && type) {
+       if (brackets && !didone) {
+           (void) printf ("%*s%%{\n", level * 4, "");
+           level++, didone++;
+       }
+
+       if (h2flag && (yp -> yp_code == YP_SEQTYPE ||
+                      yp -> yp_code == YP_SETTYPE)) {
+           (void) printf ("%*s{\n%*sPE      xx_pe = prim2%s ($$);\n\n",
+                   level * 4, "", (level +1) * 4, "",
+                   yp -> yp_code == YP_SEQTYPE ? "seq" : "set");
+           (void) printf ("%*sn_%s = xx_pe -> pe_cardinal > 0 ",
+                   (level + 1) * 4, "", arg);
+           (void) printf ("? xx_pe -> pe_cardinal : 0;\n%*s}\n", level * 4, "");
+           (void) printf ("%*sif ((*(%s) = (struct %s *)\n",
+                   level * 4, "", arg, type);
+           (void) printf ("%*scalloc (1 + (unsigned) n_%s, sizeof **(%s)",
+                   (level + 2) * 4, "", arg, arg);
+           (void) printf (")) == ((struct %s *) 0)) {\n", type);
+           (void) printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n",
+                   (level + 1) * 4, "");
+           (void) printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "",
+                   level * 4, "");
+           (void) printf ("%*s(*%s) -> nelem = n_%s;\n", level * 4, "", arg, arg);
+           (void) printf ("%*sn_%s = 0;\n", level * 4, "", arg);
+       } else {
+           (void) printf ("%*sif ((*(%s) = (struct %s *)\n",
+                   level * 4, "", arg, type);
+           (void) printf ("%*scalloc (1, sizeof **(%s))) == ((struct %s *) 0)) {\n",
+                   (level + 2) * 4, "", arg, type);
+           (void) printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n",
+                   (level + 1) * 4, "");
+           (void) printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "",
+                   level * 4, "");
+       }
+    }
+    switch (yp -> yp_code) {
+    case YP_SEQTYPE:
+    case YP_SETTYPE:
+       if (top) break;
+    case YP_CHOICE:
+    case YP_SEQLIST:
+    case YP_SETLIST:
+       for (y = yp -> yp_type; y; y = y -> yp_next)
+           switch (y -> yp_code) {
+           case YP_SEQTYPE: 
+           case YP_SETTYPE:
+               if (h2flag && (yp -> yp_code == YP_SETLIST ||
+                              yp -> yp_code == YP_SEQLIST)) {
+                   /* include allocation here - no chance later */
+                   if (brackets && !didone) {
+                       (void) printf ("%*s%%{\n", level * 4, "");
+                       level++, didone++;
+                   }
+                   if (y -> yp_declexp)
+                       (void) printf ("%*s%s = &(%s);\n", level * 4, "",
+                               y -> yp_declexp,
+                               y -> yp_varexp);
+                   xalloc (y, top, level, y -> yp_declexp,
+                           y -> yp_declexp, 0);
+               }
+               /* and continue ... */
+           case YP_SEQLIST: 
+           case YP_SETLIST: 
+           case YP_CHOICE:
+               if (brackets && !didone) {
+                   (void) printf ("%*s%%{\n", level * 4, "");
+                   level++, didone++;
+               }
+               (void) printf ("%*s%s = &(%s);\n",
+                       level * 4, "", y -> yp_declexp,
+                       y -> yp_varexp);
+               break;
+           }
+       break;
+    }
+
+    if (brackets && didone) {
+       level--;
+       (void) printf ("%*s%%}\n", level * 4, "");
+    }
+}
+
+
+static balloc (yp, var, action2, level)
+register YP    yp;
+char   *var, *action2;
+int    level;
+{
+    (void) printf ("\n%*s%%{\n", level * 4, "");
+    level++;
+
+    (void) printf ("%*sif ((%s%s = prim2bit (pe_cpy ($$))) == NULLPE) {\n",
+           level * 4, "", var, SVAL (yp -> yp_varexp));
+    (void) printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n", (level + 1) * 4, "");
+    (void) printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", level * 4, "");
+
+    if (action2)
+       (void) printf ("\n%*s%s\n", level * 4, "", action2);
+
+    level--;
+    (void) printf ("%*s%%}", level * 4, "");
+}
+
+#ifdef notdef
+static qalloc (yp, var, action2, level)
+register YP    yp;
+char   *var,
+       *action2;
+int    level;
+{
+    (void) printf ("\n%*s%%{\n", level * 4, "");
+    level++;
+
+    (void) printf ("%*sif ((%s%s = str2qb ($$, $$_len, 1)) == ((struct qbuf *) 0)) {\n",
+           level * 4, "", var, SVAL (yp -> yp_varexp));
+    (void) printf ("%*sadvise (NULLCP, \"%%s\", PEPY_ERR_NOMEM);\n", (level + 1) * 4, "");
+    (void) printf ("%*sreturn NOTOK;\n%*s}\n", (level + 1) * 4, "", level * 4, "");
+
+    if (action2)
+       (void) printf ("\n%*s%s\n", level * 4, "", action2);
+
+    level--;
+    (void) printf ("%*s%%}", level * 4, "");
+}
+#endif
+
+/* \f */
+
+/*
+ * now we don't pull up things if they have actions associated with them
+ * this should be okay for those who want exact posy equivalence and
+ * yet keep those who want the pepy support able to have multiple
+ * actions in CHOICE { CHOICE {} } and such like
+ */
+static choice_pullup (yp, partial)
+register YP    yp;
+int    partial;
+{
+    register YP           *x,
+                   y,
+                   z,
+                  *z1,
+                   z2,
+                   z3;
+
+    for (x = &yp -> yp_type; y = *x; x = &y -> yp_next) {
+       if (y -> yp_flags & (YP_TAG | YP_BOUND))
+           continue;
+
+       switch (y -> yp_code) {
+           case YP_IDEFINED:
+               if ((z = lookup_type (y -> yp_module, y -> yp_identifier))
+                       == NULLYP
+                       || z -> yp_code != YP_CHOICE)
+                   continue;
+               if (z -> yp_control_act || z ->yp_bef_alist || z-> yp_aft_alist)
+                   continue;
+
+               choice_pullup (z2 = copy_type (z), CH_FULLY);
+               if (y -> yp_flags & YP_OPTIONAL) {
+                   z2 -> yp_flags |= YP_OPTIONAL;
+                   partial = 1;
+               }
+               if (y -> yp_flags & YP_DEFAULT) {
+                   z2 -> yp_flags |= YP_DEFAULT;
+                   z2 -> yp_default = copy_value (y -> yp_default);
+                   partial = 1;
+               }
+               goto patch;
+
+           case YP_CHOICE:
+               if (y -> yp_control_act || y ->yp_bef_alist || y-> yp_aft_alist)
+                   continue;
+
+               choice_pullup (z2 = copy_type (y), CH_FULLY);
+patch: ;
+               if (partial) {
+                   *x = z2;
+                   z2 -> yp_next =  y -> yp_next;
+                   continue;
+               }
+               break;
+
+           default:
+               continue;
+       }
+       z = z3 = z2 -> yp_type;
+       for (z1 = &z -> yp_next; z2 = *z1; z1 = &z2 -> yp_next)
+           z3 = z2;
+       *z1 = y -> yp_next;
+       *x = z;
+       y = z3;
+    }
+}
+
+/* \f */
+
+static components_pullup (yp)
+register YP    yp;
+{
+    register YP    *x,
+                   y,
+                   z,
+                   z1,
+                   z2;
+
+    for (x = &yp -> yp_type; y = *x; x = &y -> yp_next) {
+       if (!(y -> yp_flags & YP_COMPONENTS))
+           continue;
+
+       switch (y -> yp_code) {
+           case YP_SEQLIST:
+           case YP_SETLIST:
+               z = y;
+               break;
+
+           case YP_IDEFINED:
+               if ((z = lookup_type (y -> yp_module, y -> yp_identifier))
+                       == NULLYP) {
+                   warning ("COMPONENTS OF target \"%s\" is undefined",
+                            y -> yp_identifier);
+                   continue;
+               }
+               break;
+       }
+       if (yp -> yp_code != z -> yp_code) {
+           warning ("COMPONENTS OF target \"%s\" is wrong type, should be %s",
+                    y -> yp_code == YP_IDEFINED ? y -> yp_identifier
+                                                : y -> yp_id ? y -> yp_id
+                                                : "",
+                    yp -> yp_code == YP_SEQLIST ? "SEQUENCE" : "SET");
+           continue;
+       }
+       if (z -> yp_type == NULLYP)
+           continue;
+       components_pullup (z = copy_type (z));
+       *x = z2 = z -> yp_type;
+       for (x = &z -> yp_type; z1 = *x; x = &z1 -> yp_next)
+           z2 = z1;
+       *x = y -> yp_next;
+       y = z2;
+    }
+}
+
+/* \f   VALUE HANDLING */
+
+static int  val2int (yv)
+register YV    yv;
+{
+    switch (yv -> yv_code) {
+       case YV_BOOL:
+       case YV_NUMBER:
+           return yv -> yv_number;
+
+       case YV_STRING:
+           yyerror ("need an integer, not a string");
+
+       case YV_IDEFINED:
+       case YV_IDLIST:
+           yyerror ("haven't written symbol table for values yet");
+
+       case YV_NULL:
+           yyerror ("need an integer, not NULL");
+
+       default:
+           myyerror ("unknown value: %d", yv -> yv_code);
+    }
+/* NOTREACHED */
+}
+
+static double  val2real (yv)
+register YV    yv;
+{
+    switch (yv -> yv_code) {
+       case YV_NUMBER:
+           return yv -> yv_number;
+
+       case YV_REAL:
+           return yv -> yv_real;
+
+       case YV_STRING:
+           yyerror ("need an integer, not a string");
+
+       case YV_IDEFINED:
+       case YV_IDLIST:
+           yyerror ("haven't written symbol table for values yet");
+
+       case YV_NULL:
+           yyerror ("need an integer, not NULL");
+
+       default:
+           myyerror ("unknown value: %d", yv -> yv_code);
+    }
+/* NOTREACHED */
+}
+
+/* \f */
+
+static val2prf (yv, level)
+register YV    yv;
+int    level;
+{
+    register YV    y;
+
+    if (yv -> yv_flags & YV_ID)
+       (void) printf ("%s ", yv -> yv_id);
+
+    if (yv -> yv_flags & YV_TYPE)      /* will this REALLY work??? */
+       do_type1 (yv -> yv_type, 0, level, NULLCP, NULLCP, NULLCP, NULL);
+
+    switch (yv -> yv_code) {
+       case YV_BOOL: 
+           (void) printf (yv -> yv_number ? "TRUE" : "FALSE");
+           break;
+
+       case YV_NUMBER: 
+           if (yv -> yv_named)
+               (void) printf ("%s", yv -> yv_named);
+           else
+               (void) printf ("%d", yv -> yv_number);
+           break;
+
+       case YV_REAL:
+           dump_real (yv -> yv_real);
+           break;
+
+       case YV_STRING: 
+           (void) printf ("\"%s\"", yv -> yv_string);
+           break;
+
+       case YV_IDEFINED: 
+           if (yv -> yv_module)
+               (void) printf ("%s.", yv -> yv_module);
+           (void) printf ("%s", yv -> yv_identifier);
+           break;
+
+       case YV_IDLIST: 
+       case YV_VALIST: 
+           (void) printf ("{");
+           for (y = yv -> yv_idlist; y; y = y -> yv_next) {
+               (void) printf (" ");
+               val2prf (y, level + 1);
+               (void) printf (y -> yv_next ? ", " : " ");
+           }
+           (void) printf ("}");
+           break;
+
+       case YV_NULL: 
+           (void) printf ("NULL");
+           break;
+
+       default: 
+           myyerror ("unknown value: %d", yv -> yv_code);
+       /* NOTREACHED */
+    }
+}
+static dump_real (r)
+double r;
+{
+#ifndef        BSD44
+       extern char *ecvt ();
+       char    *cp;
+       char    sbuf[128];
+       int     decpt, sign;
+
+       cp = ecvt (r, 20, &decpt, &sign);
+       (void) strcpy (sbuf, cp);       /* cp gets overwritten by printf */
+       (void) printf ("{ %s%s, 10, %d }", sign ? "-" : "", sbuf,
+               decpt - strlen (sbuf));
+#else
+    register char   *cp,
+                   *dp,
+                   *sp;
+    char    sbuf[128];
+
+    (void) sprintf (sbuf, "%.19e", r);
+    if (*(dp = sbuf) == '-')
+       sp = "-", dp++;
+    else
+       sp = "";
+    
+    if (dp[1] != '.' || (cp = index (dp, 'e')) == NULL) {
+       (void) printf ("{ 0, 10, 0 } -- %s --", sbuf);
+       return;
+    }
+    *cp++ = NULL;
+    (void) printf ("{ %s%c%s, 10, %d }",
+           sp, *dp, dp + 2, atoi (cp) - strlen (dp + 2));
+#endif
+}
+
+/* \f */
+
+static int  dfl2int (yp)
+register YP    yp;
+{
+    register YV            yv,
+                   y;
+
+    yv = yp -> yp_default;
+    switch (yv -> yv_code) {
+       case YV_BOOL:
+       case YV_NUMBER:
+           return yv -> yv_number;
+
+       case YV_STRING:
+           yyerror ("need an integer, not a string");
+
+       case YV_REAL:
+           yyerror ("need an integer, not a real");
+
+       case YV_IDEFINED:
+           for (y = yp -> yp_value; y; y = y -> yv_next)
+               if (y -> yv_code == YV_NUMBER
+                       && (y -> yv_flags & YV_NAMED)
+                       && strcmp (yv -> yv_identifier, y -> yv_named) == 0)
+                   return y -> yv_number;
+           /* and fall */
+
+       case YV_IDLIST:
+           yyerror ("haven't written symbol table for values yet");
+
+       case YV_NULL:
+           yyerror ("need an integer, not NULL");
+
+       default:
+           myyerror ("unknown value: %d", yv -> yv_code);
+    }
+/* NOTREACHED */
+}
+
+/* \f   DEBUG */
+
+print_type (yp, level)
+register YP    yp;
+register int   level;
+{
+    register YP            y;
+    register YV            yv;
+
+    if (yp == NULLYP)
+       return;
+
+    (void) fprintf (stderr, "%*scode=0x%x flags=%s direction=0x%x\n", level * 4, "",
+           yp -> yp_code, sprintb (yp -> yp_flags, YPBITS),
+           yp -> yp_direction);
+    (void) fprintf (stderr,
+           "%*sintexp=\"%s\" strexp=\"%s\" prfexp=0%o declexp=\"%s\" varexp=\"%s\"\n",
+           level * 4, "", yp -> yp_intexp, yp -> yp_strexp, yp -> yp_prfexp,
+           yp -> yp_declexp, yp -> yp_varexp);
+    if (yp -> yp_param_type)
+       (void) fprintf (stderr, "%*sparameter type=\"%s\"\n", level * 4, "",
+                yp -> yp_param_type);
+    if (yp -> yp_action0)
+       (void) fprintf (stderr, "%*saction0 at line %d=\"%s\"\n", level * 4, "",
+               yp -> yp_act0_lineno, yp -> yp_action0);
+    if (yp -> yp_action05)
+       (void) fprintf (stderr, "%*saction05 at line %d=\"%s\"\n", level * 4, "",
+               yp -> yp_act05_lineno, yp -> yp_action05);
+    if (yp -> yp_action1)
+       (void) fprintf (stderr, "%*saction1 at line %d=\"%s\"\n", level * 4, "",
+               yp -> yp_act1_lineno, yp -> yp_action1);
+    if (yp -> yp_action2)
+       (void) fprintf (stderr, "%*saction2 at line %d=\"%s\"\n", level * 4, "",
+               yp -> yp_act2_lineno, yp -> yp_action2);
+    if (yp -> yp_action3)
+       (void) fprintf (stderr, "%*saction3 at line %d=\"%s\"\n", level * 4, "",
+               yp -> yp_act3_lineno, yp -> yp_action3);
+
+    if (yp -> yp_flags & YP_TAG) {
+       (void) fprintf (stderr, "%*stag class=0x%x value=0x%x\n", level * 4, "",
+               yp -> yp_tag -> yt_class, yp -> yp_tag -> yt_value);
+       print_value (yp -> yp_tag -> yt_value, level + 1);
+    }
+
+    if (yp -> yp_flags & YP_DEFAULT) {
+       (void) fprintf (stderr, "%*sdefault=0x%x\n", level * 4, "", yp -> yp_default);
+       print_value (yp -> yp_default, level + 1);
+    }
+
+    if (yp -> yp_flags & YP_ID)
+       (void) fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yp -> yp_id);
+
+    if (yp -> yp_flags & YP_BOUND)
+       (void) fprintf (stderr, "%*sbound=\"%s\"\n", level * 4, "", yp -> yp_bound);
+
+    if (yp -> yp_offset)
+       (void) fprintf (stderr, "%*soffset=\"%s\"\n", level * 4, "", yp -> yp_offset);
+
+    switch (yp -> yp_code) {
+       case YP_INTLIST:
+        case YP_ENUMLIST:
+       case YP_BITLIST:
+           (void) fprintf (stderr, "%*svalue=0x%x\n", level * 4, "", yp -> yp_value);
+           for (yv = yp -> yp_value; yv; yv = yv -> yv_next) {
+               print_value (yv, level + 1);
+               (void) fprintf (stderr, "%*s----\n", (level + 1) * 4, "");
+           }
+           break;
+
+       case YP_SEQTYPE:
+       case YP_SEQLIST:
+       case YP_SETTYPE:
+       case YP_SETLIST:
+       case YP_CHOICE:
+           (void) fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yp -> yp_type);
+           for (y = yp -> yp_type; y; y = y -> yp_next) {
+               print_type (y, level + 1);
+               (void) fprintf (stderr, "%*s----\n", (level + 1) * 4, "");
+           }
+           break;
+
+       case YP_IDEFINED:
+           (void) fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n",
+                   level * 4, "", yp -> yp_module ? yp -> yp_module : "",
+                   yp -> yp_identifier);
+           break;
+
+       default:
+           break;
+    }
+}
+
+/* \f */
+
+static print_value (yv, level)
+register YV    yv;
+register int   level;
+{
+    register YV            y;
+
+    if (yv == NULLYV)
+       return;
+
+    (void) fprintf (stderr, "%*scode=0x%x flags=%s\n", level * 4, "",
+           yv -> yv_code, sprintb (yv -> yv_flags, YVBITS));
+
+    if (yv -> yv_action)
+       (void) fprintf (stderr, "%*saction at line %d=\"%s\"\n", level * 4, "",
+               yv -> yv_act_lineno, yv -> yv_action);
+
+    if (yv -> yv_flags & YV_ID)
+       (void) fprintf (stderr, "%*sid=\"%s\"\n", level * 4, "", yv -> yv_id);
+
+    if (yv -> yv_flags & YV_NAMED)
+       (void) fprintf (stderr, "%*snamed=\"%s\"\n", level * 4, "", yv -> yv_named);
+
+    if (yv -> yv_flags & YV_TYPE) {
+       (void) fprintf (stderr, "%*stype=0x%x\n", level * 4, "", yv -> yv_type);
+       print_type (yv -> yv_type, level + 1);
+    }
+
+    switch (yv -> yv_code) {
+       case YV_NUMBER:
+       case YV_BOOL:
+           (void) fprintf (stderr, "%*snumber=0x%x\n", level * 4, "",
+                   yv -> yv_number);
+           break;
+
+       case YV_STRING:
+           (void) fprintf (stderr, "%*sstring=\"%s\"\n", level * 4, "",
+                   yv -> yv_string);
+           break;
+
+       case YV_IDEFINED:
+           if (yv -> yv_flags & YV_BOUND)
+               (void) fprintf (stderr, "%*smodule=\"%s\" identifier=\"%s\"\n",
+                       level * 4, "", yv -> yv_module, yv -> yv_identifier);
+           else
+               (void) fprintf (stderr, "%*sbound identifier=\"%s\"\n",
+                       level * 4, "", yv -> yv_identifier);
+           break;
+
+       case YV_IDLIST:
+       case YV_VALIST:
+           for (y = yv -> yv_idlist; y; y = y -> yv_next) {
+               print_value (y, level + 1);
+               (void) fprintf (stderr, "%*s----\n", (level + 1) * 4, "");
+           }
+           break;
+
+       default:
+           break;
+    }
+}
+
+/* \f   SYMBOLS */
+
+static SY  new_symbol (encpref, decpref, prfpref, mod, id, type)
+register char  *encpref,
+              *decpref,
+              *prfpref,
+              *mod,
+              *id;
+register YP    type;
+{
+    register SY    sy;
+
+    if ((sy = (SY) calloc (1, sizeof *sy)) == NULLSY)
+       yyerror ("out of memory");
+    sy -> sy_encpref = encpref;
+    sy -> sy_decpref = decpref;
+    sy -> sy_prfpref = prfpref;
+    sy -> sy_module = mod;
+    sy -> sy_name = id;
+    sy -> sy_type = type;
+
+    return sy;
+}
+
+
+static SY  add_symbol (s1, s2)
+register SY    s1,
+               s2;
+{
+    register SY            sy;
+
+    if (s1 == NULLSY)
+       return s2;
+
+    for (sy = s1; sy -> sy_next; sy = sy -> sy_next)
+       continue;
+    sy -> sy_next = s2;
+
+    return s1;
+}
+
+/* \f   MODULES */
+
+MD  lookup_module (module, oid)
+char   *module;
+OID    oid;
+{
+    register MD            md;
+
+    for (md = mymodules; md; md = md -> md_next) {
+       if (module && md -> md_module && strcmp (md -> md_module, module) == 0)
+           return md;
+       if (oid && md -> md_oid && oid_cmp(oid, md->md_oid) == 0)
+           return md;
+    }
+
+    read_ph_file (module, oid);
+
+    if ((md = (MD) calloc (1, sizeof *md)) == NULLMD)
+       yyerror ("out of memory");
+    md -> md_module = new_string (module);
+    if (oid)
+       md -> md_oid = oid_cpy(oid);
+    else
+       md -> md_oid = NULLOID;
+
+    if (mymodules != NULLMD)
+       md -> md_next = mymodules;
+
+    return (mymodules = md);
+}
+
+/* \f   TYPES */
+
+YP     new_type (code, lineno)
+int    code;
+int    lineno;
+{
+    register YP    yp;
+
+    if ((yp = (YP) calloc (1, sizeof *yp)) == NULLYP)
+       yyerror ("out of memory");
+    yp -> yp_code = code;
+    yp -> yp_lineno = lineno;
+
+    return yp;
+}
+
+
+YP     add_type (y, z)
+register YP    y,
+               z;
+{
+    register YP            yp;
+
+    for (yp = y; yp -> yp_next; yp = yp -> yp_next)
+       continue;
+    yp -> yp_next = z;
+
+    return y;
+}
+
+/* \f */
+
+YP     copy_type (yp)
+register YP    yp;
+{
+    register YP            y;
+
+    if (yp == NULLYP)
+       return NULLYP;
+
+    y = new_type (yp -> yp_code, yp -> yp_lineno);
+    y -> yp_direction = yp -> yp_direction;
+
+    switch (yp -> yp_code) {
+       case YP_IDEFINED:
+           if (yp -> yp_module)
+               y -> yp_module = new_string (yp -> yp_module);
+           y -> yp_identifier = new_string (yp -> yp_identifier);
+           y -> yp_modid = oid_cpy (yp -> yp_modid);
+           break;
+
+       case YP_SEQTYPE:
+       case YP_SEQLIST:
+       case YP_SETTYPE:
+       case YP_SETLIST:
+       case YP_CHOICE:
+           y -> yp_type = copy_type (yp -> yp_type);
+           break;
+
+       case YP_INTLIST:
+       case YP_ENUMLIST:
+       case YP_BITLIST:
+           y -> yp_value = copy_value (yp -> yp_value);
+           break;
+
+       default:
+           break;
+    }
+
+    y -> yp_intexp = yp -> yp_intexp;
+    y -> yp_strexp = yp -> yp_strexp;
+    y -> yp_prfexp = yp -> yp_prfexp;
+
+    y -> yp_declexp = yp -> yp_declexp;
+    y -> yp_varexp = yp -> yp_varexp;
+
+    if (yp -> yp_structname)
+       y -> yp_structname = new_string (yp -> yp_structname);
+    if (yp -> yp_ptrname)
+       y -> yp_ptrname = new_string (yp -> yp_ptrname);
+
+    if (yp -> yp_param_type)
+       y -> yp_param_type = new_string (yp -> yp_param_type);
+
+    if (yp -> yp_action0) {
+       y -> yp_action0 = new_string (yp -> yp_action0);
+       y -> yp_act0_lineno = yp -> yp_act0_lineno;
+    }
+
+    if (yp -> yp_action05) {
+       y -> yp_action05 = new_string (yp -> yp_action05);
+       y -> yp_act05_lineno = yp -> yp_act05_lineno;
+    }
+
+    if (yp -> yp_action1) {
+       y -> yp_action1 = new_string (yp -> yp_action1);
+       y -> yp_act1_lineno = yp -> yp_act1_lineno;
+    }
+
+    if (yp -> yp_action2) {
+       y -> yp_action2 = new_string (yp -> yp_action2);
+       y -> yp_act2_lineno = yp -> yp_act2_lineno;
+    }
+
+    if (yp -> yp_action3) {
+       y -> yp_action3 = new_string (yp -> yp_action3);
+       y -> yp_act3_lineno = yp -> yp_act3_lineno;
+    }
+
+    y -> yp_flags = yp -> yp_flags;
+
+    if (yp -> yp_flags & YP_DEFAULT)
+       y -> yp_default = copy_value (yp -> yp_default);
+
+    if (yp -> yp_flags & YP_ID)
+       y -> yp_id = new_string (yp -> yp_id);
+
+    if (yp -> yp_flags & YP_TAG)
+       y -> yp_tag = copy_tag (yp -> yp_tag);
+
+    if (yp -> yp_flags & YP_BOUND)
+       y -> yp_bound = new_string (yp -> yp_bound);
+
+    if (yp -> yp_flags & YP_PARMVAL)
+       y -> yp_parm = new_string (yp -> yp_parm);
+
+    if (yp -> yp_flags & YP_CONTROLLED)
+        y -> yp_control = new_string (yp -> yp_control);
+
+    if (yp -> yp_flags & YP_OPTCONTROL)
+        y -> yp_optcontrol = new_string (yp -> yp_optcontrol);
+
+    if (yp -> yp_offset)
+       y -> yp_offset = new_string (yp -> yp_offset);
+
+    if (yp -> yp_control_act) {
+       y -> yp_control_act = yp -> yp_control_act;
+    }
+    if (yp -> yp_optional_act) {
+       y -> yp_optional_act = yp -> yp_optional_act;
+    }
+    if (yp -> yp_bef_alist) {
+       y -> yp_bef_alist = yp -> yp_bef_alist;
+    }
+    if (yp -> yp_aft_alist) {
+       y -> yp_aft_alist = yp -> yp_aft_alist;
+    }
+
+
+    if (yp -> yp_next)
+       y -> yp_next = copy_type (yp -> yp_next);
+
+    return y;
+}
+
+/* \f   VALUES */
+
+YV     new_value (code)
+int    code;
+{
+    register YV    yv;
+
+    if ((yv = (YV) calloc (1, sizeof *yv)) == NULLYV)
+       yyerror ("out of memory");
+    yv -> yv_code = code;
+
+    return yv;
+}
+
+
+YV     add_value (y, z)
+register YV    y,
+               z;
+{
+    register YV            yv;
+
+    for (yv = y; yv -> yv_next; yv = yv -> yv_next)
+       continue;
+    yv -> yv_next = z;
+
+    return y;
+}
+
+/* \f */
+
+YV     copy_value (yv)
+register YV    yv;
+{
+    register YV            y;
+
+    if (yv == NULLYV)
+       return NULLYV;
+
+    y = new_value (yv -> yv_code);
+    y -> yv_flags = yv -> yv_flags;
+
+    if (yv -> yv_action) {
+       y -> yv_action = new_string (yv -> yv_action);
+       y -> yv_act_lineno = yv -> yv_act_lineno;
+    }
+
+    if (yv -> yv_flags & YV_ID)
+       y -> yv_id = new_string (yv -> yv_id);
+
+    if (yv -> yv_flags & YV_NAMED)
+       y -> yv_named = new_string (yv -> yv_named);
+
+    if (yv -> yv_flags & YV_TYPE)
+       y -> yv_type = copy_type (yv -> yv_type);
+
+    switch (yv -> yv_code) {
+       case YV_NUMBER:
+       case YV_BOOL:
+           y -> yv_number = yv -> yv_number;
+           break;
+
+       case YV_STRING:
+           y -> yv_string = new_string (yv -> yv_string);
+           break;
+
+       case YV_IDEFINED:
+           if (yv -> yv_module)
+               y -> yv_module = new_string (yv -> yv_module);
+           y -> yv_identifier = new_string (yv -> yv_identifier);
+           break;
+
+       case YV_IDLIST:
+       case YV_VALIST:
+           y -> yv_idlist = copy_value (yv -> yv_idlist);
+           break;
+
+       default:
+           break;
+    }
+
+    if (yv -> yv_next)
+       y -> yv_next = copy_value (yv -> yv_next);
+
+    return y;
+}
+
+/* \f   TAGS */
+
+YT     new_tag (class)
+PElementClass  class;
+{
+    register YT    yt;
+
+    if ((yt = (YT) calloc (1, sizeof *yt)) == NULLYT)
+       yyerror ("out of memory");
+    yt -> yt_class = class;
+
+    return yt;
+}
+
+/* \f */
+
+YT     copy_tag (yt)
+register YT    yt;
+{
+    register YT            y;
+
+    if (yt == NULLYT)
+       return NULLYT;
+
+    y = new_tag (yt -> yt_class);
+
+    y -> yt_value = copy_value (yt -> yt_value);
+
+    return y;
+}
+
+/* \f   STRINGS */
+
+char   *new_string (s)
+register char  *s;
+{
+    register char  *p;
+
+    if (s == NULLCP)
+           return NULLCP;
+
+    if ((p = malloc ((unsigned) (strlen (s) + 1))) == NULLCP)
+       yyerror ("out of memory");
+
+    (void) strcpy (p, s);
+    return p;
+}
+
+/* \f   SYMBOLS */
+
+static struct triple {
+    char          *t_name;
+    PElementClass   t_class;
+    PElementID     t_id;
+}              triples[] = {
+    "IA5String", PE_CLASS_UNIV,        PE_DEFN_IA5S,
+    "ISO646String", PE_CLASS_UNIV, PE_DEFN_IA5S,
+    "NumericString", PE_CLASS_UNIV, PE_DEFN_NUMS,
+    "PrintableString", PE_CLASS_UNIV, PE_DEFN_PRTS,
+    "T61String", PE_CLASS_UNIV, PE_DEFN_T61S,
+    "TeletexString", PE_CLASS_UNIV, PE_DEFN_T61S,
+    "VideotexString", PE_CLASS_UNIV, PE_DEFN_VTXS,
+    "GeneralizedTime", PE_CLASS_UNIV, PE_DEFN_GENT,
+    "GeneralisedTime", PE_CLASS_UNIV, PE_DEFN_GENT,
+    "UTCTime", PE_CLASS_UNIV, PE_DEFN_UTCT,
+    "UniversalTime", PE_CLASS_UNIV, PE_DEFN_UTCT,
+    "GraphicString", PE_CLASS_UNIV, PE_DEFN_GFXS,
+    "VisibleString", PE_CLASS_UNIV, PE_DEFN_VISS,
+    "GeneralString", PE_CLASS_UNIV, PE_DEFN_GENS,
+    "EXTERNAL", PE_CLASS_UNIV, PE_CONS_EXTN,
+    "ObjectDescriptor", PE_CLASS_UNIV, PE_PRIM_ODE,
+
+    NULL
+};
+
+/* \f */
+
+char *modsym (module, id, prefix)
+register char  *module,
+              *id;
+char   *prefix;
+{
+    char    buf1[BUFSIZ],
+            buf2[BUFSIZ],
+            buf3[BUFSIZ];
+    register struct triple *t;
+    static char buffer[BUFSIZ];
+
+    if (module == NULLCP)
+       for (t = triples; t -> t_name; t++)
+           if (strcmp (t -> t_name, id) == 0) {
+               module = "UNIV";
+               break;
+           }
+
+    if (prefix)
+       modsym_aux (prefix, buf1);
+    modsym_aux (module ? module : mymodule, buf2);
+    modsym_aux (id, buf3);
+    if (prefix)
+       (void) sprintf (buffer, "%s_%s_%s", buf1, buf2, buf3);
+    else
+       (void) sprintf (buffer, "%s_%s", buf2, buf3);
+
+    return buffer;
+}
+
+
+static modsym_aux (name, bp)
+register char  *name,
+              *bp;
+{
+    register char   c;
+
+    while (c = *name++)
+       switch (c) {
+           case '-':
+               *bp++ = '_';
+               *bp++ = '_';
+               break;
+
+           default:
+               *bp++ = c;
+               break;
+       }
+
+    *bp = NULL;
+}
+
+/* \f */
+
+static char *gensym (s, a)
+char   *s, *a;
+{
+    int     i;
+    register char  *p;
+    char    buffer[BUFSIZ];
+    static int  cP = 0;
+    static int  eP = 0;
+    static int  mP = 0;
+
+    switch (*s) {
+       case 'c': 
+           i = cP++;
+           break;
+       case 'e': 
+           i = eP++;
+           break;
+       case 'm': 
+           i = mP++;
+           break;
+
+       default: 
+           myyerror ("unknown gensym argument \"%s\"", s);
+       /* NOTREACHED */
+    }
+    if (a)
+       (void) sprintf (buffer, "%s_%s_%d[n_%s]", s, modulename, i, a);
+    else
+       (void) sprintf (buffer, "%s_%s_%d", s, modulename, i);
+
+    if ((p = malloc ((unsigned) (strlen (buffer) + 11))) == NULLCP)
+       yyerror ("out of memory");
+
+    (void) strcpy (p, buffer);
+    return p;
+}
+
+/* pepy compatible routines - you know how it is ... */
+init_new_file () 
+{
+    ;
+}
+
+end_file ()
+{
+    ;
+}
+
+static char *array (s, flg)
+char   *s;
+int    flg;
+{
+    static char buf[BUFSIZ];
+    char       *p;
+
+    if (!flg) return s;
+
+    if (p = index (s, '[')) {
+       (void) sprintf (buf, "%*.*s[1]", p - s, p - s, s);
+       return buf;
+    }
+    return s;
+}
+
+static void prime_default (yp, level)
+YP     yp;
+int    level;
+{
+    switch (yp -> yp_code) {
+    case YP_BOOL:
+       (void) printf ("%*s%s = %d;\n", level * 4, "",
+               SVAL (yp->yp_varexp),
+               val2int (yp -> yp_default) ? 1 : 0);
+       break;
+
+    case YP_INT:
+       (void) printf ("%*s%s = %d;\n", level * 4, "",
+               SVAL (yp -> yp_varexp), val2int (yp -> yp_default));
+       break;
+
+    case YP_INTLIST:
+    case YP_ENUMLIST:
+       (void) printf ("%*s%s = %d;\n", level * 4, "",
+               SVAL (yp -> yp_varexp), dfl2int (yp));
+       break;
+
+    case YP_REAL:
+       (void) printf ("%*s%s = %g;\n", level * 4, "",
+               SVAL (yp -> yp_varexp),
+               val2real (yp -> yp_default));
+
+    default:
+       break;
+    }
+}
+/* PH FILES */
+
+/* really need much more information in the .ph file... */
+
+static read_ph_file (module, oid)
+register char *module;
+OID    oid;
+{
+    int     class,
+           value,
+           direction;
+    char    buffer[BUFSIZ],
+           file[BUFSIZ],
+           id[BUFSIZ],
+           encpref[BUFSIZ],
+           decpref[BUFSIZ],
+           printpref[BUFSIZ];
+    char    *p, *ep, *dp, *ppp;
+    register FILE  *fp;
+    register YP            yp;
+    register YT            yt;
+    register YV            yv;
+
+    (void) sprintf (file, "%s.ph", module);
+    if (oid)
+       (void) sprintf (p = buffer, "%s.ph", sprintoid(oid));
+    else
+       p = NULLCP;
+    if ((fp = open_ph_file (file, p, "r")) == NULL)
+    {
+       warning ("Can't find file %s%s%s failed\n",
+                    file, p ? "/" : "", p ? p : "");
+       return;
+    }
+
+    if (strcmp (module, "UNIV"))
+       yyprint (module, 1, 0);
+
+    while (fgets (buffer, sizeof buffer, fp)) {
+       if (sscanf (buffer, "%d/%d/%d: %s",
+                   &class, &value, &direction, id) !=4) {
+           myyerror ("bad external definition in %s: %s",
+                   file, buffer);
+           continue;
+       }
+       ppp = dp = ep = NULLCP;
+       if (p = index(buffer, '|')) {
+           if( sscanf (p+1, "%s %s %s\n", encpref, decpref, printpref) == 3) {
+               ppp = new_string (printpref);
+               dp = new_string (decpref);
+               ep = new_string (encpref);
+           }
+       }
+               
+       yp = new_type (class == -1 ? YP_ANY : YP_IMPTYPE, -1);
+       yp -> yp_flags = YP_IMPORTED;
+       if (class >= 0) {
+           yp -> yp_flags |= YP_TAG;
+           yp -> yp_tag = yt = new_tag ((PElementClass) class);
+           yt -> yt_value = yv = new_value (YV_NUMBER);
+           yv -> yv_number = value;
+       }
+       yp -> yp_direction = direction;
+       pass1_type (ep, dp, ppp, new_string (module),
+               new_string (id), yp);
+    }
+
+    (void) fclose (fp);
+}
+
+/* \f */
+
+static write_ph_file () {
+    int            msave;
+    char    file[BUFSIZ];
+    char    fileoid[BUFSIZ];
+    char       *cp;
+    register FILE  *fp;
+    register SY            sy;
+    register YT            yt;
+    register YP            yp;
+
+    (void) sprintf (file, "%s.ph", mymodule);
+    if (mymoduleid)
+       (void) sprintf (cp = fileoid, "%s.ph", sprintoid(mymoduleid));
+    else
+       cp = NULLCP;
+    msave = mflag, mflag = 0;
+    if ((fp = open_ph_file (file, cp, "w")) == NULL)
+       myyerror ("unable to write %s", file);
+    mflag = msave;
+
+    for (sy = mysymbols; sy; sy = sy -> sy_next) {
+       yp = sy -> sy_type;
+       if (yp -> yp_flags & YP_IMPORTED)
+           continue;
+       if (doexternals == 0 && (yp->yp_flags & YP_EXPORTED) == 0)
+           continue;
+
+       if (is_any_type (yp)) {
+           (void) fprintf (fp, "-1/0/%d: %s", yp -> yp_direction, sy -> sy_name);
+           (void) fprintf (fp, " |%s %s %s\n", yyencpref, yydecpref, yyprfpref);
+       }
+       else
+           if ((yt = lookup_tag (yp)) && yt -> yt_class != PE_CLASS_CONT) {
+               (void) fprintf (fp, "%d/%d/%d: %s", yt -> yt_class,
+                           val2int (yt -> yt_value), yp -> yp_direction,
+                           sy -> sy_name);
+               (void) fprintf (fp, " |%s %s %s\n", yyencpref, yydecpref, yyprfpref);
+           }
+    }
+
+    (void) fclose (fp);
+}
+
+/* \f */
+
+#ifndef        PEPSYPATH
+#define        PEPSYPATH       ""
+#endif
+
+
+static FILE *open_ph_file (fn, fnoid, mode)
+char *fn,
+     *fnoid,
+     *mode;
+{
+    register char  *dst,
+                  *path;
+    char    fnb[BUFSIZ];
+    register FILE  *fp;
+    static char *pepypath = NULL;
+
+    if (*fn == '/')
+       return fopen (fn, mode);
+
+    if (mflag) {       /* MOBY HACK */
+       if ((fp = fopen (fn, mode)) != NULL)
+           return fp;
+       if (fnoid && (fp = fopen (fnoid, mode)) != NULL)
+           return fp;
+
+       (void) sprintf (fnb, "../pepy/%s", fn);
+       if ((fp = fopen (fnb, mode)) != NULL)
+           return fp;
+       if (fnoid) {
+           (void) sprintf (fnb, "../pepy/%s", fnoid);
+           if ((fp = fopen (fnb, mode)) != NULL)
+               return fp;
+       }
+
+       (void) sprintf (fnb, "../../pepy/%s", fn);
+       if((fp = fopen (fnb, mode)) != NULL)
+               return fp;
+       if (fnoid) {
+           (void) sprintf (fnb, "../../pepy/%s", fnoid);
+           if ((fp = fopen (fnb, mode)) != NULL)
+               return fp;
+       }
+       return NULL;
+    }
+
+    if (pepypath == NULL && (pepypath = getenv ("PEPSYPATH")) == NULL)
+       pepypath = PEPSYPATH;
+    path = pepypath;
+
+    do {
+       dst = fnb;
+       while (*path && *path != ':')
+           *dst++ = *path++;
+       if (dst != fnb)
+           *dst++ = '/';
+       (void) strcpy (dst, fn);
+       if ((fp = fopen (fnb, mode)) != NULL)
+           break;
+       if (fnoid) {
+           (void) strcpy (dst, fnoid);
+           if ((fp = fopen (fnb, mode)) != NULL)
+               break;
+       }
+    } while (*path++);
+
+    return fp;
+}
+
+YT  lookup_tag (yp)
+register YP     yp;
+{
+    register struct tuple *t;
+    static struct ypt ypts;
+    register YT     yt = &ypts;
+    static struct ypv ypvs;
+    register YV     yv = &ypvs;
+    register YP     z;
+
+    if (yp -> yp_flags & YP_TAG)
+        return yp -> yp_tag;
+
+    while (yp -> yp_code == YP_IDEFINED) {
+        if (yp -> yp_module && strcmp (yp -> yp_module, mymodule))
+            (void) lookup_module (yp -> yp_module, yp -> yp_modid);
+        if (z = lookup_type (yp -> yp_module, yp -> yp_identifier)) {
+            yp = z;
+            if (yp -> yp_flags & YP_TAG)
+                return yp -> yp_tag;
+            continue;
+        }
+        break;
+    }
+    for (t = tuples; t -> t_type != YP_UNDF; t++)
+        if (t -> t_type == yp -> yp_code) {
+            yt -> yt_class = t -> t_classnum;
+            yt -> yt_value = yv;
+            yv -> yv_code = YV_NUMBER;
+            yv -> yv_number = t -> t_idnum;
+            return yt;
+        }
+    return NULLYT;
+}
+int  is_any_type (yp)
+register YP     yp;
+{
+    register    YP z;
+
+    while (yp -> yp_code == YP_IDEFINED) {
+        if (yp -> yp_flags & YP_TAG)
+            return 0;
+
+        if (yp -> yp_module && strcmp (yp -> yp_module, mymodule))
+            (void) lookup_module (yp -> yp_module, yp -> yp_modid);
+
+        if (z = lookup_type (yp -> yp_module, yp -> yp_identifier)) {
+            yp = z;
+
+            continue;
+        }
+        break;
+    }
+    return (yp -> yp_code == YP_ANY && !(yp -> yp_flags & YP_TAG));
+}
+
+/*
+ * return a string with the leading pathname stripped off
+ */
+char *
+pstrip(p)
+char *p;
+{
+    char *p1;
+
+    if (p1 = rindex(p, '/'))
+       return (p1 + 1);
+    return (p);
+}
+
+/*
+ * produce a #include on the given file descriptor according to what ever
+ * rules are in fashion today. Unfortunately these keep changing so to
+ * minimise the effort involved in keeping up we put all the code to change
+ * in the one place, here. -- amrw
+ *
+ * actually, the rules have never changed, andrew just can't figure them out.
+ *     -- mtr
+ */
+doincl(fp, file)
+FILE   *fp;            /* where #include is to be written to */
+char   *file[];        /* files to be included */
+{
+    char       **p;
+
+    if (mflag) {
+       /* PEPYPATH version */
+
+       (void) fprintf (fp, "#ifndef    PEPYPATH\n");
+       for (p = file; *p; p++) {
+           if (is_stand(*p))
+               (void) fprintf (fp, "#include <isode/%s>\n", *p);
+           else
+               (void) fprintf (fp, "#include \"%s\"\n", pstrip(*p));
+       }
+       (void) fprintf (fp, "#else\n");
+       for (p = file; *p; p++) {
+           (void) fprintf (fp, "#include \"%s\"\n", pstrip(*p));
+       }
+       (void) fprintf (fp, "#endif\n\n");
+
+    }
+    else {
+       for (p = file; *p; p++) {
+           if (is_stand(*p))
+               (void) fprintf (fp, "#include <isode/%s>\n", *p);
+           else
+               (void) fprintf (fp, "#include \"%s\"\n", pstrip(*p));
+       }
+    }
+    (void) fprintf (fp, "\n");
+}
+
+/* standard files  - that should be found in the <isode> directory */
+static char *stand_f[] = {
+       "psap.h",
+       "pepsy.h",
+       "UNIV-types.h",
+       "UNIV_defs.h",
+       "UNIV_pre_defs.h",
+
+       (char *)0       /* terminating NULL pointer */
+       };
+
+
+/*
+ * determine if the given (after stripping any path) file is a standard
+ * include file which should be in the include/isode directory.
+ * return nonzero (true) if it is.
+ */
+is_stand(file)
+char *file;
+{
+    char       **p;
+    char       *f = pstrip (file);
+    for (p = stand_f; *p; p++) {
+       if (strcmp(f, pstrip(*p)) == 0)
+           return (1);
+    }
+
+    return (0);
+}
+
+/* Number of different external modules that can referenced */
+#define EXTMODSIZE     50
+
+/* table of external modules we reference */
+static char *extmodtab[EXTMODSIZE];
+static int   nextmod = 0;      /* next free slot in external module table */
+
+/*
+ * build up a list of external modules we have referenced
+ */
+addextmod(p)
+char   *p;     /* name of external module */
+{
+
+    if (nextmod >= EXTMODSIZE)
+       ferr(1, "Too many external modules reference, table overflow\n");
+
+    extmodtab[nextmod++] = p;
+}
+
+/*
+ * process all the external modules collected to produce the includes
+ * required
+ */
+proc_extmod(fp)
+FILE   *fp;
+{
+    char       **p;
+    char       *files[EXTMODSIZE + 1];
+    char       *buf;
+    char       *tail = "-types.h";
+    char       *prefix = "pepsy/";
+    int                last = 0;
+
+    if (nextmod <= 0)
+       return;         /* no external definitions */
+
+    for (p = extmodtab; p < extmodtab + nextmod; p++) {
+       if (last >= EXTMODSIZE)
+           ferr(1, "proc_extmod: too many external modules\n");
+
+       buf = concat(*p, tail);
+       if (mflag || is_stand(buf)) /* need to prepend a "pepsy/" */
+           files[last++] = my_strcat(prefix, buf);
+       else
+           files[last++] = my_new_str(buf);
+    }
+    files[last++] = (char *)0;
+
+    doincl(fp, files);
+
+    /* free up this memory */
+    --last; /* don't free the NULL pointer - can core dump */
+    while (last > 0)
+       free(files[--last]);
+
+}
+
+/*
+ * allocate a yfn structure and intialise it
+ */
+YFN
+new_yfn(efn, dfn, pfn, ffn)
+char   *efn, *dfn, *pfn, *ffn;
+{
+       
+    register YFN    fn;
+    char       buf[STRSIZE];
+
+    if ((fn = (YFN) calloc (1, sizeof *fn)) == NULLYFN)
+       yyerror ("out of memory");
+
+    if (efn) {
+        if (getid(efn, buf, STRSIZE) == NULLCP)
+           yyerror("Bad Encoding function\n");
+       fn -> yfn_enc = strdup(buf);
+       free(efn);
+    }
+
+    if (dfn) {
+        if (getid(dfn, buf, STRSIZE) == NULLCP)
+           yyerror("Bad Decoding function\n");
+       fn -> yfn_dec = strdup(buf);
+       free(dfn);
+    }
+
+    if (pfn) {
+        if (getid(pfn, buf, STRSIZE) == NULLCP)
+           yyerror("Bad Printing function\n");
+       fn -> yfn_prt = strdup(buf);
+       free(pfn);
+    }
+
+    if (ffn) {
+        if (getid(ffn, buf, STRSIZE) == NULLCP)
+           yyerror("Bad Printing function\n");
+       fn -> yfn_fre = strdup(buf);
+       free(ffn);
+    }
+
+    return fn;
+}
+
+/*
+ * support routine for action_t = allocate space for it and fill it in with
+ * the given yy_action field
+ */
+Action
+new_action_t(text, lineno, num)
+char   *text;
+int    lineno;
+{
+    Action     act;
+
+    if ((act = (Action) malloc(sizeof (action_t))) == NULLAction)
+       yyerror("out of memory\n");
+    
+    act->a_data = text;
+    act->a_line = lineno;
+    act->a_num = num;
+
+    return (act);
+}
+
+/*
+ * support routine for YAL = allocate space for it and make sure it is
+ * zero'd
+ */
+YAL
+new_yal()
+{
+    YAL        yal;
+
+    if ((yal = (YAL) calloc(1, sizeof (*yal))) == NULLYAL)
+       yyerror("out of memory\n");
+    
+    return (yal);
+}
+YAL
+yal_join(yal1, yal2)
+YAL    yal1, yal2;
+{
+    if (yal2 == NULLYAL)
+       return (yal1);
+    if (yal1 == NULLYAL)
+       return (yal2);
+
+    if (yal1->yal_enc == NULLAction && yal2->yal_enc != NULLAction)
+       yal1->yal_enc = yal2->yal_enc;
+    else if (yal1->yal_enc != NULLAction && yal2->yal_enc != NULLAction)
+       yyerror("two encoding actions in the same place\n merge into one\n");
+
+    if (yal1->yal_dec == NULLAction && yal2->yal_dec != NULLAction)
+       yal1->yal_dec = yal2->yal_dec;
+    else if (yal1->yal_dec != NULLAction && yal2->yal_dec != NULLAction)
+       yyerror("two decoding actions in the same place\n merge into one\n");
+
+    if (yal1->yal_prn == NULLAction && yal2->yal_prn != NULLAction)
+       yal1->yal_prn = yal2->yal_prn;
+    else if (yal1->yal_prn != NULLAction && yal2->yal_prn != NULLAction)
+       yyerror("two printing actions in the same place\n merge into one\n");
+
+    free((char *)yal2);
+    return (yal1);
+}
+/*
+ * join two yfn structures
+ */
+YFN
+join_yfn(fn1, fn2)
+register YFN   fn1, fn2;
+{
+       
+    if (fn2 == NULLYFN)
+       return (fn1);
+    if (fn1 == NULLYFN)
+       return (fn2);
+
+    if (fn1->yfn_enc == NULLCP && fn2->yfn_enc != NULLCP)
+       fn1->yfn_enc = fn2->yfn_enc;
+    else if (fn1->yfn_enc != NULLCP && fn2->yfn_enc != NULLCP)
+       yyerror("Illegal: two encoding functions for the same type\n");
+
+    if (fn1->yfn_dec == NULLCP && fn2->yfn_dec != NULLCP)
+       fn1->yfn_dec = fn2->yfn_dec;
+    else if (fn1->yfn_dec != NULLCP && fn2->yfn_dec != NULLCP)
+       yyerror("Illegal: two decoding functions for the same type\n");
+
+    if (fn1->yfn_prt == NULLCP && fn2->yfn_prt != NULLCP)
+       fn1->yfn_prt = fn2->yfn_prt;
+    else if (fn1->yfn_prt != NULLCP && fn2->yfn_prt != NULLCP)
+       yyerror("Illegal: two printing functions for the same type\n");
+
+    free((char *)fn2);
+
+    return (fn1);
+}
+
diff --git a/src/isode/pepsy/pepsy.h.gnrc b/src/isode/pepsy/pepsy.h.gnrc
new file mode 100644 (file)
index 0000000..9e0c8c4
--- /dev/null
@@ -0,0 +1,342 @@
+%BEGIN(PEPSY)%
+/* pepsy.h - definitions for pepsy */
+%END(PEPSY)%
+%BEGIN(PEPY)%
+/* pepy.h - definitions for pepy */
+%END(PEPY)%
+%BEGIN(ROSY)%
+/* rosy-defs.h - definitions for rosy */
+%END(ROSY)%
+%BEGIN(MOSY)%
+/* mosy-defs.h - definitions for mosy */
+%END(MOSY)%
+/* %WARNING% */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:20  eichin
+ * autoconfed isode for kerberos work
+ *
+# Revision 1.1  1994/05/31 20:40:08  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+ * Revision 8.0  91/07/17  12:43:09  isode
+ * Release 7.0
+ * 
+ *
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#include "psap.h"
+
+struct tuple {
+    int     t_type;
+    char   *t_class;
+    char   *t_form;
+    char   *t_id;
+    PElementClass t_classnum;
+    int            t_idnum;
+};
+
+typedef struct ypv {
+    int     yv_code;
+#define        YV_UNDF         0x00    /* ??? */
+#define        YV_NUMBER       0x01    /* LITNUMBER */
+#define        YV_BOOL         0x02    /* TRUE | FALSE */
+#define        YV_STRING       0x03    /* LITSTRING */
+#define        YV_IDEFINED     0x04    /* ID */
+#define        YV_IDLIST       0x05    /* IdentifierList */
+#define        YV_VALIST       0x06    /* { Values } */
+#define        YV_NULL         0x07    /* NULL */
+#define YV_ABSENT      0x08    /* WITH COMPONENTS .. ABSENT */
+#define YV_PRESENT     0x09    /*  "   "          .. PRESENT */
+#define YV_INCLUDES    0x0a    /* INCLUDES ... */
+#define YV_WITHCOMPS   0x0b    /* WITH COMPONENTS */
+#define        YV_OIDLIST      0x0c    /* { object identifier } */
+#define YV_REAL                0x0d    /* real value */
+
+    union {
+       int         yv_un_number;               /* code = YV_NUMBER
+                                                  code = YV_BOOL */
+
+       double      yv_un_real;                 /* code = YV_REAL */
+
+       char       *yv_un_string;               /* code = YV_STRING */
+
+       struct {                                /* code = YV_IDEFINED */
+           char   *yv_st_module;
+           char   *yv_st_modid;
+           char   *yv_st_identifier;
+       }               yv_st;
+
+        struct ypv *yv_un_idlist;              /* code = YV_IDLIST
+                                                  code = YV_VALIST
+                                                  code = YV_OIDLIST */
+    }                   yv_un;
+#define        yv_number       yv_un.yv_un_number
+#define        yv_string       yv_un.yv_un_string
+#define        yv_identifier   yv_un.yv_st.yv_st_identifier
+#define        yv_module       yv_un.yv_st.yv_st_module
+#define yv_modid       yv_un.yv_st.yv_st_modid
+#define yv_idlist      yv_un.yv_un_idlist
+#define yv_real                yv_un.yv_un_real
+
+    char   *yv_action;
+    int            yv_act_lineno;
+
+    int            yv_flags;
+#define        YV_NOFLAGS      0x00    /* no flags */
+#define        YV_ID           0x01    /* ID Value */
+#define        YV_NAMED        0x02    /* NamedNumber */
+#define        YV_TYPE         0x04    /* TYPE Value */
+#define        YV_BOUND        0x08    /* named value */
+#define        YVBITS  "\020\01ID\02NAMED\03TYPE\04BOUND"
+
+    char   *yv_id;                             /* flags & YV_ID */
+
+    char   *yv_named;                          /* flags & YV_NAMED */
+
+    struct ype *yv_type;                       /* flags & YV_TYPE */
+
+    struct ypv *yv_next;
+}                      ypv, *YV;
+#define        NULLYV  ((YV) 0)
+
+YV     new_value (), add_value (), copy_value ();
+
+/* \f */
+
+typedef struct ypt {
+    PElementClass   yt_class;
+
+    YV             yt_value;
+}                      ypt, *YT;
+#define        NULLYT  ((YT) 0)
+
+YT     new_tag (), copy_tag ();
+
+/* \f */
+
+typedef struct ype {
+    int     yp_code;
+#define        YP_UNDF         0x00    /* type not yet known */
+#define        YP_BOOL         0x01    /* BOOLEAN */
+#define        YP_INT          0x02    /* INTEGER */
+#define        YP_INTLIST      0x03    /* INTEGER [ NamedNumberList ] */
+#define        YP_BIT          0x04    /* BITSTRING */
+#define        YP_BITLIST      0x05    /* BITSTRING [ NamedNumberList ] */
+#define        YP_OCT          0x06    /* OCTETSTRING */
+#define        YP_NULL         0x07    /* NULL */
+#define        YP_SEQ          0x08    /* SEQUENCE */
+#define        YP_SEQTYPE      0x09    /* SEQUENCE OF Type */
+#define        YP_SEQLIST      0x0a    /* SEQUENCE [ ElementTypes ] */
+#define        YP_SET          0x0b    /* SET */
+#define        YP_SETTYPE      0x0c    /* SET OF Type */
+#define        YP_SETLIST      0x0d    /* SET [ MemberTypes ] */
+#define        YP_CHOICE       0x0e    /* CHOICE [ AlternativeTypeList ] */
+#define        YP_ANY          0x0f    /* ANY */
+#define        YP_OID          0x10    /* OBJECT IDENTIFIER */
+#define        YP_IDEFINED     0x11    /* identifier */
+#define YP_ENUMLIST    0x12    /* ENUMERATED */
+#define YP_REAL                0x13    /* Real (floating-point) */
+
+    int     yp_direction;
+#define YP_DECODER     0x01
+#define YP_ENCODER     0x02
+#define        YP_PRINTER      0x04
+
+    union {
+       struct {                                /* code = YP_IDEFINED */
+           char   *yp_st_module;                   /* module name */
+           OID     yp_st_modid;                    /* module id */
+           char   *yp_st_identifier;               /* definition name */
+       }               yp_st;
+
+       struct ype *yp_un_type;                 /* code = YP_SEQTYPE
+                                                  code = YP_SEQLIST
+                                                  code = YP_SETTYPE
+                                                  code = YP_SETLIST
+                                                  code = YP_CHOICE */
+
+       YV          yp_un_value;                /* code = YP_INTLIST
+                                                  code = YP_BITLIST */
+    }                   yp_un;
+#define        yp_identifier   yp_un.yp_st.yp_st_identifier
+#define        yp_module       yp_un.yp_st.yp_st_module
+#define yp_modid       yp_un.yp_st.yp_st_modid
+#define        yp_type         yp_un.yp_un_type
+#define        yp_value        yp_un.yp_un_value
+
+    char   *yp_intexp;         /* expressions to pass (use) as extra */
+    char   *yp_strexp;         /* parameters (primitive values) */
+    char    yp_prfexp;
+
+    char   *yp_declexp;
+    char   *yp_varexp;
+
+    char   *yp_structname;
+    char   *yp_ptrname;
+
+    char   *yp_param_type;
+
+    char   *yp_action0;
+    int     yp_act0_lineno;
+
+    char   *yp_action05;
+    int            yp_act05_lineno;
+
+    char   *yp_action1;
+    int            yp_act1_lineno;
+
+    char   *yp_action2;
+    int            yp_act2_lineno;
+
+    char   *yp_action3;
+    int            yp_act3_lineno;
+
+    int     yp_flags;
+#define        YP_NOFLAGS      0x0000  /* no flags */
+#define        YP_OPTIONAL     0x0001  /* OPTIONAL */
+#define        YP_COMPONENTS   0x0002  /* COMPONENTS OF */
+#define        YP_IMPLICIT     0x0004  /* IMPLICIT */
+#define        YP_DEFAULT      0x0008  /* DEFAULT */
+#define        YP_ID           0x0010  /* ID */
+#define        YP_TAG          0x0020  /* Tag */
+#define        YP_BOUND        0x0040  /* ID LANGLE */
+#define        YP_PULLEDUP     0x0080  /* member is a choice */
+#define YP_PARMVAL     0x0100  /* value to be passed to parm is present */
+#define YP_CONTROLLED  0x0200  /* encoding item has a controller */
+#define        YP_OPTCONTROL   0x0400  /*   .. */
+#define        YP_ACTION1      0x0800  /* action1 acted upon */
+#define        YP_PARMISOID    0x1000  /* value to be passed to parm is OID */
+#define YP_ENCRYPTED   0x2000  /* encypted - which is a bit hazy */
+#define YP_IMPORTED    0x4000  /* value imported from another module */
+#define YP_EXPORTED    0x8000  /* value exported to another module */
+#define        YPBITS  "\020\01OPTIONAL\02COMPONENTS\03IMPLICIT\04DEFAULT\05ID\06TAG\
+\07BOUND\010PULLEDUP\011PARMVAL\012CONTROLLED\013OPTCONTROL\
+\014ACTION1\015PARMISOID\016ENCRYPTED\017IMPORTED\020EXPORTED"
+
+    YV     yp_default;                         /* flags & YP_DEFAULT */
+
+    char   *yp_id;                             /* flags & YP_ID */
+
+    YT     yp_tag;                             /* flags & YP_TAG */
+
+    char   *yp_bound;                          /* flags & YP_BOUND */
+
+    char   *yp_parm;                           /* flags & YP_PARMVAL */
+
+    char   *yp_control;                                /* flags & YP_CONTROLLED */
+
+    char   *yp_optcontrol;                     /* flags & YP_OPTCONTROL */
+
+    char   *yp_offset;
+
+    struct ype *yp_next;
+}                      ype, *YP;
+#define        NULLYP  ((YP) 0)
+
+YP     new_type (), add_type (), copy_type ();
+
+char   *new_string ();
+
+#define        TBL_EXPORT      0
+#define TBL_IMPORT     1
+#define MAX_TBLS       2
+
+extern int tagcontrol;
+#define TAG_UNKNOWN    0
+#define TAG_IMPLICIT   1
+#define TAG_EXPLICIT   2
+
+#define CH_FULLY       0
+#define CH_PARTIAL     1
+
+typedef struct yop {
+    char   *yo_name;
+
+    YP     yo_arg;
+    YP     yo_result;
+    YV     yo_errors;
+    YV     yo_linked;
+
+    int            yo_opcode;
+}              yop, *YO;
+#define        NULLYO  ((YO) 0)
+
+
+typedef struct yerr {
+    char   *ye_name;
+
+    YP     ye_param;
+
+    int            ye_errcode;
+
+    int            ye_offset;
+}          yerr, *YE;
+#define        NULLYE  ((YE) 0)
+
+/* \f */
+
+%BEGIN(PEPSY)%
+extern char *pepsyversion;
+%END(PEPSY)%
+%BEGIN(PEPY)%
+extern char *pepyversion;
+%END(PEPY)%
+%BEGIN(ROSY)%
+extern char *rosyversion;
+%END(ROSY)%
+%BEGIN(MOSY)%
+extern char *mosyversion;
+%END(MOSY)%
+
+extern int yysection;
+extern char *yyencpref;
+extern char *yydecpref;
+extern char *yyprfpref;
+extern char *yyencdflt;
+extern char *yydecdflt;
+extern char *yyprfdflt;
+
+extern int yydebug;
+extern int yylineno;
+
+#ifndef        HPUX
+extern char yytext[];
+#else
+extern unsigned char yytext[];
+#endif
+
+extern char *mymodule;
+
+extern OID   mymoduleid;
+
+extern char *bflag;
+extern int   Cflag;
+extern int   dflag;
+extern int   Pflag;
+extern char *sysin;
+
+extern char *module_actions;
+
+OID    addoid ();
+OID    int2oid ();
+OID    oidlookup ();
+char   *oidname ();
+char   *oidprint ();
+
+extern int errno;
diff --git a/src/isode/pepsy/pepsy_misc.c b/src/isode/pepsy/pepsy_misc.c
new file mode 100644 (file)
index 0000000..98edbdc
--- /dev/null
@@ -0,0 +1,381 @@
+/* pepy_misc.c - PE parser (yacc-based) misc routines */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:22  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:10  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:10  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "pepsydefs.h"
+
+/* \f Oid manipulation */
+
+typedef struct oidlist {
+    OID                op_oid;
+    char       *op_name;
+    struct oidlist *op_next;
+} oidlist, *OP;
+#define NULLOP ((OP) 0)
+
+typedef struct symtable {
+    char       *sym_name;
+    char       *sym_module;
+    OID                sym_oid;
+    int                sym_type;
+    struct symtable *sym_next;
+} symtable, *SYM;
+#define NULLSYM ((SYM)0)
+
+
+static OP      myoids;
+static SYM     symtab[MAX_TBLS];
+
+
+OID    addoid (o1, o2)
+OID    o1, o2;
+{
+    OID                noid;
+
+    if (o1 == NULLOID || o2 == NULLOID)
+       return NULLOID;
+
+    noid = (OID) calloc (1, sizeof(*noid));
+    if (noid == NULLOID)
+       myyerror ("out of memory (%d needed)", sizeof(*noid));
+
+    noid -> oid_nelem = o1->oid_nelem + o2->oid_nelem;
+    noid -> oid_elements = (unsigned int *) calloc ((unsigned)noid->oid_nelem,
+                                                   sizeof(unsigned int));
+    if (noid -> oid_elements == NULL)
+       myyerror ("out of memory (%d needed)", noid->oid_nelem);
+
+    bcopy ((char *)o1->oid_elements, (char *)noid->oid_elements,
+          o1->oid_nelem * sizeof(unsigned int));
+    bcopy ((char *)o2 -> oid_elements,
+          (char *) &noid -> oid_elements[o1->oid_nelem],
+          o2 -> oid_nelem * sizeof(unsigned int));
+    return noid;
+}
+
+defineoid (name, oid)
+char   *name;
+OID    oid;
+{
+    register char      *p;
+    register OP                op;
+
+    if (oid == NULLOID) {
+       myyerror ("Warning Null oid in defineoid");
+       return;
+    }
+    for (op = myoids; op; op = op -> op_next)
+       if (strcmp (op -> op_name, name) == 0) {
+           if (oid_cmp(op->op_oid, oid) != 0) {
+               p = new_string(sprintoid (oid));
+               warning ("OID name clash %s => %s & %s",
+                         name, p, sprintoid(op->op_oid));
+               free (p);
+           }
+           else
+               return;
+       }
+    op = (OP) calloc (1, sizeof *op);
+    if (op == NULLOP)
+       myyerror ("out of memory (%d needed)", sizeof(*op));
+    op -> op_oid = oid_cpy(oid);
+    op -> op_name = new_string (name);
+    op -> op_next = myoids;
+    myoids = op;
+}
+
+OID    oidlookup (name)
+char   *name;
+{
+    OP op;
+
+    for (op = myoids; op; op = op -> op_next)
+       if (strcmp ( name, op->op_name) == 0)
+           return oid_cpy(op -> op_oid);
+
+    warning ("unknown Object Identifier '%s'", name);
+    return NULLOID;
+}
+
+char   *oidname (oid)
+OID    oid;
+{
+    OP op;
+
+    for (op = myoids; op; op = op -> op_next)
+       if (oid_cmp (op->op_oid, oid) == 0)
+           return op -> op_name;
+
+    return NULLCP;
+}
+
+OID    int2oid (n)
+int    n;
+{
+    OID                noid;
+
+    noid = (OID) calloc(1, sizeof(*noid));
+    if (noid == NULLOID)
+       myyerror ("out of memory (%d needed)", sizeof *noid);
+
+    noid -> oid_elements = (unsigned int *) calloc (1, sizeof(unsigned int));
+    if (noid -> oid_elements == NULL)
+       myyerror ("out of memory (%d needed)", sizeof(unsigned int));
+    noid -> oid_nelem = 1;
+    noid -> oid_elements[0] = n;
+    return noid;
+}
+
+/* \f */
+
+addtable (name, lt, typ)
+char   *name;
+int    lt;
+int    typ;    /* Does it allow implicit's to work or not */
+{
+    SYM                sp;
+
+    sp = (SYM)calloc (1, sizeof *sp);
+    sp -> sym_name = new_string (name);
+    sp -> sym_next = symtab[lt];
+    sp -> sym_type = typ;
+    symtab[lt] = sp;
+}
+
+addtableref (name, id, lt)
+char   *name;
+OID    id;
+int    lt;
+{
+    SYM                sp;
+    char       *nm;
+    OID                oid;
+
+    nm = name ? new_string (name) : NULLCP;
+    oid = id ? oid_cpy (id) : NULLOID;
+
+    for (sp = symtab[lt]; sp; sp = sp -> sym_next)
+       if (sp -> sym_module == NULLCP && sp -> sym_oid == NULLOID)
+       {
+           sp -> sym_module = nm;
+           sp -> sym_oid = oid;
+       }
+}
+
+print_expimp ()
+{
+    SYM                sp;
+    int                ind;
+    OID                oid;
+    char       *p;
+
+    if (sp = symtab[TBL_EXPORT])
+       (void) printf ("\nEXPORTS\n");
+       
+    for (ind = 0; sp; sp = sp->sym_next) {
+       if (ind == 0) {
+           (void) putchar('\t');
+           ind = 8;
+       }
+       (void) printf("%s", sp -> sym_name);
+       ind += strlen (sp -> sym_name);
+       if (sp -> sym_next){
+           (void) putchar (',');
+           ind ++;
+       }
+       else
+           (void) putchar (';');
+       if (ind > 72) {
+           (void) putchar ('\n');
+           ind = 0;
+       }
+       else {
+           (void) putchar (' ');
+           ind ++;
+       }
+    }
+    (void) putchar ('\n');
+
+    if (sp = symtab[TBL_IMPORT]) {
+       (void) printf ("\nIMPORTS\n");
+       p = sp -> sym_module;
+       oid = sp -> sym_oid;
+    }
+    for (ind = 0; sp; sp = sp -> sym_next) {
+       if (ind == 0) {
+           (void) putchar ('\t');
+           ind = 8;
+       }
+       (void) printf ("%s", sp -> sym_name);
+       ind += strlen (sp -> sym_name);
+       if (sp -> sym_next) {
+           if (strcmp (p, sp -> sym_next -> sym_module) == 0) {
+               (void) putchar (',');
+               ind ++;
+               if ( ind > 72) {
+                   (void) putchar ('\n');
+                   ind = 0;
+               }
+               else {
+                   (void) putchar (' ');
+                   ind ++;
+               }
+           }
+           else {
+               if (ind != 8)
+                   (void) printf ("\n\t\t");
+               else
+                   (void) putchar ('\t');
+               (void) printf ("FROM %s", p);
+               if (oid)
+                   (void) printf (" %s", oidprint (oid));
+               (void) printf ("\n\t");
+               ind = 8;
+               p = sp -> sym_next -> sym_module;
+               oid = sp -> sym_next -> sym_oid;
+           }
+       }
+       else {
+           if (ind != 8)
+               (void) printf ("\n\t\t");
+           else
+               (void) putchar ('\t');
+           (void) printf ("FROM %s", p);
+           if (oid)
+               (void) printf (" %s", oidprint (oid));
+           (void) printf (";\n");
+        }
+    }
+}
+
+check_impexp (yp)
+YP     yp;
+{
+    SYM                sp;
+
+    for (sp = symtab[TBL_EXPORT]; sp; sp = sp->sym_next)
+       if (strcmp (sp -> sym_name, yp -> yp_identifier) == 0)
+       {
+           yp -> yp_flags |= YP_EXPORTED;
+           break;
+       }
+
+    for (sp = symtab[TBL_IMPORT]; sp; sp = sp -> sym_next)
+       if (strcmp (sp -> sym_name, yp -> yp_identifier) == 0) {
+           if (yp->yp_flags & YP_EXPORTED)
+               myyerror ("Warning: %s imported & exported!", yp->yp_identifier);
+           yp -> yp_module = sp -> sym_module;
+           yp -> yp_modid = sp -> sym_oid;
+/*         yp -> yp_flags |= YP_IMPORTED;      */
+       }
+}
+static struct oidtbl {
+    char       *oid_name;
+    int                oid_value;
+} oidtable[] =  {
+                               /* Top level OIDS */
+    "ccitt",           0,
+    "iso",             1,
+    "joint-iso-ccitt", 2,
+
+    NULL,
+};
+
+initoidtbl ()
+{
+    struct oidtbl *op;
+    OID                oid;
+
+    for (op = oidtable; op -> oid_name; op++) {
+       defineoid (op->oid_name, oid = int2oid(op->oid_value));
+       oid_free (oid);
+    }
+}
+
+char   *oidprint (oid)
+OID    oid;
+{
+    static char buf[BUFSIZ];
+    char       *cp;
+    char       *p;
+    OID                o2;
+    unsigned int *ip;
+    int                i;
+
+    if (oid == NULLOID)
+       return "";
+
+    (void) strcpy (buf, "{ ");
+    cp = buf + strlen(buf);
+
+    i = oid->oid_nelem;
+    ip = oid->oid_elements;
+
+    p = oidname (o2 = int2oid((int)*ip));
+    oid_free (o2);
+    if (p) {
+       i --;
+       ip ++;
+       (void) sprintf (cp, "%s ", p);
+       cp += strlen(cp);
+    }
+
+    for (; i > 0; i--) {
+       (void) sprintf (cp, "%d ", *ip++);
+       cp += strlen (cp);
+    }
+
+    (void) strcat (cp, " }");
+    return buf;
+}
+
+/*
+ * look at import list and return any clue found as to handling implicit tags
+ * on that type
+ */
+chkil(id)
+char   *id;
+{
+    SYM sy;
+
+    for (sy = symtab[TBL_IMPORT]; sy; sy = sy->sym_next)
+       if (strcmp(sy->sym_name, id) == 0)
+               break;
+    if (sy)
+       return (sy->sym_type);
+
+    return (ER_UNKNOWN);
+
+}
diff --git a/src/isode/pepsy/pepsy_str.c b/src/isode/pepsy/pepsy_str.c
new file mode 100644 (file)
index 0000000..58bd5b8
--- /dev/null
@@ -0,0 +1,61 @@
+/* pepy_strings.c - constant strings used in pepy */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:23  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:12  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:12  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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   *pepy_strings[] = {
+       "bad ",                         /* PEPY_ERR_BAD */
+       "bad bitstring: ",              /* PEPY_ERR_BAD_BITS */
+       "bad boolean: ",                /* PEPY_ERR_BAD_BOOLEAN */
+       "bad class/id: ",               /* PEPY_ERR_BAD_CLASS */
+       "bad class/form/id: ",          /* PEPY_ERR_BAD_CLASS_FORM_ID */
+       "bad form ",                    /* PEPY_ERR_BAD_FORM */
+       "bad integer: ",                /* PEPY_ERR_BAD_INTEGER */
+       "bad object identifier: ",      /* PEPY_ERR_BAD_OID */
+       "bad octetstring: ",            /* PEPY_ERR_BAD_OCTET */
+       "bad real: ",                   /* PEPY_ERR_BAD_REAL */
+       "bad sequence: ",               /* PEPY_ERR_BAD_SEQ */
+       "bad set: ",                    /* PEPY_ERR_BAD_SET */
+       "has too many bits",            /* PEPY_ERR_TOO_MANY_BITS */
+       "has too many elements",        /* PEPY_ERR_TOO_MANY_ELEMENTS */
+       "has unknown choice: ",         /* PEPY_ERR_UNKNOWN_CHOICE */
+       "has unknown component: ",      /* PEPY_ERR_UNK_COMP */
+       "initialization fails",         /* PEPY_ERR_INIT_FAILED */
+       "invalid choice selected: ",    /* PEPY_ERR_INVALID_CHOICE */
+       "missing ",                     /* PEPY_ERR_MISSING */
+       "out of memory",                /* PEPY_ERR_NOMEM  */
+       "too many elements for tagged ", /* PEPY_ERR_TOO_MANY_TAGGED */
+       "warning: extra or duplicate members present in SET",
+                                       /* PEPY_ERR_EXTRA_MEMBERS */
+       (char *)0
+};
+       
+       
diff --git a/src/isode/pepsy/pepsydefs.h.gnrc b/src/isode/pepsy/pepsydefs.h.gnrc
new file mode 100644 (file)
index 0000000..119bdd8
--- /dev/null
@@ -0,0 +1,422 @@
+%BEGIN(PEPSY)%
+/* pepsydefs.h - definitions for pepsy */
+%END(PEPSY)%
+%BEGIN(PEPY)%
+/* pepy.h - definitions for pepy */
+%END(PEPY)%
+%BEGIN(ROSY)%
+/* rosy-defs.h - definitions for rosy */
+%END(ROSY)%
+%BEGIN(MOSY)%
+/* mosy-defs.h - definitions for mosy */
+%END(MOSY)%
+/* %WARNING% */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:25  eichin
+ * autoconfed isode for kerberos work
+ *
+# Revision 1.2  1994/06/07 04:06:25  eichin
+# yytext is char* under mips too
+#
+# Revision 1.1  1994/05/31 20:40:17  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+ * Revision 8.0  91/07/17  12:43:12  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+#include "psap.h"
+
+struct tuple {
+    int     t_type;
+    char   *t_class;
+    char   *t_form;
+    char   *t_id;
+    PElementClass t_classnum;
+    int            t_idnum;
+};
+
+typedef struct ypv {
+    int     yv_code;
+#define        YV_UNDF         0x00    /* ??? */
+#define        YV_NUMBER       0x01    /* LITNUMBER */
+#define        YV_BOOL         0x02    /* TRUE | FALSE */
+#define        YV_STRING       0x03    /* LITSTRING */
+#define        YV_IDEFINED     0x04    /* ID */
+#define        YV_IDLIST       0x05    /* IdentifierList */
+#define        YV_VALIST       0x06    /* { Values } */
+#define        YV_NULL         0x07    /* NULL */
+#define YV_ABSENT      0x08    /* WITH COMPONENTS .. ABSENT */
+#define YV_PRESENT     0x09    /*  "   "          .. PRESENT */
+#define YV_INCLUDES    0x0a    /* INCLUDES ... */
+#define YV_WITHCOMPS   0x0b    /* WITH COMPONENTS */
+#define        YV_OIDLIST      0x0c    /* { object identifier } */
+#define YV_REAL                0x0d    /* real value */
+#define YV_HSTRING     0x0e    /* Hex String */
+#define YV_BSTRING     0x0f    /* Bit String */
+
+    union {
+       int         yv_un_number;               /* code = YV_NUMBER
+                                                  code = YV_BOOL */
+
+       double      yv_un_real;                 /* code = YV_REAL */
+
+       char       *yv_un_string;               /* code = YV_STRING */
+
+       struct {                                /* code = YV_IDEFINED */
+           char   *yv_st_module;
+           char   *yv_st_modid;
+           char   *yv_st_identifier;
+       }               yv_st;
+
+        struct ypv *yv_un_idlist;              /* code = YV_IDLIST
+                                                  code = YV_VALIST
+                                                  code = YV_OIDLIST */
+
+       struct {                                
+           char        *yv_sl_xstring;            
+           int         yv_sl_xlength;
+       }               yv_sl;                   /* code = YV_HSTRING
+                                                   code = YV_BSTRING */
+    }                   yv_un;
+#define        yv_number       yv_un.yv_un_number
+#define        yv_string       yv_un.yv_un_string
+#define        yv_identifier   yv_un.yv_st.yv_st_identifier
+#define        yv_module       yv_un.yv_st.yv_st_module
+#define yv_modid       yv_un.yv_st.yv_st_modid
+#define yv_idlist      yv_un.yv_un_idlist
+#define yv_real                yv_un.yv_un_real
+#define yv_xstring     yv_un.yv_sl.yv_sl_xstring
+#define yv_xlength     yv_un.yv_sl.yv_sl_xlength
+
+    char   *yv_action;
+    int            yv_act_lineno;
+
+    int            yv_flags;
+#define        YV_NOFLAGS      0x00    /* no flags */
+#define        YV_ID           0x01    /* ID Value */
+#define        YV_NAMED        0x02    /* NamedNumber */
+#define        YV_TYPE         0x04    /* TYPE Value */
+#define        YV_BOUND        0x08    /* named value */
+#define        YVBITS  "\020\01ID\02NAMED\03TYPE\04BOUND"
+
+    char   *yv_id;                             /* flags & YV_ID */
+
+    char   *yv_named;                          /* flags & YV_NAMED */
+
+    struct ype *yv_type;                       /* flags & YV_TYPE */
+
+    struct ypv *yv_next;
+}                      ypv, *YV;
+#define        NULLYV  ((YV) 0)
+
+YV     new_value (), add_value (), copy_value ();
+
+/* \f */
+
+typedef struct ypt {
+    PElementClass   yt_class;
+
+    YV             yt_value;
+}                      ypt, *YT;
+#define        NULLYT  ((YT) 0)
+
+YT     new_tag (), copy_tag ();
+
+%BEGIN(PEPSY)%
+/* Encoding functions definitions */
+typedef struct yfn {
+       char    *yfn_enc; /* Encoding function name */
+       char    *yfn_dec; /* Decoding function name */
+       char    *yfn_prt; /* Printing function name */
+       char    *yfn_fre; /* Freeing function name */
+}      yfn, *YFN;
+
+#define NULLYFN        ((YFN) 0)
+
+extern YFN new_yfn(), join_yfn();
+
+typedef struct action_t        {
+       char    *a_data;        /* actual C text of action statement */
+       int     a_line;         /* line number of input we came from */
+       int     a_num;          /* number for case statement */
+}      action_t, *Action;
+#define NULLAction     ((Action)0)
+
+extern Action  new_action_t();
+
+typedef struct yactlist        {
+       Action  yal_enc;
+       Action  yal_dec;
+       Action  yal_prn;
+       char    *yal_comment;   /* A comment as to where the line comes from */
+       char    *yal_type;      /* the C type of the parm used in this action */
+}   yactlist_t, *YAL;
+#define NULLYAL        ((YAL)0)
+
+extern YAL     new_yal(), yal_join();
+
+extern Action  start_action, final_action;
+
+extern int     e_actions, d_actions, p_actions;
+
+#define ER_UNKNOWN     0       /* Unknown what the type is - warn if used */
+#define ER_NORMAL      1       /* Implicit works normally */
+#define ER_EXPLICIT    2       /* Implicit should be translated to explicit */
+
+
+%END(PEPSY)%
+
+/* \f */
+
+typedef struct ype {
+    int     yp_code;
+#define        YP_UNDF         0x00    /* type not yet known */
+#define        YP_BOOL         0x01    /* BOOLEAN */
+#define        YP_INT          0x02    /* INTEGER */
+#define        YP_INTLIST      0x03    /* INTEGER [ NamedNumberList ] */
+#define        YP_BIT          0x04    /* BITSTRING */
+#define        YP_BITLIST      0x05    /* BITSTRING [ NamedNumberList ] */
+#define        YP_OCT          0x06    /* OCTETSTRING */
+#define        YP_NULL         0x07    /* NULL */
+#define        YP_SEQ          0x08    /* SEQUENCE */
+#define        YP_SEQTYPE      0x09    /* SEQUENCE OF Type */
+#define        YP_SEQLIST      0x0a    /* SEQUENCE [ ElementTypes ] */
+#define        YP_SET          0x0b    /* SET */
+#define        YP_SETTYPE      0x0c    /* SET OF Type */
+#define        YP_SETLIST      0x0d    /* SET [ MemberTypes ] */
+#define        YP_CHOICE       0x0e    /* CHOICE [ AlternativeTypeList ] */
+#define        YP_ANY          0x0f    /* ANY */
+#define        YP_OID          0x10    /* OBJECT IDENTIFIER */
+#define        YP_IDEFINED     0x11    /* identifier */
+#define YP_ENUMLIST    0x12    /* ENUMERATED */
+#define YP_REAL                0x13    /* Real (floating-point) */
+#define YP_IMPTYPE     0x14    /* Imported - real type unknown */
+
+    int     yp_direction;
+#define YP_DECODER     0x01
+#define YP_ENCODER     0x02
+#define        YP_PRINTER      0x04
+
+    union {
+       struct {                                /* code = YP_IDEFINED */
+           char   *yp_st_module;                   /* module name */
+           OID     yp_st_modid;                    /* module id */
+           char   *yp_st_identifier;               /* definition name */
+       }               yp_st;
+
+       struct ype *yp_un_type;                 /* code = YP_SEQTYPE
+                                                  code = YP_SEQLIST
+                                                  code = YP_SETTYPE
+                                                  code = YP_SETLIST
+                                                  code = YP_CHOICE */
+
+       YV          yp_un_value;                /* code = YP_INTLIST
+                                                  code = YP_BITLIST */
+    }                   yp_un;
+#define        yp_identifier   yp_un.yp_st.yp_st_identifier
+#define        yp_module       yp_un.yp_st.yp_st_module
+#define yp_modid       yp_un.yp_st.yp_st_modid
+#define        yp_type         yp_un.yp_un_type
+#define        yp_value        yp_un.yp_un_value
+
+    char   *yp_intexp;         /* expressions to pass (use) as extra */
+    char   *yp_strexp;         /* parameters (primitive values) */
+    char    yp_prfexp;
+
+    char   *yp_declexp;
+    char   *yp_varexp;
+
+    char   *yp_structname;
+    char   *yp_ptrname;
+
+    char   *yp_param_type;
+
+    char   *yp_action0;
+    int     yp_act0_lineno;
+
+    char   *yp_action05;
+    int            yp_act05_lineno;
+
+    char   *yp_action1;
+    int            yp_act1_lineno;
+
+    char   *yp_action2;
+    int            yp_act2_lineno;
+
+    char   *yp_action3;
+    int            yp_act3_lineno;
+
+    int     yp_flags;
+#define        YP_NOFLAGS      0x0000  /* no flags */
+#define        YP_OPTIONAL     0x0001  /* OPTIONAL */
+#define        YP_COMPONENTS   0x0002  /* COMPONENTS OF */
+#define        YP_IMPLICIT     0x0004  /* IMPLICIT */
+#define        YP_DEFAULT      0x0008  /* DEFAULT */
+#define        YP_ID           0x0010  /* ID */
+#define        YP_TAG          0x0020  /* Tag */
+#define        YP_BOUND        0x0040  /* ID LANGLE */
+#define        YP_PULLEDUP     0x0080  /* member is a choice */
+#define YP_PARMVAL     0x0100  /* value to be passed to parm is present */
+#define YP_CONTROLLED  0x0200  /* encoding item has a controller */
+#define        YP_OPTCONTROL   0x0400  /*   .. */
+#define        YP_ACTION1      0x0800  /* action1 acted upon */
+#define        YP_PARMISOID    0x1000  /* value to be passed to parm is OID */
+#define YP_ENCRYPTED   0x2000  /* encypted - which is a bit hazy */
+#define YP_IMPORTED    0x4000  /* value imported from another module */
+#define YP_EXPORTED    0x8000  /* value exported to another module */
+#define YP_WANTIMPLICIT 0x10000 /* Keep the implicit tag */
+#define        YPBITS  "\020\01OPTIONAL\02COMPONENTS\03IMPLICIT\04DEFAULT\05ID\06TAG\
+\07BOUND\010PULLEDUP\011PARMVAL\012CONTROLLED\013OPTCONTROL\
+\014ACTION1\015PARMISOID\016ENCRYPTED\017IMPORTED\020EXPORTED"
+
+    YV     yp_default;                         /* flags & YP_DEFAULT */
+
+    char   *yp_id;                             /* flags & YP_ID */
+
+    YT     yp_tag;                             /* flags & YP_TAG */
+
+    char   *yp_bound;                          /* flags & YP_BOUND */
+
+    char   *yp_parm;                           /* flags & YP_PARMVAL */
+
+    char   *yp_control;                                /* flags & YP_CONTROLLED */
+
+    char   *yp_optcontrol;                     /* flags & YP_OPTCONTROL */
+
+    char   *yp_offset;
+
+    struct ype *yp_next;
+
+%BEGIN(PEPSY)%
+    YFN           yp_yfn;      /* encoding/decoding functions */
+
+    YAL    yp_bef_alist;       /* list of before this */
+    YAL    yp_aft_alist;       /* list of after this */
+
+    YAL           yp_control_act;      /* controlled actions */
+    YAL           yp_optional_act;     /* optional actions */
+%END(PEPSY)%
+    
+    int           yp_lineno;           /* line number for diagnostics */
+
+}                      ype, *YP;
+#define        NULLYP  ((YP) 0)
+
+YP     new_type (), add_type (), copy_type (), lkup();
+
+char   *new_string ();
+
+#define        TBL_EXPORT      0
+#define TBL_IMPORT     1
+#define MAX_TBLS       2
+
+extern int tagcontrol;
+#define TAG_UNKNOWN    0
+#define TAG_IMPLICIT   1
+#define TAG_EXPLICIT   2
+
+#define CH_FULLY       0
+#define CH_PARTIAL     1
+
+typedef struct yop {
+    char   *yo_name;
+
+    YP     yo_arg;
+    YP     yo_result;
+    YV     yo_errors;
+    YV     yo_linked;
+
+    int            yo_opcode;
+}              yop, *YO;
+#define        NULLYO  ((YO) 0)
+
+
+typedef struct yerr {
+    char   *ye_name;
+
+    YP     ye_param;
+
+    int            ye_errcode;
+
+    int            ye_offset;
+}          yerr, *YE;
+#define        NULLYE  ((YE) 0)
+
+typedef struct modlist {
+    char   *md_module;
+    OID    md_oid;
+    int          md_flags;
+#define MDF_SEEN              1       /* Seen this module */
+
+    struct modlist *md_next;
+}             modlist, *MD;
+#define       NULLMD  ((MD) 0)
+
+/* \f */
+
+%BEGIN(PEPSY)%
+extern char *pepsyversion;
+%END(PEPSY)%
+%BEGIN(PEPY)%
+extern char *pepyversion;
+%END(PEPY)%
+
+extern int yysection;
+extern char *yyencpref;
+extern char *yydecpref;
+extern char *yyprfpref;
+extern char *yyencdflt;
+extern char *yydecdflt;
+extern char *yyprfdflt;
+
+extern int yydebug;
+extern int yylineno;
+
+#if defined(linux) || defined(mips)
+extern char *yytext;
+#else
+#ifndef        HPUX
+extern char yytext[];
+#else
+extern unsigned char yytext[];
+#endif
+#endif
+
+extern char *mymodule;
+
+extern OID   mymoduleid;
+
+extern char *bflag;
+extern int   Cflag;
+extern int   dflag;
+extern int   Pflag;
+extern char *sysin;
+
+extern char *module_actions;
+
+OID    addoid ();
+OID    int2oid ();
+OID    oidlookup ();
+char   *oidname ();
+char   *oidprint ();
+
+extern int errno;
diff --git a/src/isode/pepsy/pepy-refs.h b/src/isode/pepsy/pepy-refs.h
new file mode 100644 (file)
index 0000000..d4b78eb
--- /dev/null
@@ -0,0 +1,146 @@
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:27  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:22  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:13  isode
+ * Release 7.0
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+/*
+ * data structure(s) for module T3 (t3.py)
+ */
+
+/* bits to use for optional fields */
+#define OPT_REAL1      0
+#define OPT_INT1       1
+#define OPT_INT2       2
+#define OPT_ENUM1      3
+#define OPT_ENUM2      4
+#define OPT_BOOL1      5
+#define OPT_BOOL2      6
+#define OPT_REAL2      7
+#define NUMOPT         8
+
+struct pepy_refs {
+    integer            t_int;
+    integer            t_enum;
+    struct qbuf                *t_qbuf;
+    char               *t_string;
+    char               *t_ostring;
+    char               *t_bstring;
+    int                        t_blen;
+    int                        t_olen;
+    char               t_bool;
+    double             t_real;
+    OID                        t_oid;
+    PE                 t_pe;
+    PE                 t_any;
+    struct pepy_refs1  *t_def;
+    struct pepy_refs1  *t_opt;
+    char       opt_set[NBITS2NCHARS(NUMOPT)]
+       };
+
+struct pepy_refs1 {
+    integer            t_int;
+    integer            t_int1;
+    integer            t_enum;
+    integer            t_enum1;
+    struct qbuf                *t_qbuf;
+    struct qbuf                *t_qbuf1;
+    char               *t_string;
+    char               *t_string1;
+    char               *t_ostring;
+    char               *t_ostring1;
+    char               *t_bstring;
+    int                        t_blen;
+    char               *t_bstring1;
+    int                        t_blen1;
+    int                        t_olen;
+    int                        t_olen1;
+    char               t_bool;
+    char               t_bool1;
+    double             t_real;
+    double             t_real1;
+    OID                        t_oid;
+    OID                        t_oid1;
+    PE                 t_pe;
+    PE                 t_pe1;
+    PE                 t_any;
+    char       opt_set[NBITS2NCHARS(NUMOPT)]
+       };
+
+struct rep_elem {
+       int             r_int;
+       char            *r_ostring;
+       char            *r_bstring;
+       struct rep_elem *r_next;
+    };
+#define NULLREP_ELEM   (struct rep_elem *)0
+
+struct rep_int {
+       int             i;
+       struct rep_int  *r;
+       };
+#define NULLREP_INT    (struct rep_int *)0
+
+
+struct repeats {
+       struct rep_int  *rp_sq1;        /* SEQUECE of INTEGER */
+       struct rep_elem *rp_sq2;        /* SEQUENCE OF Rep-elem */
+       struct rep_int  *rp_st1;        /* SET OF INTEGER */
+       struct rep_elem *rp_st2;        /* SET OF Rep-elem */
+
+       int     rp_choice;
+#define RP_INT         1       /* INTEGER */
+#define RP_BOOL                2       /* BOOLEAN */
+#define RP_OSTRING     3       /* OCTET STRING */
+       int     rp_int;         /* integer or boolean */
+       char    rp_bool;        /* integer or boolean */
+       char    *rp_ostring;
+};
+
+#define CD_INT         0
+#define CD_C           1
+#define CD_D           2
+#define NCD_OPT                3
+
+struct codedata {
+       PE      cd_a;
+       PE      cd_b;
+       PE      cd_c;
+       PE      cd_d;
+       integer cd_int;
+       integer cd_int1;
+       integer cd_int2;
+       char    *cd_string;
+       char    *cd_string1;
+       char    *cd_string2;
+       struct codedata *cd_left;
+       struct codedata *cd_right;
+       char    cd_opt_set[NBITS2NCHARS(NCD_OPT)];
+       char    cd_bool;
+       double  cd_real;
+       OID     cd_oid;
+       OID     cd_oid1;
+       OID     cd_oid2;
+       PE      cd_bit;
+};
+
diff --git a/src/isode/pepsy/prnt.c b/src/isode/pepsy/prnt.c
new file mode 100644 (file)
index 0000000..9c23b6c
--- /dev/null
@@ -0,0 +1,1740 @@
+/* prnt.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:29  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:23  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:13  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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       <varargs.h>
+#include       "pepsy-driver.h"
+#include       "psap.h"
+#include       "pepsy.h"
+#include       "tailor.h"
+
+#define PRINT_TYPES    0
+#define        CHOICE_PUSH
+
+
+extern PE p_setpresent();
+extern IFP vfnx;
+extern FILE *vfp;
+
+extern ptpe *next_ptpe();
+extern int pepsylose ();
+
+int     xlevel = 0;
+int     tabed = 0;
+int     xpushed = 0;
+
+#define NEXT_PTPE(p)   (p = next_ptpe(p))
+#define CHKTAG(mod, p, pe)     p_ismatch(p, mod, pe->pe_class, pe->pe_id)
+
+static int p_pr_obj();
+static int p_pr_type();
+static int p_pr_seq();
+static int p_pr_set();
+static int p_pr_seqof();
+static int p_pr_setof();
+static int p_pr_choice();
+static int p_pr_etype();
+
+/* SUPPRESS 36 *//* for Saber C */
+
+/*
+ * to guarentee the rules that vname and a vprint-type routine are called
+ * alternatively. Basically can't have two vname's in a row
+ */
+static vnamelock = 0;
+   /* if vnamelock > 0 don't call vname */
+#define VNAME(x)  if (vnamelock++ <= 0) vname(x); else
+#define VTAG(class, tag)       if (vnamelock++ <= 0)  \
+                                       vtag((int )class, (int )tag); else
+
+/* as vprint takes a variable number of arguements we have to put all of
+ * the arguements inside () and remove them when we expand to vprint
+ */
+#define VPRINT(x)      vnamelock = 0, vprint x
+#define VSTRING(x)     vnamelock = 0, vstring(x)
+#define VUNKNOWN(x)    vnamelock = 0, vunknown(x)
+#define VPUSH          vnamelock = 0, vpush
+#define VPOP           vnamelock = 0, vpop
+
+
+/*
+ * Print out ASN data given in pe using the information given in the tables
+ */
+prnt_f(typ, mod, pe, explicit, len, buf)
+/* ARGSUSED */
+int     typ;                   /* which type it is */
+modtyp *mod;                   /* ASN Module it is from */
+PE      pe;
+int     explicit;      /* nonzero means we are call top level 
+                        * print final \n
+                        */
+int    *len;
+char  **buf;
+{
+    ptpe   *p;
+
+    if (typ < 0 || typ >= mod->md_nentries) {
+       return (ppepsylose (mod, NULLPTPE, pe, "prnt_f:Illegal type %d\n",typ));
+    }
+
+    p = mod->md_ptab[typ];
+
+    if (p->pe_type != PE_START) {
+       return (ppepsylose (mod, p, pe, "prnt_f: missing PE_START\n"));
+    }
+
+#if EXTRA_BRACKETS
+    if (explicit) {
+       if (p->pe_typename)
+           VNAME(*p->pe_typename);
+    }
+    VPUSH();
+#endif
+
+
+    if (p_pr_obj(explicit, pe, p, mod) == NOTOK) {
+#if EXTRA_BRACKETS
+       VPOP();
+#endif
+       return (NOTOK);
+    }
+#if EXTRA_BRACKETS
+    VPOP();
+#endif
+    return (OK);
+}
+
+/*
+ * Parse an object. The top level of an object does not have any
+ * offset field which makes it different to pr_type routine which
+ * must assume that it has an offset.
+ */
+static int
+p_pr_obj(expl, pe, p, mod)
+int     expl;                  /* do we look at the tag */
+PE      pe;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    int     cnt = 0;
+
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+
+    p++;
+    while (p->pe_type != PE_END) {
+
+       if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) {
+           if (DEFAULT(p)) {
+               return (ppepsylose (mod, p, pe,
+                   "p_pr_obj:Default not implemented\n"));
+           }
+           else if (OPTIONAL(p))
+               return (NO_DATA_USED);
+           else {
+               return (ppepsylose (mod, p, pe,
+                   "p_pr_obj:missing mandatory parameter", p, mod));
+           }
+       }
+       if (p->pe_typename)
+           VNAME(*p->pe_typename);
+       switch (p->pe_type) {
+       case PE_END:
+       case PE_START:
+           goto bad;
+
+       case UCODE:
+           if (mod->md_pucode == NULLIFP
+           || (*mod->md_pucode) (pe, p) == NOTOK)
+               goto bad;
+           break;
+
+
+       default:
+           if (p_pr_type(expl, pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+       }
+       if (ISDTYPE(p) && cnt > 0)
+           return (ppepsylose (mod, p, pe, "p_pr_obj:compound type found\n"));
+       if (ISDTYPE(p) && pe != NULLPE) {
+           return (OK);
+       }
+       if (NEXT_PTPE(p) == NULLPTPE)
+           goto bad;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+
+/*
+ * Parse a single type. If a basic type parse it, if a compound type
+ * call the appropriate parsing routine
+ */
+static int
+p_pr_type(expl, pe, p, mod)
+int     expl;                  /* do we look at the tag */
+PE      pe;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    int     cnt = 0;
+    integer     i;
+    OID     oid;
+
+
+    while (p->pe_type != PE_END) {
+
+       if (ISDTYPE(p) && expl && CHKTAG(mod, p, pe) == 0) {
+           if (DEFAULT(p)) {
+#ifdef PRINT_DEFAULTS
+               setpval(p, p + 1, mod);
+#endif
+               return (OK);
+           } else if (OPTIONAL(p))
+               return (OK);
+           else {
+               dmp_ptpe("p_pr_type:missing mandatory parameter", p, mod);
+               goto bad;
+           }
+       }
+       switch (p->pe_type) {
+       case PE_END:
+       case PE_START:
+           goto bad;
+
+        case BOPTIONAL:
+            if (CHKTAG(mod, p + 1, pe) == 0) {
+                return (OK);
+            }
+            p++;
+            continue;
+
+       case UCODE:
+           if (mod->md_pucode == NULLIFP
+           || (*mod->md_pucode) (pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       case ETAG:
+           switch (p->pe_ucode) {
+           default:
+               if (p_pr_etype(pe->pe_cons, p, mod) == NOTOK)
+                   goto bad;
+           }
+           break;
+
+       case SSEQ_START:
+       case SEQ_START:
+           if (p_pr_seq(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SSEQOF_START:
+       case SEQOF_START:
+           if (p_pr_seqof(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SSET_START:
+       case SET_START:
+           if (p_pr_set(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SSETOF_START:
+       case SETOF_START:
+           if (p_pr_setof(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case IMP_OBJ:
+           p++;
+           if (p->pe_type == EXTOBJ || p->pe_type == SEXTOBJ) {
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                   (char **) 0) == NOTOK)
+                   goto bad;
+           } else {
+               if (p_pr_obj(0, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+           }
+           break;
+
+       case SOBJECT:
+       case OBJECT:
+           if (p_pr_obj(expl, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SCHOICE_START:
+       case CHOICE_START:
+           if (p_pr_choice(pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               return (ppepsylose (mod, p, pe, "p_pr_type: missing EXTMOD"));
+           }
+           if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                  (char **) 0) == NOTOK)
+                  goto bad;
+           break;
+
+       case INTEGER:
+           if (pe != NULLPE) {
+               if ((i = prim2num(pe)) == NOTOK && pe->pe_errno != PE_ERR_NONE)
+                   goto bad;
+               VPRINT(("%d", i));
+           }
+           break;
+
+#ifdef PEPSY_REALS
+       case REALTYPE:
+           if (pe != NULLPE) {
+               double r;
+
+               if ((r = prim2real(pe)) == NOTOK
+                   && pe->pe_errno != PE_ERR_NONE)
+                   goto bad;
+               VPRINT(("%g", r));
+           }
+           break;
+#endif
+
+       case BOOLEAN:
+           if (pe != NULLPE) {
+               if ((i = prim2flag(pe)) == NOTOK)
+                   goto bad;
+               VPRINT((i ? "TRUE" : "FALSE"));
+           }
+           break;
+
+       case T_NULL:
+           VPRINT(("NULL"));
+           break;
+
+       case SANY:
+           if (pe != NULLPE) {
+               if (pe->pe_errno != PE_ERR_NONE) {
+                   goto bad;
+               } else
+                   VUNKNOWN(pe);
+           }
+           break;
+
+
+       case ANY:
+           if (pe != NULLPE) {
+               if (pe->pe_errno != PE_ERR_NONE) {
+                   goto bad;
+               } else
+                   VUNKNOWN(pe);
+           }
+           break;
+
+       case SOCTETSTRING:
+           if (pe != NULLPE) {
+               VSTRING(pe);
+           }
+           break;
+
+       case OCTETSTRING:
+       case T_STRING:
+       case OCTET_PTR:
+           if (pe != NULLPE) {
+               VSTRING(pe);
+           }
+           break;
+
+       case SBITSTRING:
+           if (pe != NULLPE) {
+               PE      bstr;
+
+               if ((bstr = prim2bit(pe)) == NULLPE)
+                   goto bad;
+               if (p -> pe_ucode >= 0 && mod->md_ptrtab &&
+                   mod -> md_ptrtab[p -> pe_ucode] &&
+                   bstr -> pe_nbits < LOTSOFBITS)
+                   VPRINT (("%s", bit2str(bstr,
+                                          mod -> md_ptrtab[p -> pe_ucode])));
+               else if (bstr->pe_nbits < LOTSOFBITS)
+                   VPRINT(("%s", bit2str(bstr, "\020")));
+               else
+                   VUNKNOWN(pe);
+           }
+           break;
+
+       case BITSTR_PTR:
+       case BITSTRING:
+           if (pe != NULLPE) {
+               PE      bstr;
+
+               if ((bstr = prim2bit(pe)) == NULLPE)
+                   goto bad;
+               if (p -> pe_ucode >= 0 && mod->md_ptrtab &&
+                   mod -> md_ptrtab[p -> pe_ucode] &&
+                   bstr -> pe_nbits < LOTSOFBITS)
+                   VPRINT (("%s", bit2str(bstr,
+                                          mod -> md_ptrtab[p -> pe_ucode])));
+               else if (bstr->pe_nbits < LOTSOFBITS)
+                   VPRINT(("%s", bit2str(bstr, "\020")));
+               else
+                   VUNKNOWN(pe);
+           }
+           break;
+
+       case SOBJID:
+           if ((oid = (OID) prim2oid(pe)) == NULLOID) {
+               goto bad;
+           } else {
+               VPRINT(("%s", oid2ode(oid)));
+           }
+           break;
+
+       case OBJID:
+           if ((oid = (OID) prim2oid(pe)) == NULLOID) {
+               goto bad;
+           } else {
+               VPRINT(("%s", oid2ode(oid)));
+           }
+           break;
+
+       case FN_CALL:
+           if ((FN_PTR(mod, p))(pe) == NOTOK)
+               return ppepsylose (mod, &p[1], NULLPE,
+                                 "p_pr_type:FN_CALL:call failed");
+           break;
+
+       default:
+           return (ppepsylose (mod, p, pe, "p_pr_type: %d not implemented\n",
+               p->pe_type));
+       }
+       if (ISDTYPE(p) && cnt > 0)
+           return (ppepsylose (mod, p, pe, "p_pr_type:compound type found\n"));
+       if (ISDTYPE(p) && pe != NULLPE)
+           return (OK);
+       if (NEXT_PTPE(p) == NULLPTPE)
+           goto bad;
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Parse a sequence, calling appropriate routines to parse each sub
+ * type
+ */
+static int
+p_pr_seq(head, p, mod)
+PE      head;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+
+    if (p->pe_type != SEQ_START && p->pe_type != SSEQ_START)
+       return (ppepsylose (mod, p, head, "p_pr_seq: missing SEQ_START\n"));
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+    VPUSH();
+
+    p++;
+    if (p->pe_type == DFLT_B)
+       p++;
+
+
+    pe = first_member(head);
+    while (p->pe_type != PE_END) {
+       if (ISDTYPE(p) && OPTIONAL(p)) {
+           if (pe == NULLPE || CHKTAG(mod, p, pe) == 0)
+               goto next;
+       } else if (ISDTYPE(p) && (pe == NULLPE || CHKTAG(mod, p, pe) == 0)) {
+           if (DEFAULT(p)) {
+#ifdef PRINT_DEFAULTS
+               setpval(p, p + 1, mod);
+#endif
+               goto next;
+           } else {
+               dmp_ptpe("p_pr_seq:missing mandatory parameter", p, mod);
+               goto bad;
+           }
+       }
+       if (p->pe_typename)
+           VNAME(*p->pe_typename);
+       switch (p->pe_type) {
+       case OPTL:
+           break;
+
+       case UCODE:
+           if (mod->md_pucode == NULLIFP
+           || (*mod->md_pucode) (pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       case BOPTIONAL:
+           if (CHKTAG(mod, p + 1, pe) == 0)
+               goto next;
+           p++;
+           continue;
+
+       case ETAG:
+           if (p_pr_type(1, pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQ_START:
+           if (p_pr_seq(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SEQOF_START:
+           if (p_pr_seqof(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SET_START:
+           if (p_pr_set(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SETOF_START:
+           if (p_pr_setof(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case IMP_OBJ:
+           p++;
+           if (p->pe_type == EXTOBJ) {
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                   (char **) 0) == NOTOK)
+                   goto bad;
+           } else {
+               if (p_pr_obj(0, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+           }
+           break;
+
+       case SOBJECT:
+           if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case OBJECT:
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+           if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SCHOICE_START:
+       case CHOICE_START:
+           if (p_pr_choice(pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               return (ppepsylose (mod, p, pe, "p_pr_seq: missing EXTMOD"));
+           }
+           if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0,NULLIP,
+               (char **)0) == NOTOK)
+               goto bad;
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               return (ppepsylose (mod, p, pe, "p_pr_seq: missing EXTMOD"));
+           }
+           if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                   (char **)0) == NOTOK)
+               goto bad;
+           break;
+
+       default:
+           if (p_pr_type(1, pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+       }
+
+       if (ISDTYPE(p) && pe != NULLPE)
+           pe = next_member(head, pe);
+next:
+       if (NEXT_PTPE(p) == NULLPTPE)
+           goto bad;
+    }
+
+    VPOP();
+    return (OK);
+
+bad:
+    VPOP();
+    return (NOTOK);
+}
+
+
+/*
+ * Parse a set, calling appropriate routines to parse each sub type
+ */
+static int
+p_pr_set(head, p, mod)
+PE      head;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+
+    if (p->pe_type != SET_START && p->pe_type != SSET_START)
+       return (ppepsylose (mod, p, head, "p_pr_seq: missing SET_START\n"));
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+    VPUSH();
+
+    p++;
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    while (p->pe_type != PE_END) {
+
+       if (ISDTYPE(p) && OPTIONAL(p)) {
+           if ((pe = (PE) p_setpresent(head, p, mod)) == NULLPE)
+               goto next;
+       } else if (ISDTYPE(p)
+           && (pe = (PE) p_setpresent(head, p, mod)) == NULLPE) {
+           if (DEFAULT(p)) {
+#ifdef PRINT_DEFAULTS
+               setpval(p, p + 1, mod);
+#endif
+               goto next;
+           } else {
+               dmp_ptpe("p_pr_set:missing mandatory parameter", p, mod);
+               goto bad;
+           }
+       }
+       if (p->pe_typename)
+           VNAME(*p->pe_typename);
+       switch (p->pe_type) {
+       case OPTL:
+           break;
+
+       case UCODE:
+           if (mod->md_pucode == NULLIFP
+           || (*mod->md_pucode) (pe, p) == NOTOK)
+               goto bad;
+           break;
+
+       case BOPTIONAL:
+           if ((pe = (PE) p_setpresent(head, p + 1, mod)) == NULLPE)
+               goto next;
+           p++;
+           continue;
+
+       case ETAG:
+           if (p_pr_type(1, pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEQ_START:
+           if (p_pr_seq(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SEQOF_START:
+           if (p_pr_seqof(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SET_START:
+           if (p_pr_set(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SETOF_START:
+           if (p_pr_setof(pe, p, mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case IMP_OBJ:
+           p++;
+           if (p->pe_type == EXTOBJ) {
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                      (char **) 0) == NOTOK)
+                      goto bad;
+           } else {
+               if (p_pr_obj(0, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+           }
+           break;
+
+       case SOBJECT:
+           if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case OBJECT:
+           if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+               goto bad;
+           }
+           break;
+
+       case SCHOICE_START:
+       case CHOICE_START:
+           if (p_pr_choice(pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+
+       case SEXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               return (ppepsylose (mod, p, pe, "p_pr_set: missing EXTMOD"));
+           }
+           if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP, (char **)0) == NOTOK)
+                   return (NOTOK);
+           break;
+
+       case EXTOBJ:
+           if (p[1].pe_type != EXTMOD) {
+               return (ppepsylose (mod, p, pe, "p_pr_set: missing EXTMOD"));
+           }
+           if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+               (char **)0) == NOTOK)
+               goto bad;
+           break;
+
+       default:
+           if (p_pr_type(1, pe, p, mod) == NOTOK)
+               goto bad;
+           break;
+       }
+
+next:
+       if (NEXT_PTPE(p) == NULLPTPE)
+           goto bad;
+    }
+
+    VPOP();
+    return (OK);
+
+bad:
+    VPOP();
+    return (NOTOK);
+}
+
+
+/*
+ * Parse a sequence of calling appropriate routines to parse each sub
+ * type
+ */
+
+static int
+p_pr_seqof(head, p, mod)
+PE      head;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+    ptpe   *start;             /* first entry in list */
+    int     dflt = 0;
+
+    if (p->pe_type != SEQOF_START && p->pe_type != SSEQOF_START) {
+       return (ppepsylose (mod, p, head, "p_pr_seqof: missing SEQOF_START\n"));
+    }
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+    VPUSH();
+
+    p++;
+
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    start = p;
+
+
+    pe = first_member(head);
+    while (pe != NULLPE) {
+       while (p->pe_type != PE_END) {
+
+           if (ISDTYPE(p) && CHKTAG(mod, p, pe) == 0) {
+               if (DEFAULT(p))
+                   return (ppepsylose (mod, p, pe,
+                       "p_pr_seqof:Default not implemented\n"));
+               else if (OPTIONAL(p))
+                   goto next;
+               else {
+                   return (ppepsylose (mod, p, pe,
+                       "p_pr_seqof:missing mandatory parameter"));
+               }
+           }
+           if (p->pe_typename)
+               VNAME(*p->pe_typename);
+           switch (p->pe_type) {
+           case UCODE:
+               if (mod->md_pucode == NULLIFP
+               || (*mod->md_pucode) (pe, p) == NOTOK)
+                   goto bad;
+               break;
+
+           case BOPTIONAL:
+               if (CHKTAG(mod, p + 1, pe) == 0)
+                   goto next;
+               p++;
+               continue;
+
+           case ETAG:
+               if (p_pr_type(1, pe, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+               /*
+                * case SCTRL:  parm = (char *) ((char *) parm);
+                * break;
+                */
+
+           case SEQ_START:
+               if (p_pr_seq(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SEQOF_START:
+               if (p_pr_seqof(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SET_START:
+               if (p_pr_set(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SETOF_START:
+               if (p_pr_setof(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SOBJECT:
+               if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case OBJECT:
+               if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SCHOICE_START:
+           case CHOICE_START:
+               if (p_pr_choice(pe, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD) {
+                   return (ppepsylose (mod, p, pe,"p_pr_seqof:missing EXTMOD"));
+               }
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                    (char **)0) == NOTOK)
+                    goto bad;
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD) {
+                   return (ppepsylose (mod, p, pe,"p_pr_seqof:missing EXTMOD"));
+               }
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP, 
+                   (char **) 0) == NOTOK)
+                   goto bad;
+               break;
+
+           default:
+               if (p_pr_type(1, pe, p, mod) == NOTOK)
+                   goto bad;
+               break;
+           }
+
+           if (ISDTYPE(p) && dflt == 0)
+               pe = next_member(head, pe);
+    next:
+           if (NEXT_PTPE(p) == NULLPTPE)
+               goto bad;
+       }
+       /* parm = (char *) (parm); */
+       p = start;
+    }
+
+    VPOP();
+    return (OK);
+
+bad:
+    VPOP();
+    return (NOTOK);
+}
+
+/*
+ * Parse a setof, calling appropriate routines to parse each sub type
+ */
+static int
+p_pr_setof(head, p, mod)
+PE      head;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    PE      pe;
+    ptpe   *start;
+
+    if (p->pe_type != SETOF_START && p->pe_type != SSETOF_START)
+       return (ppepsylose (mod, p, head, "p_pr_setof: missing SETOF_START\n"));
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+    VPUSH();
+
+    p++;
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    start = p;
+
+    for (pe = first_member(head); pe; pe = next_member(head, pe)) {
+       while (p->pe_type != PE_END) {
+           if (pe == NULLPE || CHKTAG(mod, p, pe) == 0) {
+               if (DEFAULT(p)) {
+#ifdef PRINT_DEFAULTS
+                   setpval(p, p + 1, mod);
+#endif
+                   goto next;
+               } else {
+                   dmp_ptpe("p_pr_setof:missing mandatory parameter", p, mod);
+                   goto bad;
+               }
+           }
+
+           if (p->pe_typename)
+               VNAME(*p->pe_typename);
+           switch (p->pe_type) {
+           case UCODE:
+               if (mod->md_pucode == NULLIFP
+               || (*mod->md_pucode) (pe, p) == NOTOK)
+                   goto bad;
+               break;
+
+           case BOPTIONAL:
+               if ((pe = (PE) p_setpresent(head, p + 1, mod)) == NULLPE)
+                   goto next;
+               p++;
+               continue;
+
+           case ETAG:
+               if (p_pr_type(1, pe->pe_cons, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+               /*
+                * case SCTRL: parm = (char *) (parm); break;
+                */
+
+           case SEQ_START:
+               if (p_pr_seq(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SEQOF_START:
+               if (p_pr_seqof(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SET_START:
+               if (p_pr_set(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SETOF_START:
+               if (p_pr_setof(pe, p, mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SOBJECT:
+               if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case OBJECT:
+               if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK) {
+                   goto bad;
+               }
+               break;
+
+           case SCHOICE_START:
+           case CHOICE_START:
+               if (p_pr_choice(pe, p, mod) == NOTOK)
+                   goto bad;
+               break;
+
+           case SEXTOBJ:
+               if (p[1].pe_type != EXTMOD) {
+                   return (ppepsylose (mod, p, pe,"p_pr_setof:missing EXTMOD"));
+               }
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                   (char **) 0) == NOTOK)
+                   goto bad;
+               break;
+
+           case EXTOBJ:
+               if (p[1].pe_type != EXTMOD) {
+                   return (ppepsylose (mod, p, pe,"p_pr_setof:missing EXTMOD"));
+               }
+               if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                   (char **) 0) == NOTOK)
+                   goto bad;
+               break;
+
+           default:
+               if (p_pr_type(1, pe, p, mod) == NOTOK)
+                   goto bad;
+               break;
+           }
+
+    next:
+           if (NEXT_PTPE(p) == NULLPTPE)
+               goto bad;
+       }
+       /* parm = (char *)(parm); */
+       p = start;
+    }
+
+    VPOP();
+    return (OK);
+
+bad:
+    VPOP();
+    return (NOTOK);
+
+}
+
+/*
+ * parse a choice field. This means find which choice is taken
+ */
+static int
+p_pr_choice(head, p, mod)
+PE      head;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    if (p->pe_type != CHOICE_START && p->pe_type != SCHOICE_START) {
+       return (ppepsylose (mod, p, head, "p_pr_choice:missing CHOICE_START"));
+    }
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+#ifdef CHOICE_PUSH
+    VPUSH();
+#endif
+
+    p++;
+    if (p->pe_type == DFLT_B)
+       p++;
+
+    if (p->pe_type == SCTRL) {
+       p++;
+    }
+
+    for (; p->pe_type != PE_END; NEXT_PTPE(p)) {
+       if (ISDTYPE(p) && p_ismatch(p, mod, head->pe_class, head->pe_id)) {
+           if (p->pe_typename)
+               VNAME(*p->pe_typename);
+           if (p_pr_type(0, head, p, mod) == NOTOK)
+               return (NOTOK);
+#ifdef CHOICE_PUSH
+           VPOP();
+#endif
+           NEXT_PTPE(p);
+           if (p->pe_type == UCODE) {
+               if (mod->md_pucode == NULLIFP
+               || (*mod->md_pucode) (head, p) == NOTOK)
+                   return (NOTOK);
+           }
+           return (OK);
+       }
+    }
+
+    dmp_ptpe("p_pr_choice: no choice taken", p, mod);
+#ifdef CHOICE_PUSH
+       VPOP();
+#endif
+    return (NOTOK);
+}
+
+/*
+ * Calculate the next ptpe entry in the sequence. Count a sequence as
+ * one element
+ */
+ptpe   *
+next_ptpe(p)
+ptpe   *p;
+{
+    int     level;
+
+    level = 0;
+    if (p->pe_type == PE_END) {
+       (void) ppepsylose (NULLMODTYP, p, NULLPE,
+           "next_ptpe: unexpected PE_END");
+       return (NULLPTPE);
+    }
+    do {
+again:
+       switch (p->pe_type) {
+       case SSEQ_START:
+       case SSEQOF_START:
+       case SSET_START:
+       case SSETOF_START:
+       case SCHOICE_START:
+       case SEQ_START:
+       case SEQOF_START:
+       case SET_START:
+       case SETOF_START:
+       case CHOICE_START:
+           level++;
+           break;
+
+       case UCODE:
+       case SCTRL:
+       case CH_ACT:
+       case INTEGER:
+       case REALTYPE:
+       case BOOLEAN:
+       case SANY:
+       case ANY:
+       case T_NULL:
+       case OBJECT:
+       case SOBJECT:
+       case BITSTRING:
+       case SBITSTRING:
+       case BITSTR_LEN:
+       case OCTETSTRING:
+       case T_STRING:
+       case OCTET_LEN:
+       case SOCTETSTRING:
+       case OBJID:
+       case SOBJID:
+       case OPTL:
+       case EXTMOD:
+       case DFLT_B:
+       case FN_CALL:
+       case FFN_CALL:
+           break;
+
+       case OCTET_PTR:
+       case BITSTR_PTR:
+       case IMP_OBJ:
+       case ETAG:
+       case EXTOBJ:
+       case SEXTOBJ:
+       case DFLT_F:
+       case BOPTIONAL:
+           p++;
+           goto again;
+
+       case PE_END:
+           level--;
+           break;
+
+       default:
+           (void) ppepsylose (NULLMODTYP, p, NULLPE,
+               "next_ptpe: unknown type %d\n", p->pe_type);
+           return (NULLPTPE);
+       }
+       p++;
+    } while (level > 0 || p->pe_type == DFLT_B);
+
+    return (p);
+}
+
+/*
+ * Parse a single type for explicit tag If a basic type parse it, if
+ * a compound type call the appropriate parsing routine
+ */
+static int
+p_pr_etype(pe, p, mod)
+PE      pe;
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+{
+    integer     i;
+    OID     oid;
+
+    if (p->pe_type != ETAG)
+       return (ppepsylose (mod, p, pe, "p_pr_etype: missing ETAG\n"));
+    
+
+    if (PRINT_TAG(p))
+       VTAG (CLASS (p), TAG (p));
+    p++;
+
+    switch (p->pe_type) {
+    case PE_END:
+    case PE_START:
+       goto bad;
+
+    case UCODE:
+       if (mod->md_pucode == NULLIFP
+       || (*mod->md_pucode) (pe, p) == NOTOK)
+           goto bad;
+       break;
+
+    case BOPTIONAL:
+       return (ppepsylose (mod, p, pe, "p_pr_etype:illegal BOPTIONAL\n"));
+
+    case ETAG:
+       switch (p->pe_ucode) {
+
+       default:
+           if (p_pr_etype(pe->pe_cons, p, mod) == NOTOK)
+               goto bad;
+       }
+       break;
+
+    case SSEQ_START:
+    case SEQ_START:
+       if (p_pr_seq(pe, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSEQOF_START:
+    case SEQOF_START:
+       if (p_pr_seqof(pe, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSET_START:
+    case SET_START:
+       if (p_pr_set(pe, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SSETOF_START:
+    case SETOF_START:
+       if (p_pr_setof(pe, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case IMP_OBJ:
+       p++;
+       if (p->pe_type == EXTOBJ) {
+           if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+                  (char **) 0) == NOTOK)
+                  goto bad;
+       } else {
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+           if (p_pr_obj(0, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK)
+               goto bad;
+       }
+       break;
+
+    case SOBJECT:
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+       if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK)
+           goto bad;
+       break;
+
+    case OBJECT:
+#if PRINT_TYPES
+    if (p->pe_typename)
+       VNAME(*p->pe_typename);
+#endif
+       if (p_pr_obj(1, pe, mod->md_ptab[p->pe_tag], mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SCHOICE_START:
+    case CHOICE_START:
+       if (p_pr_choice(pe, p, mod) == NOTOK)
+           goto bad;
+       break;
+
+    case SEXTOBJ:
+       if (p[1].pe_type != EXTMOD) {
+           return (ppepsylose (mod, p, pe, "p_pr_etype: missing EXTMOD"));
+       }
+       if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+              (char **) 0) == NOTOK)
+              goto bad;
+       break;
+
+    case EXTOBJ:
+       if (p[1].pe_type != EXTMOD) {
+           return (ppepsylose (mod, p, pe, "p_pr_etype: missing EXTMOD"));
+       }
+       if (prnt_f(p->pe_tag, EXT2MOD(mod, (p + 1)), pe, 0, NULLIP,
+              (char **) 0) == NOTOK)
+              goto bad;
+       break;
+
+    case INTEGER:
+       if (pe != NULLPE) {
+           if ((i = prim2num(pe)) == NOTOK && pe->pe_errno != PE_ERR_NONE)
+               goto bad;
+           VPRINT(("%d", i));
+       }
+       break;
+
+#ifdef PEPSY_REALS
+    case REALTYPE:
+       if (pe != NULLPE) {
+           double r;
+
+           if ((r = prim2real(pe)) == NOTOK
+               && pe->pe_errno != PE_ERR_NONE)
+               goto bad;
+           VPRINT(("%g", r));
+       }
+       break;
+#endif
+
+
+    case BOOLEAN:
+       if (pe != NULLPE) {
+           if ((i= prim2flag(pe)) == NOTOK)
+               goto bad;
+           VPRINT((i ? "TRUE" : "FALSE"));
+       }
+       break;
+
+    case T_NULL:
+       VPRINT(("NULL"));
+       break;
+
+    case ANY:
+       if (pe != NULLPE) {
+           if (pe->pe_errno != PE_ERR_NONE) {
+               goto bad;
+           } else
+               VUNKNOWN(pe);
+       }
+       break;
+
+    case SANY:
+       if (pe != NULLPE) {
+           if (pe->pe_errno != PE_ERR_NONE) {
+               goto bad;
+           } else
+               VUNKNOWN(pe);
+       }
+       break;
+
+    case SOCTETSTRING:
+    case OCTETSTRING:
+    case T_STRING:
+    case OCTET_PTR:
+       if (pe != NULLPE) {
+           VSTRING(pe);
+       }
+       break;
+
+    case BITSTRING:
+    case BITSTR_PTR:
+    case SBITSTRING:
+       if (pe != NULLPE) {
+           PE  bstr;
+
+           if ((bstr = prim2bit(pe)) == NULLPE)
+               goto bad;
+           if (p -> pe_ucode >= 0 && mod->md_ptrtab &&
+               mod -> md_ptrtab[p -> pe_ucode] &&
+               bstr -> pe_nbits < LOTSOFBITS)
+               VPRINT (("%s", bit2str(bstr,
+                                      mod -> md_ptrtab[p -> pe_ucode])));
+           else if (bstr->pe_nbits < LOTSOFBITS)
+               VPRINT(("%s", bit2str(bstr, "\020")));
+           else
+               VUNKNOWN(pe);
+       }
+       break;
+
+    case SOBJID:
+       if ((oid = prim2oid(pe)) == NULLOID) {
+           goto bad;
+       } else {
+           VPRINT(("%s", oid2ode(oid)));
+       }
+       break;
+
+    case OBJID:
+       if ((oid = prim2oid(pe)) == NULLOID) {
+           goto bad;
+       } else {
+           VPRINT(("%s", oid2ode(oid)));
+       }
+       break;
+
+    default:
+       return (ppepsylose (mod, p, pe, "p_pr_etype: %d not implemented\n",
+           p->pe_type));
+    }
+
+    return (OK);
+
+bad:
+    return (NOTOK);
+}
+
+/*
+ * Is there a match at for this tag and class pair. Return 1 if yes 0
+ * if no We will search through contained objects and through choices
+ */
+p_ismatch(p, mod, cl, tag)
+ptpe   *p;
+modtyp *mod;                   /* Module it is from */
+unsigned int cl, tag;
+{
+    if (!ISDTYPE(p))
+       return (0);
+    switch (p->pe_type) {
+    case SOBJECT:
+    case OBJECT:
+       /* Needs to be changed for optional and default */
+       return (p_ismatch(p = mod->md_ptab[p->pe_tag] + 1, mod, cl, tag));
+
+    case SEXTOBJ:
+    case EXTOBJ:
+       if (p[1].pe_type != EXTMOD) {
+           (void) ppepsylose (mod, p, NULLPE, "p_ismatch: missing EXTMOD");
+           return (0); /* fixup ismatch return -1 */
+       }
+       return (p_ismatch(EXT2MOD(mod, (p + 1))->md_ptab[p->pe_tag] + 1,
+                         EXT2MOD(mod, (p + 1)), cl, tag));
+
+    case SCHOICE_START:
+    case CHOICE_START:
+       for (p++; p->pe_type != PE_END; p = NEXT_PTPE(p)) {
+           if (!ISDTYPE(p))
+               continue;
+           if (p_ismatch(p, mod, cl, tag))
+               return (1);
+       }
+       return (0);
+
+
+    case SANY:
+       return (1);
+
+    case ANY:
+       if (STAG(p) == -1)
+           return (1);
+       /* else fall through - not sure if this is needed */
+
+    default:
+       return (tag == TAG(p) && cl == CLASS(p));
+    }
+    /* NOTREACHED */
+    /* return (0); */
+}
+
+/*
+ * determine if the given field is present in the data This is simple
+ * if the field is a simple type with an obvious tag but in the case
+ * of an object or a CHOICE type the tag is not obvious. If the
+ * object is a CHOICE there are more than one possible tag that could
+ * match and in this case we must try to match each one of them.
+ */
+PE
+p_setpresent(head, p, mod)
+PE      head;
+ptpe   *p;
+modtyp *mod;
+{
+    PE      pe;
+    modtyp     *nmod;
+
+    while (!ISDTYPE(p) && p->pe_type != PE_END) {
+       p++;
+    }
+    if (!ISDTYPE(p) || p->pe_type == PE_END)
+       return (NULLPE);
+
+    switch (p->pe_type) {
+    case EXTOBJ:
+    case SEXTOBJ:
+       /* Needs to be changed for optional and default */
+       nmod = EXT2MOD(mod, (p + 1));
+       return (p_setpresent(head, p = nmod->md_ptab[p->pe_tag] + 1, nmod));
+
+    case OBJECT:
+    case SOBJECT:
+       {
+           /* Needs to be changed for optional and default */
+           return (p_setpresent(head, p = mod->md_ptab[p->pe_tag] + 1, mod));
+       }
+
+    case SCHOICE_START:
+    case CHOICE_START:
+       for (p++; p->pe_type != PE_END; p = NEXT_PTPE(p)) {
+           if (!ISDTYPE(p))
+               continue;
+           if ((pe = (PE) p_setpresent(head, p, mod)))
+               return (pe);
+       }
+       return (NULLPE);
+
+    default:
+       return (set_find(head, CLASS(p), TAG(p)));
+    }
+}
+
+#ifdef PRINT_DEFAULTS
+/*
+ * set the default value to that value in the structure
+ */
+setpval(typ, dflt, mod)
+ptpe   *typ, *dflt;
+modtyp *mod;
+{
+    int     len, i;
+    integer intval;
+    char   *ptr, *optr;
+    PE      pe_ptr;
+
+    switch (typ->pe_type) {
+
+    case INTEGER:
+       intval = IVAL(mod, dflt);
+       (*vfnx) (vfp, "%d (DEFAULT INTEGER)\n", intval);
+       break;
+
+
+#ifdef PEPSY_REALS
+    case REALTYPE:
+       (*vfnx) (vfp, "%f (DEFAULT Real)\n", RVAL(mod, dflt));
+       break;
+#endif
+
+    case BOOLEAN:
+       intval = IVAL(mod, dflt);
+       /*
+        * (*vfnx) (vfp, "%s  %d (DEFAULT BOOLEAN)\n",
+        * (typ->pe_typename) ? typ->pe_typename : "", charval);
+        */
+       (*vfnx) (vfp, "%d (DEFAULT BOOLEAN)\n", intval);
+       break;
+
+    case T_NULL:
+       /* Only one value */
+       break;
+
+    case SBITSTRING:
+    case BITSTRING:
+       (PE) pe_ptr = strb2bitstr(PVAL(mod, dflt), IVAL(mod, dflt), 0, 0);
+       (*vfnx) (vfp, " '");
+       optr = ptr = bitstr2strb((PE) pe_ptr, &len);
+       for (i = 0; i < len; i += 8)
+           (*vfnx) (vfp, "%.2x", *ptr++);
+       (*vfnx) (vfp, "'H (DEFAULT BITSTRING)\n");
+       pe_free (pe_ptr);
+       free (optr);
+       break;
+
+    case SOCTETSTRING:
+    case OCTETSTRING:
+        ptr = PVAL(mod, dflt); /* array of octets */
+        intval = IVAL(mod, dflt);              /* length of array */
+       if (printable(ptr, intval)) {
+           (*vfnx) (vfp, "\"");
+           for (; *ptr && intval-- > 0; ptr++)
+                (void) fputc(*ptr, vfp);
+           (*vfnx) (vfp, "\"\n");
+       } else {
+           (*vfnx) (vfp, "'");
+           if (ptr) {
+               for (; intval-- > 0; ptr++)
+                   (*vfnx) (vfp, "%.2x", *ptr & 0xff);
+           }
+           (*vfnx) (vfp, "'H \n");
+       }
+       break;
+
+    case OBJECT:
+       setpval(mod->md_ptab[typ->pe_tag] + 1, dflt, mod);
+       break;
+
+    case SOBJECT:
+       setpval(mod->md_ptab[typ->pe_tag] + 1, dflt, mod);
+       break;
+
+    case IMP_OBJ:
+       typ++;
+
+    case ANY:
+    case SANY:
+    case SEXTOBJ:
+    case EXTOBJ:
+    case OBJID:
+    case SOBJID:
+    case SEQ_START:
+    case SET_START:
+    case -1:                   /* Just use the pepy method of null
+                                * pointers */
+       /*
+        * This is the posy/pepy hack way of doing things at the
+        * moment
+        */
+       (char *) ptr = NULL;
+       break;
+
+    default:
+       return (ppepsylose (mod, p, pe, "setpval: type %d not implemented\n",
+           typ->pe_type));
+       break;
+    }
+
+}
+#endif
+/*
+ * return non zero if we can print out the string
+ */
+printable(strptr, len)
+char   *strptr;
+int    len;
+{
+    if (strptr == NULL || *strptr == '\0') {
+       return (0);
+    }
+
+     while (len-- > 0) {
+       if (!isprint(*strptr++))
+           return (0);
+    }
+
+    return (1);
+}
+
+/*
+ * (Dump) Print out a printable entry in a human recognisable form
+ */
+dmp_ptpe(s, p, mod)
+char   *s;
+modtyp *mod;                   /* Module it is from */
+ptpe   *p;
+{
+    int     i, j;
+    ptpe  **par, **prev;
+    char   *name;
+
+    (void) fprintf(vfp, "%s:(%s)", s, mod->md_name);
+    /*
+     * Calculate what table it is in - we assume they are in order of
+     * increasing address
+     */
+
+    par = NULL;
+    if (mod->md_ptab != NULL && mod->md_ptab[0] < p) {
+       par = mod->md_ptab;
+       name = "Printing:";
+    }
+    if (par == NULL) {
+       (void) fprintf(vfp, "can't find entry 0x%x\n", p);
+       return;
+    }
+    prev = par;
+    for (i = mod->md_nentries; i > 0; i--) {
+       if (*par > p)
+           break;
+       par++;
+    }
+    if (par == prev) {
+       (void) ppepsylose (mod, p, NULLPE,
+           "dmp_ptpe:par == prev == 0x%x internal error\n", (int) par);
+       return;
+    }
+    par--;
+    j = p - *par;
+
+    (void) fprintf(vfp, "%s type %d + %d ", name, par - prev, j);
+    p_pr_entry(p);
+}
diff --git a/src/isode/pepsy/ptabs.c b/src/isode/pepsy/ptabs.c
new file mode 100644 (file)
index 0000000..81dad23
--- /dev/null
@@ -0,0 +1,1144 @@
+/* ptabs.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:32  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:26  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:14  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "pepsydefs.h"
+#include "pass2.h"
+#include "mine.h"
+
+extern char *c_tag(), *c_class();
+extern char *ec_tag(), *ec_class(), *pec_class();
+extern char *strip_last();
+extern char *str_yp_code[];
+extern char *get_val(), *get_comp(), *strp2name();
+extern s_table *lookup_list(), *get_offset();
+extern YP tprnt_loop();
+extern int     gen_pentry();
+
+extern char *concat();
+extern char *my_strcat();
+extern char    *rm_indirect();
+extern char    *getfield();
+extern char    *setfield();
+extern char    *yp2name ();
+extern char    *code2name ();
+extern char    *modsym ();
+
+/*
+extern int explicit;
+*/
+
+extern char *tab;
+static int cons_type = 0;
+
+s_table *ptr;
+s_table *save_ptr;
+
+#define WORDSIZE       20
+
+/*
+ * Marshall's three extra conditions for changing the printing output
+ */
+static int     mrose1; /* if NamedType */
+static int     mrose2; /* !mrose1 && -h && DefinedType */
+static int     mrose3; /* (mrose1 || !mrose2) && TAG && (OPTIONAL|DEFAULT) */
+
+/*
+ * table printe a type. generate tables for the printing of a type
+ */
+tprnt_typ(fp, yp, id, type)
+FILE   *fp;
+YP      yp;
+char   *id;
+char   *type;
+{
+    char   *t, *f;
+    char   *p1;
+    YP      y;
+    int                flag;
+    int                ptr_tblidx = -1;
+
+    if (yp->yp_code < 0 || yp->yp_code > YP_REAL)
+       ferrd(1, "tdec_typ: unimplemented type %d\n", yp->yp_code);
+
+    if (yp == NULL) {
+       ferr(0, "tprnt_typ:NULL arguement\n");
+       return;
+    }
+
+    if (yp->yp_bef_alist && yp->yp_bef_alist->yal_prn)
+       gen_act(fp, yp->yp_bef_alist->yal_prn);
+
+    if (yp->yp_flags & YP_ID)
+       mrose1 = 1;
+    else
+       mrose1 = 0;
+
+    if (!mrose1 && hflag && yp->yp_code == YP_IDEFINED)
+       mrose2 = 1;
+    else
+       mrose2 = 0;
+
+    if ((mrose1 || !mrose2) && yp->yp_flags & YP_TAG
+       && yp->yp_flags & (YP_OPTIONAL|YP_DEFAULT))
+        mrose3 = 1;
+    else
+       mrose3 = 0;
+
+    if (type)
+       t = type;
+    else if (yp->yp_param_type) {
+       char *t1;
+       /* we have a [[ P type ]] specification */
+       if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+           fprintf(stderr,
+           "\ntenc_typ:SETLIST can't extract direct type from %s\n",
+               yp->yp_param_type);
+           exit(1);
+       }
+       t = strdup(t1);
+    } else
+       t = my_strcat("struct ", modsym(mymodule, id, "type"));
+
+    if ((yp->yp_flags & YP_PARMVAL) && yp->yp_parm) {
+       if ((f = getfield(yp->yp_parm)) == NULLCP) {
+           fprintf(stderr, "\ntprnt_typ:can't extract field from %s\n",
+               yp->yp_parm);
+           exit(1);
+       }
+       f = strdup(f);
+    } else
+       f = yp->yp_varexp;
+
+    if ((yp->yp_flags & (YP_OPTIONAL|YP_OPTCONTROL|YP_DEFAULT))
+       == (YP_OPTIONAL|YP_OPTCONTROL)) {
+       yp->yp_flags &= ~YP_OPTCONTROL;
+       flag = 1;
+    } else
+       flag = 0;
+
+    if (yp->yp_flags & YP_TAG && !(yp->yp_flags & YP_IMPLICIT)) {
+       prte_enoff(fp, "ETAG", yp, ptr_tblidx);
+    }
+
+    if (yp->yp_yfn && yp->yp_yfn->yfn_prt) {
+       gen_fn(fp, yp, yp->yp_yfn->yfn_prt);
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+
+       if (yp->yp_aft_alist && yp->yp_aft_alist->yal_prn)
+           gen_act(fp, yp->yp_aft_alist->yal_prn);
+
+       return;
+    }
+
+    switch (yp->yp_code) {
+
+    case YP_UNDF:
+       ferr(1, "tprnt_typ:Undefined type\n");
+
+    case YP_BOOL:
+       if (yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tdec_typ:BOOL: must specify a field [[ b .. ]]\n");
+       p1 = "BOOLEAN";
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f)))
+           break;
+       ferr(1, "tdec_typ:BOOL: can't find a type for boolean\n");
+
+       /* This needs to be fixed up in the action generating area */
+    case YP_INTLIST:
+
+    case YP_INT:
+
+    case YP_ENUMLIST:
+       if (yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tdec_typ:INT: must specify a field [[ i .. ]]\n");
+       p1 = "INTEGER";
+       if (yp->yp_varexp || (yp->yp_intexp && !noindirect(f)))
+           break;
+       ferr(1, "tdec_typ:INT: couldn't determine type\n");
+
+    case YP_REAL:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (noindirect(f))
+           ferr(1, "tdec_typ:REAL: must specify a field [[ r .. ]]\n");
+       p1 = "REALTYPE";
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f)))
+           break;
+       ferr(1, "tdec_typ:INT: couldn't determine type\n");
+
+
+    case YP_BITLIST:
+       ptr_tblidx = addptr (modsym(mymodule,
+                                   yp->yp_varexp ? yp -> yp_varexp : id,
+                                   "bits"));
+       /* fall */
+    case YP_BIT:
+       if (yp->yp_strexp && yp->yp_intexp) {
+           if (yp->yp_strexp)
+               f = setfield(yp->yp_strexp);
+           if (noindirect(f))
+               ferr(1, "tdec_typ:BIT: must specify a field [[ x .. ]]\n");
+           p1 = "BITSTR_PTR";
+           prte_off(fp, p1, yp, t, f, ptr_tblidx);
+           if (yp->yp_intexp)
+               f = setfield(yp->yp_intexp);
+           if (noindirect(f))
+               ferr(1, "tdec_typ:BIT: must specify a field [[ x .. ]]\n");
+           p1 = "BITSTR_LEN";
+           break;
+       }
+       if (yp->yp_strexp == NULLCP && yp->yp_intexp)
+           f = setfield(yp->yp_intexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "BITSTRING";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       (void) fprintf(fp, "\t{ SBITSTRING, %d, %s, %s, NULLVP },\n",
+                      ptr_tblidx, c_tag(yp), c_class(yp));
+       break;
+
+    case YP_OCT:
+       if (yp->yp_strexp) {
+           switch (yp->yp_prfexp) {
+           case 'q': /* [[ q parm->qbufptr ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   p1 = "SOCTETSTRING";
+               else
+                   p1 = "OCTETSTRING";
+               break;
+
+           case 's': /* [[ s ptr ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   ferr(1, "tdec_typ:OCT: must specify a field [[ s .. ]]\n");
+               p1 = "T_STRING";
+               break;
+               
+           case 'o': /* [[ o ptr $ length ]] */
+               if (yp->yp_strexp)
+                   f = setfield(yp->yp_strexp);
+               if (noindirect(f))
+                   ferr(1, "tdec_typ:OCT: must specify a field [[ o .. ]]\n");
+               p1 = "OCTET_PTR";
+               prte_off(fp, p1, yp, t, f, ptr_tblidx);
+               if (yp->yp_intexp)
+                   f = setfield(yp->yp_intexp);
+               if (noindirect(f))
+                   ferr(1, "tdec_typ:OCT: must specify a field [[ o .. ]]\n");
+               p1 = "OCTET_LEN";
+               break;
+
+           default:
+              fprintf(stderr,"\ntprnt_typ:Unknown Octet string specifier %c\n",
+                  yp->yp_prfexp);
+               exit(1);
+           }
+           break;
+       }
+
+       if (f && !noindirect(f)) {
+           p1 = "OCTETSTRING";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       prte_noff(fp, "SOCTETSTRING", yp, ptr_tblidx);
+       break;
+
+    case YP_OID:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "OBJID";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       prte_noff(fp, "SOBJID", yp, ptr_tblidx);
+       break;
+
+    case YP_SEQ:
+    case YP_SET:
+    case YP_ANY:
+       if (yp->yp_strexp)
+           f = setfield(yp->yp_strexp);
+       if (yp->yp_varexp || (yp->yp_strexp && !noindirect(f))) {
+           p1 = "ANY";
+           break;
+       }
+       t = NULL;
+       p1 = NULL;
+       prte_noff(fp, "SANY", yp, ptr_tblidx);
+       break;
+
+    case YP_NULL:
+       p1 = "T_NULL";
+       t = NULL;
+       break;
+
+    case YP_IDEFINED:
+       p1 = NULL;
+
+       if ((yp->yp_flags & YP_PARMVAL) && yp->yp_prfexp)
+               ferr(1,
+    "\n[[ ? reference ]] [[ p reference ]] is illegal\n\t only one allowed\n");
+
+       if (yp->yp_prfexp) { /* [[ ? parm->field ]] - complex to process */
+           gen_identry(fp, t, f, yp, gen_pentry);
+
+           if (yp->yp_flags & YP_DEFAULT)
+               gdflt(fp, yp, G_DEC);
+
+           break;
+       }
+
+       pr_deftyp(fp, yp, t, f);
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       break;
+
+    case YP_SEQLIST:
+       p1 = NULL;
+       /* support for -h flag */
+       cons_type++;
+       save_ptr = ptr;
+       if (yp->yp_varexp == NULL && type != NULL)
+           ferr(1, "tprnt_typ:YP_SEQLIST:NULL varexp pointer\n");
+       if (type == NULL)
+           prte_noff(fp, "SSEQ_START", yp, ptr_tblidx);
+       else if (noindirect(f))
+           prte_noff(fp, "SSEQ_START", yp, ptr_tblidx);
+       else
+           prte_off(fp, "SEQ_START", yp, t, f, ptr_tblidx);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntprnt_typ:SEQLIST can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tprnt_typ:YP_SEQLIST:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+#ifdef DO_OFFSETS
+           if (optfield(y)) {
+               (void) fprintf(fp,
+               "\t{ OPTL, OFFSET(%s, optionals), 0, 0, NULLVP },\n",
+                                   yp->yp_structname);
+           }
+#endif
+           tprnt_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0, NULLVP },\n");
+       ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_SETLIST:
+       p1 = NULL;
+       /* support for -h flag */
+       cons_type++;
+       if (yp->yp_varexp == NULL && type != NULL)
+           ferr(1, "tprnt_typ:YP_SETLIST:NULL varexp pointer\n");
+       if (type == NULL)
+           prte_noff(fp, "SSET_START", yp, ptr_tblidx);
+       else if (noindirect(f))
+           prte_noff(fp, "SSET_START", yp, ptr_tblidx);
+       else
+           prte_off(fp, "SET_START", yp, t, f, ptr_tblidx);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           ddflt(fp, yp);
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntprnt_typ:SETLIST can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tprnt_typ:YP_SETLIST:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+#ifdef DO_OFFSETS
+           if (optfield(y)) {
+               (void) fprintf(fp,
+                   "\t{ OPTL, OFFSET(%s, optionals), 0, 0, NULLVP },\n",
+                                       yp->yp_structname);
+           }
+#endif
+           tprnt_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0, NULLVP },\n");
+       ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_SEQTYPE:           /* What is the difference ?? */
+       p1 = NULL;
+       cons_type++;
+       save_ptr = ptr;
+       if (type == NULL)
+           prte_noff(fp, "SSEQOF_START", yp, ptr_tblidx);
+       else if (noindirect(f))
+           prte_noff(fp, "SSEQOF_START", yp, ptr_tblidx);
+       else
+           prte_off(fp, "SEQOF_START", yp, t, f, ptr_tblidx);
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntprnt_typ:SEQTYPE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tprnt_typ:YP_SEQTYPE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           tprnt_loop(fp, y, id, yp->yp_structname);
+       }
+#ifdef DO_OFFSETS
+       if (yp->yp_flags & YP_CONTROLLED) {
+           char *f1;
+
+           if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+               fprintf(stderr, "\ntprnt_typ:SEQ OF: can't extract field from %s\n",
+                   yp->yp_control);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
+                   yp->yp_structname, f1);
+       } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp,
+               "\t{ PE_END, OFFSET(%s, next), 0, 0, NULLVP },\n",
+                   yp->yp_structname);
+       else
+#endif
+           (void) fprintf(fp, "\t{ PE_END, 0, 0, 0, NULLVP },\n");
+       ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_SETTYPE:
+       p1 = NULL;
+       cons_type++;
+       save_ptr = ptr;
+       if (type == NULL)
+           prte_noff(fp, "SSETOF_START", yp, ptr_tblidx);
+       else if (noindirect(f))
+           prte_noff(fp, "SSETOF_START", yp, ptr_tblidx);
+       else
+           prte_off(fp, "SETOF_START", yp, t, f, ptr_tblidx);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+
+       if (y = yp->yp_type) {
+           char *t1;
+
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                   "\ntprnt_typ:SETTYPE can't extract direct type from %s\n",
+                       yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tprnt_typ:YP_SETTYPE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           tprnt_loop(fp, y, id, yp->yp_structname);
+       }
+       if (yp->yp_flags & YP_CONTROLLED) {
+           char *f1;
+
+           if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+               fprintf(stderr, "\ntprnt_typ:SET OF: can't extract field from %s\n",
+                   yp->yp_control);
+               exit(1);
+           }
+           (void) fprintf(fp, "\t{ PE_END, OFFSET(%s, %s), 0, 0 },\n",
+                   yp->yp_structname, f1);
+       } else if (yp->yp_structname != NULL)
+           (void) fprintf(fp,
+               "\t{ PE_END, OFFSET(%s, next), 0, 0, NULLVP },\n",
+                   yp->yp_structname);
+       else
+           (void) fprintf(fp, "\t{ PE_END, 0, 0, 0, NULLVP },\n");
+       ptr = save_ptr;
+       cons_type--;
+       break;
+
+    case YP_CHOICE:
+       p1 = NULL;
+       /* support for -h flag */
+       if (hflag && (y = yp->yp_type) && !y->yp_next) {
+           tprnt_typ(fp, y, id, yp->yp_structname);
+           break;
+       }
+       cons_type++;
+       save_ptr = ptr;
+       /* Generates an unused tags field - so beware */
+       if (type == NULL)
+           prte_noff(fp, "SCHOICE_START", yp, ptr_tblidx);
+       else if (noindirect(f))
+           prte_noff(fp, "SCHOICE_START", yp, ptr_tblidx);
+       else
+           prte_off(fp, "CHOICE_START", yp, t, f, ptr_tblidx);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+       if (y = yp->yp_type) {
+           char *t1;
+#ifdef DO_OFFSETS
+           char *f1;
+
+           if (yp->yp_flags & YP_CONTROLLED) {
+
+               if ((f1 = getfield(yp->yp_control)) == NULLCP) {
+                   fprintf(stderr,
+                           "\ntprnt_typ:CHOICE: can't extract field from %s\n",
+                           yp->yp_control);
+                   exit(1);
+               }
+
+           } else
+               f1 = "offset";
+
+           if ((yp->yp_flags & YP_ID) && yp->yp_id)
+               (void) fprintf(fp,
+                              "\t{ SCTRL, OFFSET(%s, %s), 0, 0, (char **)&%s%s%s[%d] },\n",
+                              yp->yp_structname, f1, PREFIX, PTR_TABNAME, tab,
+                              addsptr(yp->yp_id));
+           else
+               (void) fprintf(fp,
+                              "\t{ SCTRL, OFFSET(%s, %s), 0, 0, NULLVP },\n",
+                              yp->yp_structname, f1);
+#else
+           if ((yp->yp_flags & YP_ID) && yp->yp_id)
+               (void) fprintf(fp,"\t{ SCTRL, 0, 0, 0, (char **)&%s%s%s[%d] },\n",
+                              PREFIX, PTR_TABNAME, tab, addsptr(yp->yp_id));
+           else
+               (void) fprintf(fp, "\t{ SCTRL, 0, 0, 0, NULLVP },\n");
+
+#endif
+           if (yp->yp_param_type) {
+               /* we have a [[ P type ]] specification */
+               if ((t1 = rm_indirect(yp->yp_param_type)) == NULLCP) {
+                   fprintf(stderr,
+                           "\ntprnt_typ:CHOICE can't extract direct type from %s\n",
+                           yp->yp_param_type);
+                   exit(1);
+               }
+               yp->yp_structname = strdup(t1);
+           } else if (type) {
+               if (yp->yp_declexp == NULL)
+                   ferr(1, "tprnt_typ:YP_CHOICE:no declexp\n");
+               yp->yp_structname = my_strcat("struct ", yp->yp_declexp);
+           } else
+               yp->yp_structname = t;
+           tprnt_loop(fp, y, id, yp->yp_structname);
+       }
+       (void) fprintf(fp, "\t{ PE_END, 0, 0, 0, NULLVP },\n");
+       ptr = save_ptr;
+       cons_type--;
+       break;
+
+    default:
+       ferrd(1, "tprnt_typ: yp_code = %d  not implemented\n", yp->yp_code);
+    }
+
+    if (p1 != NULL) {
+       if (t != NULL)
+           prte_off(fp, p1, yp, t, f, ptr_tblidx);
+       else
+           prte_noff(fp, p1, yp, ptr_tblidx);
+
+       if (yp->yp_flags & YP_DEFAULT)
+           gdflt(fp, yp, G_DEC);
+    }
+
+    if (flag)
+       yp->yp_flags |= YP_OPTCONTROL;
+
+    if (yp->yp_aft_alist && yp->yp_aft_alist->yal_prn)
+       gen_act(fp, yp->yp_aft_alist->yal_prn);
+
+}
+
+/*
+ * generate tables for printing a contructed type
+ */
+YP 
+tprnt_loop(fp, yp, id, type)
+FILE   *fp;
+YP      yp;
+char   *id;
+char   *type;
+{
+    for (; yp != NULL; yp = yp->yp_next) {
+       tprnt_typ(fp, yp, id, type);
+    }
+}
+
+
+ddflt(fp, yp)
+FILE   *fp;
+YP      yp;
+{
+    switch (yp->yp_code) {
+    case YP_BOOL:
+    case YP_INT:
+    case YP_INTLIST:
+       (void) fprintf(fp, "\t{DFLT_B,      %d,     0,      0 },\n",
+               yp->yp_default->yv_number);
+       break;
+    case YP_BIT:
+    case YP_BITLIST:
+    case YP_OCT:
+    case YP_NULL:
+    case YP_SEQ:
+    case YP_SEQTYPE:
+    case YP_SEQLIST:
+    case YP_SET:
+    case YP_SETTYPE:
+    case YP_SETLIST:
+    case YP_CHOICE:
+    case YP_ANY:
+    case YP_OID:
+    case YP_IDEFINED:
+    case YP_ENUMLIST:
+    case YP_REAL:
+       (void) fprintf(fp, "\t{DFLT_B,      0,      0,      0 },\n");
+       break;
+
+    default:
+       ferrd(1, "ddflt:unknown type %d\n", yp->yp_code);
+    }
+
+}
+
+/*
+ * print a Non offset table entry
+ */
+prte_noff(fp, type, yp, idx)
+FILE   *fp;
+char   *type;
+YP     yp;
+int    idx;
+{
+    char       *tag;
+    char       *flags;
+    char       *typename;
+    char       buf1[BUFSIZ];
+
+    tag = c_tag(yp);
+    flags = c_class(yp);
+    if (mrose3) {              /* need to append FL_PRTAG flag */
+       (void) strncpy(buf1, flags, BUFSIZ);
+       (void) strncat(buf1, "|FL_PRTAG", BUFSIZ);
+       flags = buf1;
+    }
+    if (mrose1)
+       typename = yp->yp_id;
+    else if (mrose2)
+       typename = yp->yp_identifier;
+    else
+       typename = (char *)0;
+    if (typename) {
+       int pindex = addsptr (typename);
+       (void) fprintf(fp, "\t{ %s, %d, %s, %s, (char **)&%s%s%s[%d] },\n",
+                      type, idx, tag, flags,
+                      PREFIX, PTR_TABNAME, tab, pindex);
+    }
+    else
+       (void) fprintf(fp, "\t{ %s, %d, %s, %s, NULLVP },\n",
+                      type,idx, tag, flags);
+}
+
+/*
+ * print a Non offset table entry for an ETAG - special case
+ */
+prte_enoff(fp, type, yp, idx)
+FILE   *fp;
+char   *type;
+YP     yp;
+int    idx;
+{
+    char       *tag;
+    char       *flags;
+    char       *typename;
+    char       buf1[BUFSIZ];
+
+    tag = ec_tag(yp);
+    flags = ec_class(yp);
+    if (mrose3) {              /* need to append FL_PRTAG flag */
+       (void) strncpy(buf1, flags, BUFSIZ);
+       (void) strncat(buf1, "|FL_PRTAG", BUFSIZ);
+       flags = buf1;
+       mrose3 = 0;     /* don't want the next tag */
+    }
+    if (mrose1) {
+       typename = yp->yp_id;
+       mrose1 = 0;
+    } else if (mrose2) {
+       typename = yp->yp_identifier;
+       mrose2 = 0;
+    } else
+       typename = NULL;
+    if (typename){
+       int pindex = addsptr (typename);
+       (void) fprintf(fp, "\t{ %s, %d, %s, %s, (char **)&%s%s%s[%d] },\n",
+                      type, idx, tag, flags,
+                      PREFIX, PTR_TABNAME, tab, pindex);
+    }
+    else
+       (void) fprintf(fp, "\t{ %s, %d, %s, %s, NULLVP },\n",
+                                   type, idx, tag, flags);
+}
+
+/*
+ * print an offset table entry
+ */
+/* ARGSUSED */
+prte_off(fp, type, yp, t, f, idx)
+FILE   *fp;
+char   *type;
+YP     yp;
+char   *t, *f;
+int    idx;
+{
+    char       *tag;
+    char       *flags;
+    char       *typename;
+    char       buf1[BUFSIZ];
+
+    tag = c_tag(yp);
+    flags = c_class(yp);
+    if (mrose3) {              /* need to append FL_PRTAG flag */
+       (void) strncpy(buf1, flags, BUFSIZ);
+       (void) strncat(buf1, "|FL_PRTAG", BUFSIZ);
+       flags = buf1;
+    }
+    if (mrose1)
+       typename = yp->yp_id;
+    else if (mrose2)
+       typename = yp->yp_identifier;
+    else
+       typename = (char *)0;
+#ifdef DO_OFFSETS
+    if (typename) {
+       int pindex = addsptr (typename);
+       (void) fprintf(fp, "\t{ %s, OFFSET(%s, %s), %s, %s, (char **)&%s%s%s[%d] },\n",
+                      type, t, f, tag, flags,
+                      PREFIX, PTR_TABNAME, tab, pindex);
+    }
+    else
+       (void) fprintf(fp, "\t{ %s, OFFSET(%s, %s), %s, %s, NULLVP },\n",
+                                   type, t, f, tag, flags);
+#else
+    if (typename){
+       int pindex = addsptr (typename);
+       (void) fprintf(fp, "\t{ %s, %d, %s, %s, (char **)&%s%s%s[%d] },\n",
+                      type, idx, tag, flags,
+                      PREFIX, PTR_TABNAME, tab, pindex);
+    }
+    else
+       (void) fprintf(fp, "\t{ %s, %d, %s, %s, NULLVP },\n",
+                      type, idx, tag, flags);
+#endif
+}
+
+/*
+ * handle the very complex task of defined types.
+ * Basically generating object calls
+ */
+pr_deftyp(fp, yp, t, f)
+FILE   *fp;
+YP     yp;
+char   *t;
+char   *f;
+{
+    /* Predefined Universal Type */
+    struct univ_typ *p, *univtyp();
+
+    if ((p = univtyp(yp->yp_identifier))) {
+       if (p->univ_flags & UNF_EXTMOD) {
+           yp->yp_module = p->univ_mod;
+           goto do_obj;
+       }
+       prte_univt(fp, p, yp, t, f);
+       return;
+    }
+
+do_obj:
+    if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT)
+       prte_noff(fp, "IMP_OBJ", yp, -1);
+       prte_obj(fp, yp, t, f);
+}
+
+/*
+ * print an offset table entry for an OBJECT type entry
+ */
+/* ARGSUSED */
+prte_obj(fp, yp, t, f)
+FILE   *fp;
+YP     yp;
+char   *t, *f;
+{
+    char       *type;
+    char       *obj;
+    char       *flags;
+    char       *typename;
+    char       *off;
+    char       buf1[BUFSIZ];
+#ifdef DO_OFFSETS
+    char       buf2[BUFSIZ];
+#endif
+    int                extflag;
+
+    if (yp->yp_module == NULL || strcmp(yp->yp_module, mymodule) == 0) {
+       if (f && !noindirect(f))
+           type = "OBJECT";
+       else
+           type = "SOBJECT";
+       obj = proc_name(yp->yp_identifier, 0);
+       extflag = 0;
+    } else {
+       if (f && !noindirect(f))
+           type = "EXTOBJ";
+       else
+           type = "SEXTOBJ";
+       obj = strp2name(yp->yp_identifier, yp->yp_module);
+       extflag = 1;
+    }
+    flags = c_class(yp);
+    if (mrose3) {              /* need to append FL_PRTAG flag */
+       (void) strncpy(buf1, flags, BUFSIZ);
+       (void) strncat(buf1, "|FL_PRTAG", BUFSIZ);
+       flags = buf1;
+    }
+    if (mrose1)
+       typename = yp->yp_id;
+    else if (mrose2)
+       typename = yp->yp_identifier;
+    else
+       typename = (char *)0;
+#ifdef DO_OFFSETS
+    if (f && !noindirect(f)) {
+       (void) sprintf(buf2, "OFFSET(%s, %s)", t, f);
+       off = buf2;
+    } else if (f && *f == '&') {
+       (void) sprintf(buf2, "OFFSET(%s, %s)", t, f + 1);
+       off = buf2;
+    } else
+#endif
+        off = "0";
+    if (typename){
+       int pindex = addsptr (typename);
+       (void) fprintf(fp, "\t{ %s, %s, _Z%s, %s, (char **)&%s%s%s[%d] },\n",
+                      type, off, obj, flags,
+                      PREFIX, PTR_TABNAME, tab, pindex);
+    }
+    else
+       (void) fprintf(fp, "\t{ %s, %s, _Z%s, %s, NULLVP },\n",
+                                   type, off, obj, flags);
+    if (extflag)
+       (void) fprintf(fp, "\t{ EXTMOD, %d, 0, 0, NULLVP },\n",
+               gen_modref(yp->yp_module));
+}
+
+/*
+ * print an table entry for Universal type with the given entry
+ */
+/* ARGSUSED */
+prte_univt(fp, p, yp, t, f)
+FILE   *fp;
+struct univ_typ *p;
+YP     yp;
+char   *t, *f;
+{
+    char       *type;
+    int                tag;
+    PElementClass class;
+    char       *flags;
+    char       *typename;
+    char       *off;
+    char       buf1[BUFSIZ];
+#ifdef DO_OFFSETS
+    char       buf2[BUFSIZ];
+#endif
+    char       buf3[BUFSIZ];
+
+    if (f == NULL || noindirect(f))  {
+       (void) sprintf(buf3, "S%s", p->univ_tab);
+       type = buf3;
+    } else
+       type = p->univ_tab;
+
+    if (yp->yp_flags & YP_TAG && yp->yp_flags & YP_IMPLICIT) {
+       tag = yp->yp_tag->yt_value->yv_number;
+       class = yp->yp_tag->yt_class;
+    } else {
+       tag = p->univ_id;
+       class = p->univ_class;
+    }
+    
+    (void) strncpy(buf1, c_flags(yp, class), BUFSIZ);
+    flags = buf1;
+    if (mrose3) {              /* need to append FL_PRTAG flag */
+       (void) strncat(buf1, "|FL_PRTAG", BUFSIZ);
+    }
+    if (mrose1)
+       typename = yp->yp_id;
+    else if (mrose2)
+       typename = yp->yp_identifier;
+    else
+       typename = (char *)0;
+#ifdef DO_OFFSETS
+    if (f && !noindirect(f)) {
+       (void) sprintf(buf2, "OFFSET(%s, %s)", t, f);
+       off = buf2;
+    } else if (f && *f == '&') {
+       (void) sprintf(buf2, "OFFSET(%s, %s)", t, f + 1);
+       off = buf2;
+    } else
+#endif
+        off = "0";
+    if (typename) {
+       int pindex = addsptr (typename);
+       (void) fprintf(fp, "\t{ %s, %s, %d, %s, (char **)&%s%s%s[%d] },\n",
+                      type, off, tag, flags,
+                      PREFIX, PTR_TABNAME, tab, pindex);
+    }
+    else
+       (void) fprintf(fp, "\t{ %s, %s, %d, %s, NULLVP },\n",
+                                   type, off, tag, flags);
+}
+
+/*
+ * generate the table entry for a value passing defined type which
+ * is equivalent to the given primative type
+ */
+gen_pentry(fp, oyp, yp, t, f)
+FILE   *fp;
+YP     oyp, yp;
+char   *t, *f;
+{
+    char       *p1;
+    register char      s = oyp->yp_prfexp;     /* type of value passing */
+    int                idx;
+
+
+    if (noindirect(f) && s != 'q' && s != 'a')
+       ferrs(1,
+        "gen_ventry: must specify a field for primative value- not %s\n", f);
+
+#if 0
+/* can't get id from in here - yet */
+    if (yp->yp_code == YP_BITLIST) {
+       idx = addptr (modsym(mymodule, yp->yp_varexp ? yp -> yp_varexp : id,
+                                    "bits"));
+    } else
+#endif
+        idx = -1;
+
+    switch (s) {
+    case 'q': /* [[ q parm->qbufptr ]] */
+       if (yp->yp_code != YP_OCT)
+           warning("qbuf pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+                
+       f = setfield(oyp->yp_strexp);
+       if (noindirect(f))
+           p1 = "SOCTETSTRING";
+       else
+           p1 = "OCTETSTRING";
+       break;
+
+    case 's': /* [[ s ptr ]] */
+       if (yp->yp_code != YP_OCT)
+           warning("string pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_strexp);
+       p1 = "T_STRING";
+       break;
+
+    case 'o': /* [[ o ptr $ length ]] */
+       if (yp->yp_code != YP_OCT)
+           warning("octet/length pair passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+       f = setfield(oyp->yp_strexp);
+       p1 = "OCTET_PTR";
+       prte_off(fp, p1, yp, t, f, idx);
+       if (oyp->yp_intexp)
+           f = setfield(oyp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "gen_ventry:OCT: must specify a field [[ s .. ]]\n");
+       p1 = "OCTET_LEN";
+       break;
+
+    case 'x': /* [[ x ptr $ length ]] */
+       if (yp->yp_code != YP_BIT && yp->yp_code != YP_BITLIST)
+           warning("bit string/length pair passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_strexp);
+       p1 = "BITSTR_PTR";
+       prte_off(fp, p1, yp, t, f, idx);
+       f = setfield(oyp->yp_intexp);
+       if (noindirect(f))
+           ferr(1, "tenc_typ:BIT: must specify a field [[ x .. ]]\n");
+       p1 = "BITSTR_LEN";
+       break;
+
+    case 'r': /* [[ r REAL ]] */
+       if (yp->yp_code != YP_REAL)
+           warning("Real passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_strexp);
+       p1 = "REALTYPE";
+       break;
+
+    case 'i': /* [[ i INTEGER ]] */
+       if (yp->yp_code != YP_INT && yp->yp_code != YP_INTLIST
+        && yp->yp_code != YP_ENUMLIST)
+           warning("integer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       if (oyp->yp_intexp)
+           f = setfield(oyp->yp_intexp);
+       p1 = "INTEGER";
+       break;
+
+    case 't': /* [[ t Bitvector ]] */
+       if (yp->yp_code != YP_BIT && yp->yp_code != YP_BITLIST)
+           warning("Bitvector (PE) passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       f = setfield(oyp->yp_intexp);
+       if (oyp->yp_varexp && !noindirect(f))
+           p1 = "BITSTRING";
+       else
+           p1 = "SBITSTRING";
+       break;
+
+    case 'b': /* [[ b BOOLEAN ]] */
+       if (yp->yp_code != YP_BOOL)
+           warning("Boolean passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+
+       if (oyp->yp_intexp)
+           f = setfield(oyp->yp_intexp);
+       p1 = "BOOLEAN";
+       break;
+
+    case 'O': /* [[ O Object Identifier ]] */
+       if (yp->yp_code != YP_OID)
+           warning("Object Identifier pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+       f = setfield(oyp->yp_strexp);
+       p1 = "OBJID";
+       break;
+
+    case 'a': /* [[ a ANY ]] */
+       if (yp->yp_code != YP_ANY)
+           warning("PE pointer passed for a %s by type %s",
+           code2name(yp->yp_code), yp2name(oyp));
+       f = setfield(oyp->yp_strexp);
+       if (noindirect(f))
+           p1 = "SANY";
+       else
+           p1 = "ANY";
+       break;
+     default:
+       ferrd(1, "gen_vident:unknown Value passed %d\n", (int )s);
+   }
+
+    prte_off(fp, p1, yp, t, f, idx);
+}
+
+int addsptr (s)
+char *s;
+{
+    char buf[BUFSIZ];
+
+    (void) sprintf (buf, "\"%s\"", s);
+    return addptr (buf);
+}
diff --git a/src/isode/pepsy/py_advise.c b/src/isode/pepsy/py_advise.c
new file mode 100644 (file)
index 0000000..f588ea5
--- /dev/null
@@ -0,0 +1,66 @@
+/* py_advise.c - standard "advise" routine for pepsy/pepy */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:34  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:28  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:15  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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>
+
+/* \f */
+
+#ifndef        lint
+char   PY_pepy[BUFSIZ];
+
+
+void   PY_advise (va_alist)
+va_dcl
+{
+    va_list    ap;
+
+    va_start (ap);
+
+    asprintf (PY_pepy, ap);
+
+    va_end (ap);
+}
+#else
+/* VARARGS */
+
+void   PY_advise (what, fmt)
+char   *what,
+       *fmt;
+{
+    PY_advise (what, fmt);
+}
+#endif
diff --git a/src/isode/pepsy/sym.h b/src/isode/pepsy/sym.h
new file mode 100644 (file)
index 0000000..232b6ba
--- /dev/null
@@ -0,0 +1,43 @@
+/* sym.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:30  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:16  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 symlist {
+    char   *sy_encpref;
+    char   *sy_decpref;
+    char   *sy_prfpref;
+    char   *sy_module;
+    char   *sy_name;
+
+    YP     sy_type;
+
+    struct symlist *sy_next;
+}              symlist, *SY;
+#define        NULLSY  ((SY) 0)
+
diff --git a/src/isode/pepsy/t1.py b/src/isode/pepsy/t1.py
new file mode 100644 (file)
index 0000000..0380e5e
--- /dev/null
@@ -0,0 +1,391 @@
+-- $Header$
+--
+--
+-- $Log$
+-- Revision 1.1  1994/06/10 03:31:38  eichin
+-- autoconfed isode for kerberos work
+--
+# Revision 1.1  1994/05/31 20:40:32  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+-- Revision 8.0  91/07/17  12:43:16  isode
+-- Release 7.0
+-- 
+--
+
+--
+--                               NOTICE
+--
+--    Acquisition, use, and distribution of this module and related
+--    materials are subject to the restrictions of a license agreement.
+--    Consult the Preface in the User's Manual for the full terms of
+--    this agreement.
+--
+--
+
+
+T1 { joint-iso-ccitt rubbish(999) modid(1) } DEFINITIONS ::=
+
+
+BEGIN
+
+IMPORTS
+       + Info,
+       + Sset,
+       + Sseq,
+       - Sany,
+       + Soid
+               FROM T2
+       Pepy-refs,
+       Single-type,
+       Repeated,
+       Defined,
+       CodeTest,
+       AllSimples,
+       UAction
+               FROM T3;
+
+-- Embedded Sequences test
+
+
+    -- Test of Embedded Strings
+Emb-Strings ::= SEQUENCE {
+       atest INTEGER,
+       btest OCTET STRING,
+       ctest BIT STRING,
+       big-test Strings,
+       emb-test SEQUENCE {
+           em-int INTEGER,
+           em-oct OCTET STRING,
+           em-bit BIT STRING
+       }
+    }
+
+
+Strings ::= SEQUENCE { -- Test Octet strings, bit strings and character
+                      -- Strings in general
+       ostring OCTET STRING,
+       bstring BIT STRING,
+       nstring NumericString,
+       pstring PrintableString,
+       tstring TeletexString,
+       t61string T61String,
+       vstring VideotexString,
+       vis-string VisibleString,
+       i646string ISO646String,
+       ia5string IA5String,
+       graphstring GraphicString,
+       genstring GeneralString
+       }
+
+Embedded ::= SEQUENCE {
+       anMPDU MPDU,
+       ei INTEGER
+       }
+
+MPDU ::=
+       SEQUENCE {
+           a-seq SEQUENCE {
+               fred [0] IMPLICIT INTEGER,
+
+                   george BOOLEAN
+           }
+       }
+
+ServiceMPDU ::=
+       SET {
+           a-set SET {
+                   a-data [1] IMPLICIT BIT STRING,
+
+               a-more-data [2] IMPLICIT INTEGER
+           },
+           b-set SET {
+                   b-data [1] IMPLICIT BIT STRING,
+
+               b-more-data [2] IMPLICIT INTEGER
+           }
+       }
+-- Implicit tags
+
+Impl-Tags ::= SEQUENCE {
+       i-impl [1] IMPLICIT INTEGER,
+       o-impl [2] IMPLICIT OCTET STRING,
+       b-impl [3] IMPLICIT BIT STRING,
+       f-impl [4] IMPLICIT BOOLEAN,
+       obj-impl [5] IMPLICIT Emb-Strings,
+
+    -- Test of Embedded Strings
+       i-emb-test [APPLICATION 88] IMPLICIT SEQUENCE {
+           i-em-int INTEGER,
+           i-em-oct OCTET STRING,
+           i-em-bit BIT STRING
+       }
+    }
+
+-- Explicit tags
+
+Expl-Tags ::= SEQUENCE {
+       i-expl [1] INTEGER,
+       o-expl [2] OCTET STRING,
+       b-expl [3] BIT STRING,
+       f-expl [4] BOOLEAN,
+       obj-expl [5] Emb-Strings,
+
+    -- Test of Embedded Strings
+       i-exp-test [APPLICATION 88] SEQUENCE {
+           i-ex-int INTEGER,
+           i-ex-oct OCTET STRING,
+           i-ex-bit BIT STRING
+       }
+    }
+
+  -- Test of Sequence of
+Seqof-Test ::= SEQUENCE {
+       sqof-test1 SEQUENCE OF Expl-Tags,
+       stof-test1 SET OF Expl-Tags,
+       i-test1 INTEGER,
+       sqof-test2 SEQUENCE OF SEQUENCE {
+           sqof-in Expl-Tags,
+           sqof-i INTEGER,
+           sqof-o OCTET STRING
+       },
+       stof-test2 SET OF SEQUENCE {
+           stof-in Expl-Tags,
+           stof-i INTEGER,
+           stof-o OCTET STRING
+       },
+       i-test2 INTEGER
+    }
+
+
+   -- Test data for the Choice type
+Choice-Test ::= SET {
+       c1 CHOICE {
+       i-c1 [1] IMPLICIT INTEGER,
+       o-c1 [2] IMPLICIT OCTET STRING,
+       b-c1 [3] IMPLICIT BIT STRING,
+       f-c1 [4] IMPLICIT BOOLEAN,
+       obj-c1 [5] IMPLICIT Emb-Strings
+       },
+       c2 CHOICE {
+       i-c2 [6] INTEGER,
+       o-c2 [7] OCTET STRING,
+       b-c2 [8] BIT STRING,
+       f-c2 [9] BOOLEAN,
+       obj-c2 [10] Emb-Strings
+       },
+       c3 CHOICE {
+           seq-c3 SEQUENCE {
+               seq-c3-in Expl-Tags,
+               seq-c3-i INTEGER,
+               seq-c3-o OCTET STRING
+           },
+           set-c3 SET {
+               set-c3-in Expl-Tags,
+               set-c3-i INTEGER,
+               set-c3-o OCTET STRING
+           },
+           i-c3 INTEGER
+       },
+       c4 [12] IMPLICIT SEQUENCE {
+           c4-choice CHOICE {
+               c4-i INTEGER,
+               c4-obj [2] IMPLICIT Expl-Tags,
+               c4-subch CHOICE {
+                   sc-a-i [0] IMPLICIT INTEGER,
+                   sc-b-i [1] IMPLICIT INTEGER
+               }
+           }
+       }
+
+
+    }
+
+  -- Test of Optional fields
+
+Opt-Strings ::= SEQUENCE {
+       a-opt INTEGER OPTIONAL,
+       b-opt OCTET STRING,
+       c-opt BIT STRING OPTIONAL,
+       d-opt BOOLEAN OPTIONAL,
+       e-opt NULL OPTIONAL,
+       big-opt Strings OPTIONAL,
+       emb-opt SEQUENCE {
+           oem-int INTEGER OPTIONAL,
+           oem-oct OCTET STRING OPTIONAL,
+           oem-bit BIT STRING OPTIONAL
+       }       OPTIONAL,
+       st-opt SET {
+           st-int0 [0] IMPLICIT INTEGER OPTIONAL,
+           st-int1 [1] IMPLICIT INTEGER OPTIONAL,
+           st-int2 [2] IMPLICIT INTEGER OPTIONAL
+       }       OPTIONAL,
+       obj-opt [APPLICATION 1] IMPLICIT  MPDU OPTIONAL,
+       etag-opt [APPLICATION 2] INTEGER OPTIONAL,
+       ch-opt CHOICE {
+           ch-1 [10] IMPLICIT INTEGER,
+           ch-2 [20] IMPLICIT INTEGER
+       } OPTIONAL
+    }
+
+  -- Test of Default fields
+
+Def-Strings ::= SEQUENCE {
+       a-def INTEGER  { a-def-0 (0), a-def-1(1) } DEFAULT a-def-0,
+       -- posy bug does not allow handling of 'xxx'b or 'xx'h notation
+       -- so we don't use proper posy notation
+       -- b-def OCTET STRING DEFAULT 'ff01ab20'h,
+       b-def PrintableString   DEFAULT "hello, world",
+       c-def BIT STRING  { c-def-one(3), c-def-two (1)}
+               DEFAULT { c-def-one },
+       okay BOOLEAN DEFAULT TRUE,
+       e-def NULL DEFAULT NULL,
+       big-def Strings,
+       emb-def SEQUENCE {
+           colour INTEGER { red(1), green(2), yellow(3) } DEFAULT green,
+           oem-oct OCTET STRING OPTIONAL,
+           version BIT STRING { basic(0), patch1(1), patch2(2) }
+               DEFAULT { basic }
+       }    DEFAULT { red, { basic } },
+       st-def SET {
+           wine [0] IMPLICIT INTEGER { claret(1), burgundy(2), moselle(3) }
+               DEFAULT claret,
+           beer [1] IMPLICIT INTEGER { vb(0), fosters(1), hieneken(2) }
+               DEFAULT vb,
+           spirit [2] IMPLICIT INTEGER { brandy(0), vodka(1), wisky(2) }
+               DEFAULT vodka
+       }       DEFAULT { vb, vodka }
+    }
+
+-- External References
+--
+E-ref  ::= SEQUENCE {
+    a-ref T2.Info,
+    b-ref [APPLICATION 33] IMPLICIT T2.Info,
+    c-ref [1] T1.Choice-Test,
+    d-ref [2] T2.Info OPTIONAL,
+    e-ref [APPLICATION 33] IMPLICIT T2.Info OPTIONAL
+    }
+
+
+-- Simple type optimisations of POSY/PEPY
+
+ Bstring ::= [APPLICATION 8] BIT STRING
+
+ Ostring ::= [31] IMPLICIT OCTET STRING
+
+ Obj ::= [101] IMPLICIT MPDU
+
+ Sset ::= SET
+
+ Sseq ::= SEQUENCE
+
+ Sany ::= ANY
+
+ Soid ::= OBJECT IDENTIFIER
+
+
+Optimised ::= SEQUENCE {
+    o1 Bstring,
+    o2 Ostring,
+    o3 Obj,
+    o4 [APPLICATION 3] IMPLICIT Sset OPTIONAL,
+    [APPLICATION 21] SET {
+       o5 [PRIVATE 9] IMPLICIT Sseq,
+       o6 [PRIVATE 33] IMPLICIT Sany,
+       o7 [PRIVATE 8] IMPLICIT Soid
+    }
+}
+
+-- Use of External Simple types
+Ext-Opt ::= SEQUENCE {
+    o1 T2.Bstring,
+    o2 T2.Ostring,
+    o3 T2.Obj,
+    o4 [PRIVATE 38] IMPLICIT T2.Sset OPTIONAL,
+    [APPLICATION 21] SET {
+       o5 [PRIVATE 1] IMPLICIT T2.Sseq,
+       o6 [PRIVATE 2] IMPLICIT T2.Sany,
+       o7 [PRIVATE 3] IMPLICIT T2.Soid
+    }
+}
+
+-- External type and ANY usage
+
+Ext-typ ::= SEQUENCE {
+     ext EXTERNAL,
+     a-ny      [APPLICATION 32] ANY,
+     ext-impl  [PRIVATE 6] IMPLICIT EXTERNAL,
+     any-impl  [APPLICATION 7] ANY,
+     ext-expl  [PRIVATE 9] EXTERNAL,
+     any-expl  [APPLICATION 10] ANY
+   }
+
+SExt ::= [PRIVATE 99] IMPLICIT EXTERNAL
+
+-- check of posy's %[ name $ head %] stuff
+Names ::=
+       SEQUENCE {
+           SEQUENCE %[ seq_str $ ptr %] {
+               fred [0] IMPLICIT INTEGER
+           }
+       }
+
+-- Test explicit tags as the first field of an object
+Etags ::=
+       [APPLICATION 3]
+          CHOICE {
+               aE [0] IMPLICIT INTEGER,
+               bE [1] IMPLICIT INTEGER
+           }
+
+Stest ::=
+    [APPLICATION 4] SET {
+           st1 Sint DEFAULT 33,
+           st2 Soctet DEFAULT "goodbye, world"
+       }
+
+Sint ::= INTEGER
+
+Soctet ::= OCTET STRING
+
+Simpl-test ::= SEQUENCE { si-t [23] IMPLICIT Sbstring }
+
+Sbstring ::= BIT STRING { bit0(0), bit1(1), bit2(2) }
+
+SStest ::= [101] IMPLICIT Simpl-test
+
+Enum-type ::= ENUMERATED { pork(0), beef(1), chicken(3), lamb(-1) }
+
+T-enum ::= SEQUENCE {
+               ae1 Enum-type,
+               ae2 [12] Enum-type,
+               ae3 [13] IMPLICIT Enum-type,
+               ae4 [15] IMPLICIT Enum-type DEFAULT chicken,
+               ae5 Enum-type OPTIONAL
+           }
+Real ::= REAL
+
+T-real ::= SEQUENCE {
+               r1 Real,
+               r2 [99] Real,
+               r3 [101] IMPLICIT Real,
+               r4 [501] IMPLICIT Real DEFAULT { 31415962, 10, -7 },
+               r5 Real OPTIONAL
+           }
+
+T-pepy ::= T3.Pepy-refs
+
+T3-Single ::= T3.Single-type
+
+T3-Repeat ::= T3.Repeated
+
+T3-Defined ::= T3.Defined
+
+T3-CodeTest ::= T3.CodeTest
+
+T3-AllSimples ::= T3.AllSimples
+
+T3-UAction ::= T3.UAction
+
+END
diff --git a/src/isode/pepsy/t2.py b/src/isode/pepsy/t2.py
new file mode 100644 (file)
index 0000000..0e53938
--- /dev/null
@@ -0,0 +1,69 @@
+-- $Header$
+--
+--
+-- $Log$
+-- Revision 1.1  1994/06/10 03:31:40  eichin
+-- autoconfed isode for kerberos work
+--
+# Revision 1.1  1994/05/31 20:40:34  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+-- Revision 8.0  91/07/17  12:43:17  isode
+-- Release 7.0
+-- 
+--
+
+--
+--                               NOTICE
+--
+--    Acquisition, use, and distribution of this module and related
+--    materials are subject to the restrictions of a license agreement.
+--    Consult the Preface in the User's Manual for the full terms of
+--    this agreement.
+--
+--
+
+
+
+T2 DEFINITIONS ::=
+
+
+BEGIN
+
+-- Embedded Sequences test
+
+
+SECTIONS enc dec prnt
+
+Info ::= SEQUENCE {
+       a1 [0] IMPLICIT INTEGER,
+       a2 [1] IMPLICIT INTEGER,
+       a3 [2] IMPLICIT INTEGER,
+       a4 MPDU 
+       }
+
+MPDU ::=
+       SEQUENCE {
+           a-seq SEQUENCE {
+               fred [0] IMPLICIT INTEGER
+
+           }
+       }
+
+-- Simple type optimisations of POSY/PEPY
+
+ Bstring ::= [APPLICATION 8] BIT STRING
+
+ Ostring ::= [31] IMPLICIT OCTET STRING
+
+ Obj ::= [101] IMPLICIT MPDU
+
+ Sset ::= SET
+
+ Sseq ::= SEQUENCE
+
+ Sany ::= ANY
+
+ Soid ::= OBJECT IDENTIFIER
+
+END
diff --git a/src/isode/pepsy/t3.py b/src/isode/pepsy/t3.py
new file mode 100644 (file)
index 0000000..9b7759e
--- /dev/null
@@ -0,0 +1,513 @@
+-- $Header$
+--
+--
+-- $Log$
+-- Revision 1.1  1994/06/10 03:31:42  eichin
+-- autoconfed isode for kerberos work
+--
+# Revision 1.1  1994/05/31 20:40:36  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+-- Revision 8.0  91/07/17  12:43:17  isode
+-- Release 7.0
+-- 
+--
+
+--
+--                               NOTICE
+--
+--    Acquisition, use, and distribution of this module and related
+--    materials are subject to the restrictions of a license agreement.
+--    Consult the Preface in the User's Manual for the full terms of
+--    this agreement.
+--
+--
+
+
+
+T3 DEFINITIONS ::=
+
+%{
+/*
+ * this stuff is to test the verbatim actions at the start of the 
+ * type definitions
+ */
+%}
+
+BEGIN
+
+
+
+Pepy-refs [[ P struct pepy_refs * ]] ::= SEQUENCE {
+    [1] IMPLICIT INTEGER [[ i parm->t_int ]],
+    [2] IMPLICIT ENUMERATED [[ i parm->t_enum ]] {
+       orange(1), apple(2), pear(3), bannana(4) },
+
+    [3] IMPLICIT OCTET STRING [[ q parm->t_qbuf ]],
+    [4] IMPLICIT OCTET STRING [[ s parm->t_string ]],
+    [5] IMPLICIT OCTET STRING [[ o parm->t_ostring $ parm->t_olen ]],
+    [6] IMPLICIT BIT STRING [[ t parm->t_pe ]],
+    [7] IMPLICIT BIT STRING [[ x parm->t_bstring $ t_blen ]],
+    [8] IMPLICIT BOOLEAN [[ b parm->t_bool ]],
+    [9] IMPLICIT OBJECT IDENTIFIER [[ O parm->t_oid ]],
+    [10] IMPLICIT REAL [[ r parm->t_real ]],
+    [11] ANY [[ a parm->t_any ]],
+    [12] Def-types [[ p parm->t_def ]],
+    [13] Opt-types [[ p parm->t_opt ]] OPTIONAL
+
+    }
+
+-- Optional and Default test cases
+
+Def-types [[ P struct pepy_refs1 * ]] ::= SEQUENCE {
+    [1] INTEGER [[ i parm->t_int ]] DEFAULT 2,
+    [2] IMPLICIT INTEGER [[ i parm->t_int1 ]] DEFAULT 2,
+    [3] IMPLICIT ENUMERATED [[ i parm->t_enum ]]
+       { orange(1), apple(2), pear(3), bannana(4) } DEFAULT pear,
+
+    [4] ENUMERATED [[ i parm->t_enum1 ]] {
+       orange(1), apple(2), pear(3), bannana(4) } DEFAULT pear,
+    [5] IMPLICIT OCTET STRING [[ q parm->t_qbuf ]]
+                       DEFAULT '536f6d65206973206f757420746865726521'H,
+    [6] OCTET STRING [[ q parm->t_qbuf1 ]]
+                       DEFAULT '536f6d65206973206f757420746865726521'H,
+    [7] IMPLICIT OCTET STRING [[ s parm->t_string ]] DEFAULT '003132'h,
+    [8] OCTET STRING [[ s parm->t_string1 ]] DEFAULT '003132'h,
+    [9] IMPLICIT OCTET STRING [[ o parm->t_ostring $ parm->t_olen ]]
+                       DEFAULT 'ff01ab20'h,
+    [10] OCTET STRING [[ o parm->t_ostring1 $ parm->t_olen1 ]]
+                       DEFAULT 'ff01ab20'h,
+    [11] IMPLICIT BIT STRING [[ t parm->t_pe ]]
+       DEFAULT '00010010001100010001101000110111001010101'B,
+    [12] BIT STRING [[ t parm->t_pe1 ]]
+       DEFAULT '00010010001100010001101000110111001010101'B,
+    [13] IMPLICIT BIT STRING [[ x parm->t_bstring $ t_blen ]]
+       DEFAULT '00000000001100010011001000110011'B,
+    [14] BIT STRING [[ x parm->t_bstring1 $ t_blen1 ]]
+       DEFAULT '00000000001100010011001000110011'B,
+    [15] IMPLICIT BOOLEAN [[ b parm->t_bool ]] DEFAULT TRUE,
+    [16] BOOLEAN [[ b parm->t_bool ]] DEFAULT TRUE,
+    [17] IMPLICIT OBJECT IDENTIFIER [[ O parm->t_oid ]], -- one day  DEFAULT 1.17.42,
+    [18] OBJECT IDENTIFIER [[ O parm->t_oid1 ]] OPTIONAL, -- one day  DEFAULT 1.17.42,
+    [19] IMPLICIT REAL [[ r parm->t_real ]] DEFAULT { 306998, 10, -5 },
+    [20] REAL [[ r parm->t_real1 ]] DEFAULT { 306998, 10, -5 },
+    [21] ANY [[ a parm->t_any ]] OPTIONAL
+
+    }
+
+Opt-types [[ P struct pepy_refs1 * ]] ::= SEQUENCE {
+    [1] IMPLICIT INTEGER [[ i parm->t_int ]] OPTIONAL << opt_set $ OPT_INT1 >>,
+    [2] INTEGER [[ i parm->t_int1 ]] OPTIONAL << opt_set $ OPT_INT2 >>,
+    [3] IMPLICIT ENUMERATED [[ i parm->t_enum ]] {
+       orange(1), apple(2), pear(3), bannana(4) } OPTIONAL << opt_set $ OPT_ENUM1 >>,
+    [4] ENUMERATED [[ i parm->t_enum1 ]] {
+       orange(1), apple(2), pear(3), bannana(4) } OPTIONAL << opt_set $ OPT_ENUM2 >>,
+
+    [5] IMPLICIT OCTET STRING [[ q parm->t_qbuf ]] OPTIONAL,
+    [6] OCTET STRING [[ q parm->t_qbuf1 ]] OPTIONAL,
+    [7] IMPLICIT OCTET STRING [[ s parm->t_string ]] OPTIONAL,
+    [8] OCTET STRING [[ s parm->t_string1 ]] OPTIONAL,
+    [9] IMPLICIT OCTET STRING [[ o parm->t_ostring $ parm->t_olen ]]
+                       OPTIONAL,
+    [10] OCTET STRING [[ o parm->t_ostring1 $ parm->t_olen1 ]]
+                       OPTIONAL,
+    [11] IMPLICIT BIT STRING [[ t parm->t_pe ]] OPTIONAL,
+    [12] BIT STRING [[ t parm->t_pe1 ]] OPTIONAL,
+    [13] IMPLICIT BIT STRING [[ x parm->t_bstring $ t_blen ]] OPTIONAL,
+    [14] BIT STRING [[ x parm->t_bstring1 $ t_blen1 ]] OPTIONAL,
+    [15] IMPLICIT BOOLEAN [[ b parm->t_bool ]] OPTIONAL << opt_set $ OPT_BOOL1>>,
+    [16] BOOLEAN [[ b parm->t_bool1 ]] OPTIONAL << opt_set $ OPT_BOOL2>>,
+    [17] IMPLICIT OBJECT IDENTIFIER [[ O parm->t_oid ]], -- one day  OPTIONAL,
+    [18] IMPLICIT REAL [[ r parm->t_real ]] OPTIONAL << opt_set $ OPT_REAL1 >>,
+    [19] REAL [[ r parm->t_real1 ]] OPTIONAL << opt_set $ OPT_REAL2 >>,
+    [20] ANY [[ a parm->t_any ]]
+
+    }
+
+    Single-type [[ P struct pepy_refs1 * ]] ::= SEQUENCE {
+       a SEQUENCE [[ T struct pepy_refs1 * $ * ]] {
+               [1] IMPLICIT INTEGER [[ i parm->t_int ]] OPTIONAL << opt_set $ OPT_INT1 >>
+           },
+       b SEQUENCE [[ T struct pepy_refs1 * $ * ]] {
+               [2] INTEGER [[ i parm->t_int1 ]] OPTIONAL << opt_set $ OPT_INT2 >>
+           },
+
+       c SET [[ T struct pepy_refs1 * $ *parm ]] {
+           [3] IMPLICIT ENUMERATED [[ i parm->t_enum ]] {
+orange(1), apple(2), pear(3), bannana(4) } OPTIONAL << opt_set $ OPT_ENUM1 >>
+       },
+       d SET [[ T struct pepy_refs1 *  $ *parm ]] {
+           [4] ENUMERATED [[ i parm->t_enum1 ]] {
+orange(1), apple(2), pear(3), bannana(4) } OPTIONAL << opt_set $ OPT_ENUM2 >>
+       }
+    }
+
+    Repeated [[ P struct repeats * ]]::= SEQUENCE {
+       a SEQUENCE OF [[ T struct rep_int * $ rp_sq1 ]]
+           <<r>> [1] INTEGER [[ i i ]],
+
+       b SEQUENCE OF [[ T struct rep_elem * $ rp_sq2 ]] <<r_next>>
+               Rep-elem [[ p * ]],
+
+       c SET OF [[ T struct rep_int * $ rp_st1 ]] <<r>> INTEGER [[ i i ]],
+
+       d SET OF [[ T struct rep_elem * $ rp_st2 ]] <<r_next>>
+               [3] IMPLICIT Rep-elem [[ p * ]],
+
+       e CHOICE [[ T struct repeats  * $ * ]] <<rp_choice>> {
+               [1] INTEGER [[ i rp_int ]],
+               [2] BOOLEAN [[ b rp_bool ]],
+               [3] OCTET STRING [[ o rp_ostring $ rp_int ]]
+           }
+       }
+
+    Rep-elem [[ P struct rep_elem * ]]
+       ::= SEQUENCE {
+           a INTEGER [[ i r_int ]],
+           b OCTET STRING [[ s r_ostring ]],
+           c BIT STRING [[ x r_bstring $ r_int ]]
+       }
+
+    Defined [[ P struct pepy_refs * ]] ::= 
+       SEQUENCE {
+       a PrintableString [[ s t_string ]],
+       b [ APPLICATION 3 ] AString [[ q t_qbuf ]],
+       c [ APPLICATION 3 ] IMPLICIT AnOctetString [[ o t_ostring $ t_olen ]],
+       d BitsAndPieces [[ x t_bstring $ t_blen ]],
+       e AnAny [[ a t_any ]],
+       ABitString [[ t t_pe ]],
+       AnotherType [[ i t_int ]],
+       [12] AReal [[ r t_real ]],
+       [99] IMPLICIT AnOID [[ O t_oid ]],
+       [13] IMPLICIT Boodles [[ b t_bool ]],
+       AnEnumerated [[ i t_enum ]]
+       }
+
+    AString ::= GraphicString
+
+    AnOctetString ::= OCTET STRING
+
+    BitsAndPieces ::= [31] SomeBits
+
+    SomeBits ::= [APPLICATION 10] IMPLICIT ABitString
+
+    ABitString ::= BIT STRING
+
+    AnAny ::= ANY
+
+    AnotherType ::= [21] AnInteger
+
+    AnInteger ::= INTEGER
+
+    AReal ::= REAL
+
+    AnOID ::= OBJECT IDENTIFIER
+
+    Boodles ::= [PRIVATE 9] ABoolean
+
+    ABoolean ::= [APPLICATION 12] BOOLEAN
+
+    AnEnumerated ::= [4] ENUMERATED { orange(1), apple(2), pear(3), bannana(4) } 
+    -- Coding functions tests
+
+    CodeTest [[ P struct codedata * ]] ::= SEQUENCE {
+       a BasicANY [[ p cd_a ]],
+       b [42] E-ANY [[ p cd_b ]],
+       c [36] D-ANY [[ p cd_c ]],
+       d DE-ANY [[ p cd_d ]],
+       e [APPLICATION 44] IMPLICIT INTEGER [[ i cd_int ]]
+           [[ E get_int ]] [[ D put_int ]] DEFAULT 1,
+       f [17] GraphicString [[ s cd_string ]]
+           [[ E get_string ]][[ D put_string ]] [[ F fr_string ]] OPTIONAL,
+       left CodeOpt [[ p cd_left ]] OPTIONAL,
+       right CodeDflt [[ p cd_right ]] OPTIONAL
+    }
+
+   BasicANY ::= ANY [[ a * ]] 
+
+   E-ANY ::= ANY [[ a * ]] [[ E get_pe ]]
+
+   D-ANY ::= ANY [[ a * ]]  [[ D put_pe ]] [[ F fr_pe ]]
+
+   DE-ANY ::= ANY [[ a * ]]  [[ D put_pe ]] [[ E get_pe ]]
+
+    CodeOpt [[ P struct codedata * ]] ::= SEQUENCE {
+       a [PRIVATE 5] BasicANY [[ p cd_a ]] OPTIONAL,
+       b [35] E-ANY [[ p cd_b ]] OPTIONAL,
+       c [45] EXPLICIT D-ANY [[ p cd_c ]] OPTIONAL <<cd_opt_set $ CD_C>>,
+       d [1] DE-ANY [[ p cd_d ]] OPTIONAL <<cd_opt_set $ CD_D>>,
+       e [15] IMPLICIT INTEGER [[ i cd_int ]] [[ E get_int ]] [[ D put_int ]]
+               OPTIONAL << cd_opt_set $ CD_INT >>,
+       f GraphicString [[ s cd_string ]] [[ E get_string ]][[ D put_string ]]
+               OPTIONAL
+    }
+
+    -- It would be nice to do DEFAULTs for ANY but how do we specify
+    -- DEFAULT ANY in the ASN.1 ?? Let alone parse it
+
+    CodeDflt [[ P struct codedata * ]] ::= SEQUENCE {
+       a [1] BasicANY [[ p cd_a ]] OPTIONAL,
+       b [2] E-ANY [[ p cd_b ]] OPTIONAL,
+       c [3] D-ANY [[ p cd_c ]] OPTIONAL <<cd_opt_set $ CD_C>>,
+       d [4] DE-ANY [[ p cd_d ]] OPTIONAL <<cd_opt_set $ CD_D>>,
+       e [APPLICATION 4] INTEGER [[ i cd_int ]] [[ E get_int ]] [[ D put_int ]]
+               DEFAULT 3,
+       f [90] IMPLICIT GraphicString [[ s cd_string ]] [[ E get_string2 ]]
+           [[ D put_string2 ]] DEFAULT '536f6d65206973206f7574'H
+    }
+
+    Simple1 [[ P struct codedata * ]] ::= CodeDflt [[ p cd_right ]]
+
+    Simple2 [[ P struct codedata * ]] ::= INTEGER [[ i cd_int ]]
+
+    Simple3 [[ P struct codedata * ]] ::= [1] INTEGER [[ i cd_int1 ]]
+
+    Simple4 [[ P struct codedata * ]] ::= [1] IMPLICIT INTEGER [[ i cd_int2 ]]
+
+    Simple5 [[ P struct codedata * ]] ::= OCTET STRING [[ s cd_string ]]
+
+    Simple6 [[ P struct codedata * ]] ::= [1] OCTET STRING [[ s cd_string1 ]]
+
+    Simple7 [[ P struct codedata * ]] ::= [1] IMPLICIT OCTET STRING
+                                               [[ s cd_string2 ]]
+
+    Simple8 [[ P struct codedata * ]] ::= OBJECT IDENTIFIER [[ O cd_oid ]]
+
+    Simple9 [[ P struct codedata * ]] ::= [1] OBJECT IDENTIFIER [[ O cd_oid1 ]]
+
+    Simple10 [[ P struct codedata * ]] ::= [1] IMPLICIT OBJECT IDENTIFIER
+                                               [[ O cd_oid2 ]]
+
+    Simple11 [[ P struct codedata * ]] ::= ANY [[ a cd_a ]]
+
+    Simple12 [[ P struct codedata * ]] ::= BIT STRING [[ t cd_bit ]]
+
+    Simple13 [[ P struct codedata * ]] ::= REAL [[ r cd_real ]]
+
+    Simple14 [[ P struct codedata * ]] ::= BOOLEAN [[ b cd_bool ]]
+
+    AllSimples [[ P struct codedata * ]] ::= SEQUENCE {
+
+       a Simple1 [[ p * ]],
+       b Simple2 [[ p * ]],
+       c Simple3 [[ p * ]],
+       d Simple4 [[ p * ]],
+       e Simple5 [[ p * ]],
+       f Simple6 [[ p * ]],
+       g Simple7 [[ p * ]],
+       h Simple8 [[ p * ]],
+       i Simple9 [[ p * ]],
+       j Simple10 [[ p * ]],
+       k Simple11 [[ p * ]],
+       l Simple12 [[ p * ]],
+       m Simple13 [[ p * ]],
+       n Simple14 [[ p * ]]
+
+    }
+
+    UAction [[ P struct repeats * ]]::= SEQUENCE {
+       a SEQUENCE OF [[ T struct rep_int * $ rp_sq1 ]]
+           <<r>> [1] INTEGER [[ i i ]],
+
+       b SEQUENCE OF [[ T struct rep_elem * $ rp_sq2 ]] <<r_next>>
+               Rep-action [[ p * ]],
+
+       c SET OF [[ T struct rep_int * $ rp_st1 ]] <<r>> INTEGER [[ i i ]],
+
+       d SET OF [[ T struct rep_elem * $ rp_st2 ]] <<r_next>>
+               %E{ (void) printf("encoding SET OF Rep-action\n");%}
+               [3] IMPLICIT Rep-action [[ p * ]],
+
+       e CHOICE [[ T struct repeats  * $ * ]] <<rp_choice>> {
+           %D{ (void) printf("Before Encoding CHOICE\n"); %}
+               [1] INTEGER [[ i rp_int ]],
+               [2]
+               %E{ (void) printf("encoding Boolean %d\n", parm->rp_bool);%}
+               BOOLEAN [[ b rp_bool ]]
+               %D{ (void) printf("Decoding Boolean\n"); %},
+               [3] OCTET STRING [[ o rp_ostring $ rp_int ]]
+           }
+       %D{ (void) printf("After Decoding CHOICE: chosen %d\n", (*parm)->rp_choice); %}
+       }  %D{ (void) printf("After Decoding UAction\n"); %}
+
+    Rep-action [[ P struct rep_elem * ]]
+       ::=
+               %D{ (void) printf("Before Decoding Rep-action\n"); %}
+       SEQUENCE {
+               %E{ (void) printf("before encoding INTEGER %d\n", parm->r_int);%}
+           a INTEGER [[ i r_int ]],
+               %E{ (void) printf("before encoding OCTET STRING \"%s\"\n",
+                           parm->r_ostring);
+           %}
+           b OCTET STRING [[ s r_ostring ]],
+               %E{
+                   int i;
+
+                   (void) printf("before encoding BIT STRING: ");
+                   for (i = 0; i < parm->r_int; i++) {
+                       if (BITTEST(parm->r_bstring, i))
+                           (void) putchar('1');
+                       else
+                           (void) putchar('0');
+                   }
+                   (void) putchar('\n');
+
+               %}
+           c BIT STRING [[ x r_bstring $ r_int ]]
+               %E{
+                   (void) printf("After Bitstring encoding:");
+                   vunknown(*ppe);
+               %}
+       }
+               %E{
+                   (void) printf("After Sequence encoding:\n");
+                   vunknown(*ppe);
+               %}
+               %D{
+                   int i;
+
+                   (void) printf("After Decoding Rep-action:\n");
+                   (void) printf("rp_int %d\n", (*parm)->r_int);
+                   (void) printf("r_ostring \"%s\"\n", (*parm)->r_ostring);
+                   (void) printf("r_bstring: ");
+
+                   for (i = 0; i < (*parm)->r_int; i++) {
+                       if (BITTEST((*parm)->r_bstring, i))
+                           (void) putchar('1');
+                       else
+                           (void) putchar('0');
+                   }
+                   (void) putchar('\n');
+
+               %}
+
+END
+%{
+
+/*
+ * Encoding function for test examples of the Coding functions in t3.py
+ */
+
+get_pe(parm, ppe)
+PE     parm;
+PE     *ppe;
+{
+    if (ppe == (PE *)0) {
+       if (parm == NULLPE)     /* Optional */
+           return (OK + 1);
+       return (OK);
+    }
+
+    *ppe = pe_cpy(parm);
+    return (OK);
+}
+
+put_pe(parm, pe)
+PE     *parm;
+PE     pe;
+{
+    *parm = pe_cpy(pe);
+    return (OK);
+}
+
+get_int(parm, ppe)
+struct codedata        *parm;
+PE     *ppe;
+{
+    if (ppe == (PE *)0) {
+       if (parm->cd_int == 1)  /* Default case */
+           return (OK + 1);
+       return (OK);
+    }
+
+    *ppe = int2prim(parm->cd_int);
+    return (OK);
+}
+
+put_int(parm, pe)
+struct codedata        **parm;
+PE     pe;
+{
+    if (pe)
+       (*parm)->cd_int = prim2num(pe);
+    else
+       (*parm)->cd_int = 1;    /* Default */
+    return (OK);
+}
+
+get_string(parm, ppe)
+struct codedata        *parm;
+PE     *ppe;
+{
+    if (ppe == (PE *)0) {
+       if (parm->cd_string == NULLCP) /* Not present */
+           return (OK + 1);
+       return (OK);
+    }
+
+    *ppe = str2prim(parm->cd_string, strlen(parm->cd_string), 0, 0);
+    return (OK);
+}
+
+put_string(parm, pe)
+struct codedata        **parm;
+PE     pe;
+{
+    int        len;
+
+    if (pe)
+       (*parm)->cd_string = prim2str(pe, &len);
+    else
+       (*parm)->cd_string = NULLCP;    /* Default */
+
+    return (OK);
+}
+get_string2(parm, ppe)
+struct codedata        *parm;
+PE     *ppe;
+{
+    if (ppe == (PE *)0) {
+       if (parm->cd_string == NULLCP
+        || strcmp(parm->cd_string, "Some is out") == 0)/* Not present */
+           return (OK + 1);
+       return (OK);
+    }
+
+    *ppe = str2prim(parm->cd_string, strlen(parm->cd_string), 0, 0);
+    return (OK);
+}
+
+put_string2(parm, pe)
+struct codedata        **parm;
+PE     pe;
+{
+    int        len;
+
+    if (pe)
+       (*parm)->cd_string = prim2str(pe, &len);
+    else
+       (*parm)->cd_string = strdup("Some is out");     /* Default */
+
+    return (OK);
+}
+
+fr_string(parm)
+struct codedata        *parm;
+{
+     if (parm->cd_string)
+       free(parm->cd_string);
+
+     return (OK);
+}
+
+fr_pe(parm)
+PE     parm;
+{
+    if (parm)
+       pe_free(parm);
+
+    return (OK);
+}
+
+%}
+
diff --git a/src/isode/pepsy/test_table.h b/src/isode/pepsy/test_table.h
new file mode 100644 (file)
index 0000000..d55f588
--- /dev/null
@@ -0,0 +1,209 @@
+/* test_table.h */
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:45  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:38  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:18  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+/*
+ * This contains the information about each test case necessary to test it
+ * e.g. size, name
+ */
+
+ struct tst_typ {
+       char    *tst_name;      /* Name for error messages */
+       unsigned int    tst_size; /* Size of its data structure in bytes */
+       int     tst_entry;      /* entry for decoding/encoding */
+       int     tst_tests;      /* How many values of the t_test variable
+                                * to try it with
+                                */
+#define NOENTRY                -1
+       }  t_case[] = {
+       /* MPDU */
+       { "MPDU", sizeof (struct type_T1_MPDU), _ZMPDUT1, 1, },
+#define TY_MPDU        0       
+       { "Embedded", sizeof (struct type_T1_Embedded), _ZEmbeddedT1, 1, },
+#define TY_EMBEDDED    1       
+       { "Strings", sizeof (struct type_T1_Strings), _ZStringsT1, 1, },
+#define TY_STRINGS     2       
+       { "Embedded Strings", sizeof (struct type_T1_Emb__Strings),
+           _ZEmb_StringsT1, 1, },
+#define TY_EMB_STRINGS 3       
+       { "Implicit tags", sizeof (struct type_T1_Impl__Tags),
+           _ZImpl_TagsT1, 1, },
+#define TY_IMPLICIT    4       
+       { "Explicit tags", sizeof (struct type_T1_Expl__Tags),
+           _ZExpl_TagsT1, 1, },
+#define TY_EXPLICIT    5       
+       { "SEQ OF and SET OF", sizeof (struct type_T1_Seqof__Test),
+           _ZSeqof_TestT1, 10, },
+#define TY_SEQOF       6       
+       { "Seqof Test 1", sizeof (struct element_T1_4), NOENTRY, 0, },
+#define TY_ELEMENT4    7       
+       { "Set of Test 1", sizeof (struct member_T1_2), NOENTRY, 0, },
+#define TY_MEMBER2     8       
+       { "Seq of Test 2", sizeof (struct element_T1_6), NOENTRY, 0, },
+#define TY_ELEMENT6    9       
+       { "Seq of Sequence test", sizeof (struct element_T1_8), NOENTRY, 0, },
+#define TY_ELEMENT8    10      
+       { "Set of Test 2", sizeof (struct member_T1_4), NOENTRY, 0, },
+#define TY_MEMBER4     11      
+       { "Set of Sequence", sizeof (struct element_T1_9), NOENTRY, 0, },
+#define TY_ELEMENT9    12      
+       { "Choice", sizeof (struct type_T1_Choice__Test), _ZChoice_TestT1, 7, },
+#define TY_CHOICE      13      
+       { "Choice test 0", sizeof (struct choice_T1_0), NOENTRY, 0, },
+#define TY_CHOICE0     14      
+       { "Choice test 1", sizeof (struct choice_T1_1), NOENTRY, 0, },
+#define TY_CHOICE1     15
+       { "Choice test 2", sizeof (struct choice_T1_2), NOENTRY, 0, },
+#define TY_CHOICE2     16
+       { "Element 10", sizeof (struct element_T1_10), NOENTRY, 0, },
+#define TY_ELEMENT10   17
+       { "Member 6", sizeof (struct member_T1_6), NOENTRY, 0, },
+#define TY_MEMBER6     18
+       { "Element 11", sizeof (struct element_T1_11), NOENTRY, 0, },
+#define TY_ELEMENT11   19
+       { "Choice test 3", sizeof (struct choice_T1_3), NOENTRY, 0, },
+#define TY_CHOICE3     20
+       { "Optional test", sizeof (struct type_T1_Opt__Strings), _ZOpt_StringsT1,
+       8, },
+#define TY_OPTIONAL    21
+       { "Element 12", sizeof (struct element_T1_12), NOENTRY, 0, },
+#define TY_ELEMENT12   22
+       { "Member 7", sizeof (struct member_T1_7), NOENTRY, 0, },
+#define TY_MEMBER7     23
+       { "Choice test 4", sizeof (struct choice_T1_4), NOENTRY, 0, },
+#define TY_CHOICE4     24
+       { "Default test", sizeof (struct type_T1_Def__Strings), _ZDef_StringsT1,
+       12, },
+#define TY_DEFAULT     25
+       { "Element 13", sizeof (struct element_T1_13), NOENTRY, 0, },
+#define TY_ELEMENT13   26
+       { "Member 8", sizeof (struct member_T1_8), NOENTRY, 0, },
+#define TY_MEMBER8     27
+       { "External References", sizeof (struct type_T1_E__ref), _ZE_refT1, 6,},
+#define TY_EXTREF      28
+       { "T2 Info", sizeof (struct type_T2_Info), NOENTRY, 0, },
+#define TY_T2_INFO     29
+       { "T2 MPDU", sizeof (struct type_T2_MPDU), NOENTRY, 0, },
+#define TY_T2_MPDU     30
+       { "T2 ELEMENT 0", sizeof (struct element_T2_0), NOENTRY, 0, },
+#define TY_T2_ELEM0    31
+       { "Optimised", sizeof (struct type_T1_Optimised), _ZOptimisedT1, 8, },
+#define TY_OPTIMISED   32
+       { "MEMBER 9", sizeof (struct member_T1_9), NOENTRY, 0, },
+#define TY_MEMBER9     33
+       { "EXTERNAL", sizeof (struct type_T1_Ext__typ), _ZExt_typT1, 6, },
+#define TY_EXTERNAL    34
+       { "Single EXTERNAL", sizeof (struct type_T1_SExt), _ZSExtT1, 1, },
+#define TY_SEXTERNAL   35
+       { "Explicit Tagged Objects", sizeof (struct type_T1_Etags), _ZEtagsT1, 3, },
+#define TY_ETAGOBJ     36
+       { "Single Objects", sizeof (struct type_T1_Stest), _ZStestT1, 4, },
+#define TY_STEST       37
+       { "Single Integer", sizeof (struct type_T1_Sint), NOENTRY, 0, },
+#define TY_SINT                38
+       { "Enumerated Type", sizeof (struct type_T1_Enum__type), _ZEnum_typeT1,
+       4, },
+#define TY_ETYPE       39
+       { "Tests of Enumerated type", sizeof (struct type_T1_T__enum),
+       _ZT_enumT1, 4, },
+#define TY_ENUM_TEST   40
+#define TY_REAL                41
+#ifdef PEPSY_REALS
+       { "Real", sizeof (struct type_T1_Real), _ZRealT1, 3, },
+
+       { "Tests of Real type", sizeof (struct type_T1_T__real),
+       _ZT_realT1, 4, },
+
+       { "Pepy Stuff", sizeof (struct pepy_refs), _ZT_pepyT1, 3, },
+
+       { "Default Pepy", sizeof (struct pepy_refs1), NOENTRY, 0, },
+
+       { "Optional Pepy", sizeof (struct pepy_refs1), NOENTRY, 0, },
+
+       { "Compound S-types", sizeof (struct pepy_refs1), _ZT3_SingleT1, 3, },
+
+#else
+       { NULLCP, 0, NOENTRY, 3, },
+
+       { NULLCP, 0, NOENTRY, 4, },
+
+       { NULLCP, 0, NOENTRY, 3, },
+
+       { NULLCP, 0, NOENTRY, 3, },
+
+       { NULLCP, 0, NOENTRY, 0, },
+
+       { NULLCP, 0, NOENTRY, 3, },
+#endif
+#define TY_REAL_TEST   42
+#define TY_PEPY                43
+#define TY_DEFPEPY     44
+#define TY_OPTPEPY     45
+#define TY_S_COMPD     46
+
+       {"Repeating pepy elements",sizeof (struct repeats), _ZT3_RepeatT1, 3, },
+#define TY_REPEAT      47
+
+#ifdef PEPSY_REALS
+
+       {"Value Passing Defined types",sizeof (struct pepy_refs),
+           _ZT3_DefinedT1, 3, },
+
+#else
+       { NULLCP, 0, NOENTRY, 3, },
+
+#endif
+
+#define TY_VPDEFINED   48
+
+       {"function calling code",sizeof (struct codedata), _ZT3_CodeTestT1, 3,},
+#define TY_FUNC        49
+
+       {"optional function calling",sizeof (struct codedata), NOENTRY, 3,},
+#define TY_OPTFUNC     50
+
+       {"default function calling",sizeof (struct codedata), NOENTRY, 3,},
+#define TY_DFTFUNC     51
+
+#ifdef PEPSY_REALS
+
+       {"All Simple Types",sizeof (struct codedata), _ZT3_AllSimplesT1, 3,},
+
+#else
+       { NULLCP, 0, NOENTRY, 3, },
+
+#endif
+
+#define TY_ASIMPLE     52
+
+       {"Action Statements",sizeof (struct repeats), _ZT3_UActionT1, 3, },
+#define TY_ACTION      53
+       };
+
+#define MAXTCASE       (sizeof (t_case)/sizeof (t_case[0]))
diff --git a/src/isode/pepsy/tt.py b/src/isode/pepsy/tt.py
new file mode 100644 (file)
index 0000000..3ca2292
--- /dev/null
@@ -0,0 +1,82 @@
+-- $Header$
+--
+--
+-- $Log$
+-- Revision 1.1  1994/06/10 03:31:48  eichin
+-- autoconfed isode for kerberos work
+--
+# Revision 1.1  1994/05/31 20:40:40  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+-- Revision 8.0  91/07/17  12:43:18  isode
+-- Release 7.0
+-- 
+--
+
+--
+--                               NOTICE
+--
+--    Acquisition, use, and distribution of this module and related
+--    materials are subject to the restrictions of a license agreement.
+--    Consult the Preface in the User's Manual for the full terms of
+--    this agreement.
+--
+--
+
+
+
+TT DEFINITIONS ::=
+
+%{
+int foo;
+%}
+
+BEGIN
+
+EntryInformationSelection [[P struct entryinfoselection *]]
+       ::=
+       SET
+       {
+       attributeTypes
+               CHOICE [[ T struct entryinfoselection * $ *]]
+               <D< (*parm)->eis_allattributes>>
+               <E< parm->eis_allattributes ? 1 : 2>>
+               {
+               allAttributes
+                       [0] NULL,
+               select
+                       [1] SET OF [[ T struct attrcomp * $ eis_select ]] <<attr_link>>
+                               AttributeType [[p attr_type]]
+               }
+               %D{
+                       if ((*parm)->eis_allattributes == 1)
+                          (*parm)->eis_allattributes = TRUE;
+                       else
+                          (*parm)->eis_allattributes = FALSE;
+               %}
+                   -- DEFAULT allAttributes NULL,
+                   OPTIONAL <E<parm->eis_allattributes != FALSE>><D<0>>,
+       infoTypes
+               [2] INTEGER [[i eis_infotypes]]
+               {
+               attributeTypesOnly(0) ,
+               attributeTypesAndValues(1)
+               }
+                   DEFAULT attributeTypesAndValues
+       }
+
+
+TestChoice ::= CHOICE <E< 1 >> <D< foo >> {
+       one OCTET STRING,
+       two SEQUENCE {
+               one2 IA5String OPTIONAL <E< 1 >> <D< 0 >>,
+               two2 CHOICE {
+                       one3 NULL,
+                       two3 INTEGER
+               } OPTIONAL <E<1>> <D<foo = 1>>
+       },
+       three INTEGER {eine(1), zwei(2), drie(3) },
+       four BIT STRING { un(1), deux(2), trois(3), quatre(4) }
+}
+END
+
diff --git a/src/isode/pepsy/util.c b/src/isode/pepsy/util.c
new file mode 100644 (file)
index 0000000..5682985
--- /dev/null
@@ -0,0 +1,780 @@
+/* util.c */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:50  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/05/31 20:40:44  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:19  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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       "pepsy-driver.h"
+#include       "psap.h"
+#include       "pepsy.h"
+#include        <varargs.h>
+#include       "tailor.h"
+
+#ifndef        PEPYPARM
+#define PEPYPARM       char *
+#endif
+
+static char *pr_petype ();
+
+extern void exit();
+
+#ifdef lint
+/* VARARGS4 */
+
+int    pepsylose (module, p, pe, str)
+modtyp *module;
+tpe    *p;
+char   *str;
+PE     pe;
+{
+       return pepsylose (module, p, pe, str);
+}
+
+#else
+int    pepsylose (va_alist)
+va_dcl
+{
+       va_list ap;
+       int     type;
+       modtyp  *module;
+       tpe     *p;
+       char    *cp;
+       PE      pe;
+       char    buffer[BUFSIZ];
+
+       va_start (ap);
+
+       module = va_arg (ap, modtyp *);
+       p = va_arg (ap, tpe *);
+       pe = va_arg (ap, PE);
+
+       _asprintf (buffer, NULLCP, ap);
+       (void) sprintf (PY_pepy, "%s: module %s",
+                       buffer, module ? module -> md_name : "<none>");
+       if (p) {
+           cp = PY_pepy + strlen (PY_pepy);
+           (void) sprintf (cp, " %s/class=%s/id=%d",
+                           pr_petype (p -> pe_type),
+                           pe_classlist[p -> pe_flags & FL_CLASS],
+                           p -> pe_tag);
+       }
+       if (pe && pe -> pe_class >= 0 && ((int)pe -> pe_class) < pe_maxclass) {
+           cp = PY_pepy + strlen (PY_pepy);
+           (void) sprintf (cp, " got %s/%d", pe_classlist[pe -> pe_class],
+                           pe -> pe_id);
+       }
+
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
+
+       va_end (ap);
+       return NOTOK;
+}
+#endif
+
+#ifdef lint
+/* VARARGS4 */
+
+int    ppepsylose (module, p, pe, str)
+modtyp *module;
+ptpe   *p;
+char   *str;
+PE     pe;
+{
+       return ppepsylose (module, p, pe, str);
+}
+
+#else
+int    ppepsylose (va_alist)
+va_dcl
+{
+       va_list ap;
+       int     type;
+       modtyp  *module;
+       ptpe    *p;
+       char    *cp;
+       PE      pe;
+       char    buffer[BUFSIZ];
+
+       va_start (ap);
+
+       module = va_arg (ap, modtyp *);
+       p = va_arg (ap, ptpe *);
+       pe = va_arg (ap, PE);
+
+       _asprintf (buffer, NULLCP, ap);
+       (void) sprintf (PY_pepy, "%s: module %s",
+                       buffer, module ? module -> md_name : "<none>");
+       if (p) {
+           cp = PY_pepy + strlen (PY_pepy);
+           (void) sprintf (cp, " %s/class=%s/id=%d",
+                           pr_petype (p -> pe_type),
+                           pe_classlist[p -> pe_flags & FL_CLASS],
+                           p -> pe_tag);
+           if (p->pe_typename)
+               (void) sprintf (cp, "(%s)", *p -> pe_typename);
+       }
+       if (pe && pe -> pe_class >= 0 && ((int)pe -> pe_class) < pe_maxclass) {
+           cp = PY_pepy + strlen (PY_pepy);
+           (void) sprintf (cp, " got %s/%d", pe_classlist[pe -> pe_class],
+                           pe -> pe_id);
+       }
+
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP, ("%s", PY_pepy));
+
+       va_end (ap);
+       return NOTOK;
+}
+#endif
+
+/*
+ * Useful little routines
+ */
+/*
+ * print out the message and if the arguement is greater than 0
+ * terminate
+ */
+ferr(n, mesg)
+char   *mesg;
+{
+    (void) printf(mesg);
+    if (n > 0)
+       exit(n);
+}
+/*
+ * print out the message and number and if the arguement is greater
+ * than 0 terminate
+ */
+ferrd(n, mesg, d)
+char   *mesg;
+int     d;
+{
+    (void) printf(mesg, d);
+    if (n > 0)
+       exit(n);
+}
+
+/*
+ * 0 = Encoding table, 1 = Decoding table, 2 = Printing table
+ */
+#define TYP_ENC                0
+#define TYP_DEC                1
+#define TYP_PRINT      2
+#define TYP_LAST       2
+
+dmp_tpe(s, p, mod)
+char   *s;
+modtyp *mod;                   /* Module it is from */
+tpe    *p;
+{
+    int     typ, i, j;
+    tpe   **par, **prev;
+    char   *name;
+
+    (void) printf("%s: (%s)", s, mod->md_name);
+    /*
+     * Calculate what table it is in - we assume they are in order of
+     * increasing address
+     */
+
+    par = NULL;
+    for (typ = 0; typ <= TYP_LAST; typ++) {
+       switch (typ) {
+       case TYP_ENC:
+           if (mod->md_etab != NULL && mod->md_etab[0] < p) {
+               par = mod->md_etab;
+               name = "Encoding:";
+           }
+           break;
+
+       case TYP_DEC:
+           if (mod->md_dtab != NULL && mod->md_dtab[0] < p) {
+               par = mod->md_dtab;
+               name = "Decoding:";
+           }
+           break;
+
+       case TYP_PRINT:
+           if (mod->md_ptab != NULL && mod->md_ptab[0] < (ptpe *) p) {
+               par = (tpe **) mod->md_ptab;
+               name = "Printing:";
+           }
+           break;
+
+       default:
+           (void) pepsylose (mod, p, NULLPE, "dmp_tpe:typ = %d internal error\n",
+               typ);
+           return;
+       }
+    }
+    if (par == NULL) {
+       (void) printf("can't find entry 0x%x\n", p);
+       return;
+    }
+    prev = par;
+    for (i = mod->md_nentries; i > 0; i--) {
+       if (*par > p)
+           break;
+       par++;
+    }
+    if (par == prev)
+       (void) pepsylose (mod, p, NULLPE,
+           "dmp_tpe:par == prev == 0x%x internal error\n", (int) par);
+    par--;
+    j = p - *par;
+
+    (void) printf("%s type %d + %d ", name, par - prev, j);
+    pr_entry(p);
+}
+#define NENTRY(x)      ((sizeof (x)/sizeof (x[0])))
+/*
+ * Print out a tpe entry
+ */
+static char    *ntypes[] = { "PE_START", "PE_END", "illegal 1", "illegal 2",
+    "XOBJECT", "illegal 4", "illegal 5", "UCODE", "MALLOC", "SCTRL", "CH_ACT",
+    "OPTL", "BOPTIONAL", "FFN_CALL",},
+
+       *otypes[] = { "ANY", "INTEGER", "BOOLEAN", "OBJECT",
+    "BITSTRING", "OCTETSTRING", "SET_START", "SEQ_START", "SEQOF_START",
+    "SETOF_START", "CHOICE_START", "UNKNOWN", "T_NULL", "T_OID",
+    "ETAG", "IMP_OBJ", "EXTOBJ", "EXTMOD", "OBJID", "DFLT_F", "DFLT_B",
+    "T_STRING", "OCTET_PTR", "OCTET_LEN", "BITSTR_PTR", "BITSTR_LEN",
+    "FN_CALL" };
+
+static char *
+pr_petype (type)
+int    type;
+{
+    static char nbuf[30];
+
+    if (type >= PE_START && type < NENTRY(ntypes) - 1)
+       return ntypes[type + 1];
+    else if (type >= TYPE_DATA && type < NENTRY(otypes) + TYPE_DATA)
+       return otypes[type - TYPE_DATA];
+    (void) sprintf (nbuf, "%d", type);
+    return nbuf;
+}
+
+pr_entry(p)
+tpe    *p;
+{
+    (void) printf ("%s, ", pr_petype (p -> pe_type));
+    (void) printf("%d, %d, %d}\n", p->pe_ucode, p->pe_tag, p->pe_flags);
+}
+
+p_pr_entry(p)
+ptpe    *p;
+{
+    if (p->pe_type >= PE_START && p->pe_type < NENTRY(ntypes) - 1)
+        (void) printf("{%s, ", ntypes[p->pe_type + 1]);
+    else if (p->pe_type >= TYPE_DATA && p->pe_type < NENTRY(otypes) + TYPE_DATA)
+        (void) printf("{%s, ", otypes[p->pe_type - TYPE_DATA]);
+    else
+        (void) printf("{%d, ", p->pe_type);
+
+    (void) printf("%d, %d, %d}\n", p->pe_ucode, p->pe_tag, p->pe_flags);
+}
+
+
+/*
+ * null function for what evr purposes
+ */
+f_null()
+{
+}
+
+/*
+ * compare a given number of bits pointed to by the two character
+ * pointers return 0 if they are the same non zero otherwise
+ */
+bitscmp(p1, p2, len)
+register char *p1, *p2;
+int     len;
+{
+    register int i;
+    register unsigned int mask;
+
+    if (len >= 8 && bcmp(p1, p2, len / 8))
+       return (1);
+
+    if (len % 8 == 0)
+       return (0);
+    /* Check those last few bits */
+    i = len / 8;
+    mask = (0xff00 >> len % 8) & 0xff;
+    if ((p1[i] & mask) != (p2[i] & mask))
+       return (1);
+
+    return (0);
+}
+
+#define MIN(a, b)      (a < b ? a : b)
+/*
+ * compare an octet string and a qb and return 0 if they are the same
+ * and non zero otherwise
+ */
+ostrcmp(p, len, qb)
+register char *p;
+register int len;
+register struct qbuf *qb;
+{
+    register struct qbuf *qp;
+
+    if (len < 0 || qb == NULL || p == NULL)
+       return (1);
+    qp = qb;
+    do {
+       if (qp->qb_data != NULL) {
+           if (qp->qb_len < 0)
+               ferrd(1, "ostrcmp:qb_len %d < 0", qp->qb_len);
+           if (qp->qb_len > len)
+               return (1);
+           if (bcmp(qp->qb_data, p, qp->qb_len))
+               return (1);
+           if ((len -= qp->qb_len) == 0)
+               return (0);
+           p += qp->qb_len;
+       }
+       qp = qp->qb_forw;
+    } while (qp != qb);
+
+    return (len);
+}
+
+/*
+ * Is data present for the optional item? 1 for yes 0 for no
+ */
+hasdata(parm, p, mod, popt, optcnt)
+PEPYPARM parm;
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+int    *popt, *optcnt;
+{
+    int        val;
+
+    switch (p->pe_type) {
+    case INTEGER:
+    case REALTYPE:
+    case BOOLEAN:
+    case T_NULL:
+       if (DEFAULT(p)) {
+           /* Default's don't have bit map */
+           if (p[1].pe_type == DFLT_B && same(p, p + 1, parm, mod)
+           || p[-1].pe_type == DFLT_F && same(p, p - 1, parm, mod))
+               goto next;
+           break;
+       }
+       if (!TESTBIT(*popt, (*optcnt)++))
+           goto next;          /* Missing so skip */
+       break;
+
+    case ETAG:
+       if (!hasdata(parm, p + 1, mod, popt, optcnt))
+           goto next;
+       break;
+
+    case IMP_OBJ:
+       if (p[1].pe_type == SOBJECT && parm == NULL
+           || *((char **) (parm + p[1].pe_ucode)) == NULL)
+           goto next;
+       break;
+
+    case FN_CALL:      /* function call */
+       if ((val = (FN_PTR(mod, p))(parm, (PE *)0)) == NOTOK)
+           return pepsylose (mod, p, NULLPE,
+                             "hasdata:FN_CALL:call failed");
+       if (val != OK)
+           goto next;
+       break;
+
+    default:
+       if (*((char **) (parm + p->pe_ucode)) == NULL)
+           goto next;
+       break;
+    }
+    return (1);
+
+next:
+    return (0);
+}
+
+/*
+ * determine if the default value is the same as the value in the
+ * structure and if so return greater than zero (meaning don't encode this
+ * item). On error return NOTOK
+ */
+same(typ, dflt, parm, mod)
+tpe    *typ, *dflt;
+char   *parm;
+modtyp *mod;                   /* Module it is from */
+{
+    int     val;
+    int        len;
+    char   *p1;
+    PE      pe;
+    struct qbuf *qb;
+
+    switch (typ->pe_type) {
+    case INTEGER:
+       val = IVAL(mod, dflt) == *(integer *) (parm + typ->pe_ucode);
+       break;
+
+#ifdef PEPSY_REALS
+    case REALTYPE:
+       val = RVAL(mod, dflt) == *(double *) (parm + typ->pe_ucode);
+       break;
+#endif
+
+    case BOOLEAN:
+       val = IVAL(mod, dflt) == *(char *) (parm + typ->pe_ucode);
+       break;
+
+    case T_NULL:
+       val = 1;                /* Only one value */
+       break;
+
+    case SBITSTRING:
+       if ((pe = (PE) parm) == NULL) {
+           val = 1;
+           break;
+       }
+       goto bstring;
+
+    case BITSTRING:
+       if ((pe = *(PE *) (parm + typ->pe_ucode)) == NULL) {
+           val = 1;
+           break;
+       }
+bstring:
+       if ((p1 = bitstr2strb(pe, &val)) == NULL) {
+           (void) pepsylose (mod, typ, pe, "same:bad bitstring\n");
+           return (NOTOK);
+           /* Should really abort encoding here but how can we comunicate this
+            * to the routine that calls us?
+            */
+       }
+bstring2:
+       if (val != IVAL(mod, dflt) || bitscmp(PVAL(mod, dflt), p1, val))
+           val = 0;
+       else
+           val = 1;
+       if (typ->pe_type != BITSTR_PTR)
+           free(p1);
+       break;
+
+    case BITSTR_PTR:
+       if (typ[1].pe_type != BITSTR_LEN)
+           return pepsylose (mod, typ, pe, "same:missing BITSTR_LEN\n");
+       if ((p1 = *(char **) (parm + typ->pe_ucode)) == NULL) {
+           val = 1;
+           break;
+       }
+       val = *(int *) (parm + (typ + 1)->pe_ucode);
+       goto bstring2;
+
+    case SOCTETSTRING:
+       if ((qb = (struct qbuf *) parm) == NULL) {
+           val = 1;
+           break;
+       }
+       goto ostring;
+
+    case OCTETSTRING:
+       if ((qb = *(struct qbuf **) (parm + typ->pe_ucode)) == NULL) {
+           val = 1;
+           break;
+       }
+ostring:
+       if (ostrcmp(PVAL(mod, dflt), (int ) IVAL(mod, dflt), qb))
+           val = 0;
+       else
+           val = 1;
+       break;
+
+    case OCTET_PTR:
+       if (typ[1].pe_type != OCTET_LEN)
+           return pepsylose (mod, typ, pe, "same:missing OCTET_LEN\n");
+       if ((p1 = *(char **) (parm + typ->pe_ucode)) == NULL) {
+           val = 1;
+           break;
+       }
+       len = *(int *) (parm + (typ + 1)->pe_ucode);
+       goto o1string;
+
+    case T_STRING:
+       if ((p1 = *(char **) (parm + typ->pe_ucode)) == NULL) {
+           val = 1;
+           break;
+       }
+       len = strlen(p1);
+o1string:
+       if (len != IVAL(mod, dflt)) {
+           val = 0;
+           break;
+       }
+       if (bcmp(PVAL(mod, dflt), p1, len))
+           val = 0;
+       else
+           val = 1;
+       break;
+
+    case OBJECT:
+       if (*(char **) (parm + typ->pe_ucode) == NULL) {
+           val = 1;            /* to conform with pepy's way of
+                                * doing default */
+           break;
+       }
+       val = same(mod->md_etab[typ->pe_tag] + 1, dflt,
+                  *(char **) (parm + typ->pe_ucode), mod);
+       break;
+
+    case SOBJECT:
+       if ((char *) parm == NULL) {
+           val = 1;            /* to conform with pepy's way of
+                                * doing default */
+           break;
+       }
+       val = same(mod->md_etab[typ->pe_tag] + 1, dflt, parm, mod);
+       break;
+
+    case IMP_OBJ:
+       typ++;                  /* fall through */
+
+    case ANY:
+    case SANY:
+    case SEXTOBJ:
+    case EXTOBJ:
+    case OBJID:
+    case SOBJID:
+    case SEQ_START:
+    case SET_START:
+    case -1:                   /* Just use the pepy method of null
+                                * pointers */
+       /*
+        * This is the posy/pepy hack way of doing things at the
+        * moment
+        */
+       val = *(char **) (parm + typ->pe_ucode) == NULL;
+       break;
+
+    case FN_CALL:      /* function call */
+       if ((val = (FN_PTR(mod, typ))(parm, (PE *)0)) == NOTOK)
+           return pepsylose (mod, typ, NULLPE,
+                             "same:FN_CALL:call failed");
+       if (val != OK)
+           val = 1;
+       else
+           val = 0;
+       break;
+
+
+    default:
+       (void) pepsylose (mod, typ, NULLPE, "same: %d not implemented\n",
+           typ->pe_type);
+       return (NOTOK);
+    }
+
+    return (val);
+}
+
+/*
+ * Calculate the next tpe entry in the sequence. Count a sequence as
+ * one element
+ */
+tpe    *
+next_tpe(p)
+tpe    *p;
+{
+    int     level;
+
+
+
+    level = 0;
+    if (p->pe_type == PE_END) {
+       (void) pepsylose (NULLMODTYP, p, NULLPE,
+           "next_tpe:internal error: unexpected PE_END found");
+       return (p);
+    }
+    do {
+again:
+       switch (p->pe_type) {
+       case SSEQ_START:
+       case SSEQOF_START:
+       case SSET_START:
+       case SSETOF_START:
+       case SCHOICE_START:
+       case SEQ_START:
+       case SEQOF_START:
+       case SET_START:
+       case SETOF_START:
+       case CHOICE_START:
+           level++;
+           break;
+
+       case UCODE:
+       case MEMALLOC:
+       case SCTRL:
+       case CH_ACT:
+       case INTEGER:
+       case REALTYPE:
+       case BOOLEAN:
+       case SANY:
+       case ANY:
+       case T_NULL:
+       case OBJECT:
+       case SOBJECT:
+       case BITSTRING:
+       case BITSTR_LEN:
+       case SBITSTRING:
+       case OCTETSTRING:
+       case T_STRING:
+       case OCTET_LEN:
+       case SOCTETSTRING:
+       case OBJID:
+       case SOBJID:
+       case OPTL:
+       case EXTMOD:
+       case DFLT_B:
+       case FN_CALL:
+       case FFN_CALL:
+           break;
+
+       case IMP_OBJ:
+       case ETAG:
+       case EXTOBJ:
+       case SEXTOBJ:
+       case DFLT_F:
+       case OCTET_PTR:
+       case BITSTR_PTR:
+       case BOPTIONAL:
+       case FREE_ONLY:
+           p++;
+           goto again;
+
+       case PE_END:
+           level--;
+           break;
+
+       default:
+           ferrd(1, "next_tpe: unknown type %d\n", p->pe_type);
+       }
+       p++;
+    } while (level > 0 || p->pe_type == DFLT_B);
+
+    return (p);
+}
+
+/*
+ * Is there a match at for this tag and class pair. Return 1 if yes 0
+ * if no We will search through contained objects and through choices
+ */
+ismatch(p, mod, cl, tag)
+tpe    *p;
+modtyp *mod;                   /* Module it is from */
+unsigned int cl, tag;
+{
+    while (!ISDTYPE(p))
+       p++;
+
+    switch (p->pe_type) {
+    case SOBJECT:
+    case OBJECT:
+       /* Needs to be changed for optional and default */
+       return (ismatch(p = mod->md_dtab[p->pe_tag] + 1, mod, cl, tag));
+
+    case SEXTOBJ:
+    case EXTOBJ:
+       if (p[1].pe_type != EXTMOD) {
+           dmp_tpe("ismatch: missing EXTMOD", p, mod);
+           ferr(1, "ismatch:internal error\n");
+       }
+       return (ismatch(EXT2MOD(mod, (p + 1))->md_dtab[p->pe_tag] + 1,
+                       EXT2MOD(mod, (p + 1)), cl, tag));
+
+    case CHOICE_START:
+    case SCHOICE_START:
+       for (p++; p->pe_type != PE_END; p = next_tpe (p)) {
+           if (!ISDTYPE(p))
+               continue;
+           if (ismatch(p, mod, cl, tag))
+               return (1);
+       }
+       return (0);
+
+    case SANY:
+       return (1);
+
+    case FN_CALL:
+    case ANY:
+       if (STAG(p) == -1)
+           return (1);
+       /* else fall through - not sure if this is needed */
+
+    default:
+       return (tag == TAG(p) && cl == CLASS(p));
+    }
+}
+
+/*
+ * find the data entry that goes with this DFLT_F entry
+ * bascially skip over any ETAGS that (an arbitary number but almost always 1)
+ */
+tpe    *
+fdflt_f(p)
+register tpe   *p;
+{
+    if (p->pe_type != DFLT_F)
+       ferr(1, "fdlt_f:Internal Error missing DFLT_F\n");
+    
+    for (p++; p->pe_type != PE_END; p++) {
+       if (p->pe_type != ETAG)
+               return (p);
+    }
+    ferr(1, "fdlt_f:Internal Error PE_END found\n");
+    /*NOTREACHED*/
+}
+
+/*
+ * find the DFLT_B entry
+ */
+tpe    *
+fdflt_b(p)
+register tpe   *p;
+{
+    for (p++; p->pe_type != PE_END; p++) {
+       if (p->pe_type == DFLT_B)
+               return (p);
+    }
+    ferr(1, "fdflt_b:Internal Error PE_END found\n");
+    /*NOTREACHED*/
+}
diff --git a/src/isode/pepsy/version.major b/src/isode/pepsy/version.major
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/src/isode/pepsy/version.minor b/src/isode/pepsy/version.minor
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/src/isode/pepsy/vprint.c b/src/isode/pepsy/vprint.c
new file mode 100644 (file)
index 0000000..abad66e
--- /dev/null
@@ -0,0 +1,766 @@
+/* vprint.c - pepy printer support */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:55  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.2  1994/06/03 18:43:58  eichin
+ * don't declare fprintf on aix
+ *
+ * Revision 1.1  1994/05/31 20:40:53  eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0  91/07/17  12:43:20  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include <varargs.h>
+#include "UNIV-types.h"
+#include "psap.h"
+#include "pepsy.h"
+#include "logger.h"
+
+
+#ifndef __STDC__
+#ifndef _AIX
+int    fprintf ();     
+#endif
+#else
+#ifdef  __GNUC__
+#ifdef  SUNOS4         /* And probaby a few more - what a mess! */
+int    fprintf ();     
+#endif
+#endif
+#endif
+
+static vprint1 ();
+static vprint2 ();
+static vwrite ();
+
+/* \f   DATA */
+
+#define        VPRINT(s)       vprint1 (), vwrite ((s)), vprint2 ()
+
+static int vlevel = 0;
+
+static int didname = 0;
+static int didvpop = 0;
+static int didvpush = 0;
+static int docomma = 0;
+
+static char  *py_classlist[] = {
+    "UNIVERSAL", "APPLICATION", "", "PRIVATE"
+};
+
+static char *vbp = NULL;
+static char *vsp;
+
+IFP   vfnx = (IFP) fprintf;
+FILE *vfp = stdout;
+static PS    vps = NULLPS;
+
+char   *oct2str (), *newbuf ();
+
+/* \f   VPUSH/VPOP */
+
+vpush () {
+    if (didvpush)
+       vwrite ("\n"), didvpush = 0;
+    else
+       if (!didname && docomma)
+           vwrite (",\n");
+
+    if (didname)
+       vwrite (" ");
+    else
+       if (vfp && vlevel > 0)
+           (*vfnx) (vfp, "%*s", vlevel * 3, "");
+    vwrite ("{");
+    vlevel++;
+
+    didname = didvpop = docomma = 0, didvpush = 1;
+}
+
+
+vpop () {
+    if (didname || docomma)
+       vwrite ("\n");
+
+    vlevel--;
+    if (!didvpush && vfp && vlevel > 0)
+       (*vfnx) (vfp, "%*s", vlevel * 3, "");
+    vwrite ("}");
+    if (vlevel == 0)
+       vwrite ("\n");
+
+    didname = didvpush = 0, didvpop = docomma = vlevel ? 1 : 0;
+}
+
+/* \f   VNAME/VTAG */
+
+vname (name)
+char   *name;
+{
+    if (didvpush)
+       vwrite ("\n"), didvpush = 0;
+    else
+       if (docomma)
+           vwrite (",\n");
+
+    if (vfp && vlevel > 0)
+       (*vfnx) (vfp, "%*s", vlevel * 3, "");
+    vwrite (name);
+
+    didname = 1;
+}
+
+
+vtag (class, id)
+int    class,
+       id;
+{
+    register char *bp;
+    static char buffer[BUFSIZ];
+
+    if (didname)
+       return;
+
+    bp = buffer;
+    *bp++ = '[';
+    switch (class) {
+       case PE_CLASS_UNIV: 
+       case PE_CLASS_APPL: 
+       case PE_CLASS_PRIV: 
+           (void) sprintf (bp, "%s ", py_classlist[class]);
+           bp += strlen (bp);
+           break;
+
+       case PE_CLASS_CONT: 
+       default:
+           break;
+    }
+    (void) sprintf (bp, "%d]", id);
+
+    vname (buffer);
+}
+
+/* \f   VPRINT */
+
+#ifndef        lint
+vprint (va_alist)
+va_dcl
+{
+    char    buffer[BUFSIZ];
+    va_list ap;
+    
+    vprint1 ();
+
+    va_start (ap);
+
+    _asprintf (buffer, NULLCP, ap);
+    
+    va_end (ap);
+
+    vwrite (buffer);
+
+    vprint2 ();
+}
+#else
+/* VARARGS */
+
+vprint (fmt)
+char   *fmt;
+{
+    vprint (fmt);
+}
+#endif
+
+
+static vprint1 ()
+{
+    if (didvpush) {
+       vwrite ("\n"), didvpush = 0;
+       goto indent;
+    }
+    else
+       if (didname)
+           vwrite (" ");
+       else {
+           if (docomma)
+               vwrite (",\n");
+indent: ;
+           if (vfp && vlevel > 0)
+               (*vfnx) (vfp, "%*s", vlevel * 3, "");
+       }
+}
+
+
+static vprint2 ()
+{
+    if (vlevel == 0)
+       vwrite ("\n");
+
+    didname = didvpop = 0, docomma = vlevel ? 1 : 0;
+}
+
+/* \f */
+
+static vwrite (s)
+char   *s;
+{
+    if (vfp)
+       (*vfnx) (vfp, "%s", s);
+    else {
+       register char   c,
+                      *cp;
+
+       if (vps)
+               for (cp = s; *cp; cp++) {
+                   if (*cp == '\n' )
+                           (void) ps_write (vps, (PElementData) " ", 1);
+                   else
+                           (void) ps_write (vps, (PElementData) cp, 1);
+               }
+       else
+               for (cp = s; *cp; )
+                   *vbp++ = (c = *cp++) != '\n' ? c : ' ';
+    }
+}
+
+/* \f   VSTRING */
+
+vstring (pe)
+register PE    pe;
+{
+    register PE            p;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+       case PE_FORM_ICONS:
+           VPRINT (oct2str ((char *) pe -> pe_prim, (int) pe -> pe_len));
+           break;
+
+       case PE_FORM_CONS: 
+           vpush ();
+           for (p = pe -> pe_cons; p; p = p -> pe_next)
+               vstring (p);
+           vpop ();
+           break;
+    }
+}
+
+/* \f */
+
+static char   *oct2str (s, len)
+register char  *s;
+register int   len;
+{
+    int     ia5ok;
+    register int    k;
+    register char  *bp,
+                   *cp,
+                   *dp,
+                  *zp;
+
+    ia5ok = 1, k = 0;
+    for (dp = (cp = s) + len; cp < dp; cp++) {
+       switch (*cp) {
+           case ' ': 
+               continue;
+
+           case '"': 
+               break;
+
+           case '\b':
+           case '\f':
+           case '\n':
+           case '\r':
+           case '\t':
+           case '\\':
+               ia5ok = -1, k++;
+               continue;
+
+           case '-': 
+               if (cp > s && *(cp + 1) == '-')
+                   break;
+               continue;
+
+           default: 
+               if (iscntrl (*cp) || isspace (*cp) || (*cp & 0x80))
+                   break;
+               continue;
+       }
+       ia5ok = 0;
+       break;
+    }
+
+    switch (ia5ok) {
+       case 1: 
+           zp = newbuf (len + 2);
+           (void) sprintf (zp, "\"%*.*s\"", len, len, s);
+           break;
+
+       case -1: 
+           bp = zp = newbuf (len + k + 2);
+           *bp++ = '"';
+           for (cp = s; cp < dp; cp++)
+               if (*cp >= ' ' && *cp != '\\')
+                   *bp++ = *cp;
+               else {
+                   *bp++ = '\\';
+                   switch (*cp) {
+                       case '\b':
+                           *bp++ = 'b';
+                           break;
+                       case '\f':
+                           *bp++ = 'f';
+                           break;
+                       case '\n':
+                           *bp++ = 'n';
+                           break;
+                       case '\r':
+                           *bp++ = 'r';
+                           break;
+                       case '\t':
+                           *bp++ = 't';
+                           break;
+
+                       case '\\':
+                           *bp++ =  '\\';
+                           break;
+                   }
+               }
+           (void) sprintf (bp, "\"");
+           break;
+
+       case 0: 
+       default: 
+           bp = zp = newbuf (len * 2 + 3);
+           *bp++ = '\'';
+           for (cp = s; cp < dp; cp++) {
+               (void) sprintf (bp, "%02x", *cp & 0xff);
+               bp += strlen (bp);
+           }
+           (void) sprintf (bp, "'H");
+           break;
+    }
+
+    return zp;
+}
+
+/* \f */
+
+char   *bit2str (pe, s)
+PE     pe;
+char   *s;
+{
+    int     ia5ok;
+    register int    hit,
+                   i,
+                    j,
+                    k;
+    register char  *bp,
+                   *cp,
+                  *zp;
+
+    j = pe -> pe_nbits;
+    if ((cp = s) && *++cp) {
+       ia5ok = 1, hit = 0;
+       for (i = 0; i < j;)
+           if (bit_test (pe, i++) == 1) {
+               do {
+                   if (!(k = *cp++ & 0xff))
+                       break;
+                   if (k == i) {
+                       hit += hit ? 2 : 1;
+                       for (; *cp > ' '; cp++)
+                           hit++;
+                   }
+                   else
+                       for (; *cp > ' '; cp++)
+                           continue;
+               } while (k != 0 && k < i);
+               if (k == 0 || k > i) {
+                   ia5ok = 0;
+                   break;
+               }
+           }
+    }
+    else
+       ia5ok = 0;
+
+    if (ia5ok) {
+       bp = zp = newbuf (hit + 3);
+       *bp++ = '{';
+
+       cp = s, cp++;
+       for (i = hit = 0; i < j;)
+           if (bit_test (pe, i++) == 1) {
+               do {
+                   if (!(k = *cp++ & 0xff))
+                       break;
+                   if (k == i) {
+                       if (hit)
+                           *bp++ = ',';
+                       *bp++ = ' ';
+                       for (; *cp > ' '; cp++)
+                           *bp++ = *cp;
+                   }
+                   else
+                       for (; *cp > ' '; cp++)
+                           continue;
+               } while (k != 0 && k < i);
+               if (k == 0 || k > i)
+                   break;
+               hit++;
+           }
+
+       (void) sprintf (bp, "%s}", hit ? " " : "");
+    }
+    else {
+       bp = zp = newbuf (j + 3);
+       *bp++ = '\'';
+       for (i = 0; i < j; i++)
+           *bp++ = bit_test (pe, i) ? '1' : '0';
+       (void) sprintf (bp, "'B");
+    }
+
+    return zp;
+}
+
+/* \f */
+
+#ifdef vunknown
+#undef vunknown
+#endif
+
+vunknown (pe)
+register PE    pe;
+{
+    int     i;
+#ifdef notyet      /* could comment this in, but then all programs need -lm */
+    double  j;
+#endif
+    OID            oid;
+    register PE            p;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           switch (PE_ID (pe -> pe_class, pe -> pe_id)) {
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_BOOL): 
+                   if ((i = prim2flag (pe)) == NOTOK)
+                       goto bad_pe;
+                   VPRINT (i ? "TRUE" : "FALSE");
+                   break;
+
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_INT): 
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_ENUM): 
+                   if ((i = prim2num (pe)) == NOTOK
+                           && pe -> pe_errno != PE_ERR_NONE)
+                       goto bad_pe;
+                   vprint ("%d", i);
+                   break;
+
+#ifdef notyet
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_REAL): 
+                   if ((j = prim2real (pe)) == NOTOK
+                           && pe -> pe_errno != PE_ERR_NONE)
+                       goto bad_pe;
+                   vprint ("%g", j);
+                   break;
+#endif
+
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_BITS): 
+                   if ((p = prim2bit (pe)) == NULLPE)
+                       goto bad_pe;
+                   if (p -> pe_nbits < LOTSOFBITS) {
+                       VPRINT (bit2str (p, "\020"));
+                       break;
+                   }
+                   /* else fall... */
+
+               default: 
+           bad_pe: ;
+                   vtag ((int) pe -> pe_class, (int) pe -> pe_id);
+               /* fall */
+
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_OCTS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_IA5S): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_NUMS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_PRTS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_T61S): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_VTXS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_GENT): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_UTCT): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_GFXS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_VISS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_GENS): 
+               case PE_ID (PE_CLASS_UNIV, PE_DEFN_CHRS): 
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_ODE): 
+                   vstring (pe);
+                   break;
+
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_NULL):
+                   VPRINT ("NULL");
+                   break;
+
+               case PE_ID (PE_CLASS_UNIV, PE_PRIM_OID): 
+                   if ((oid = prim2oid (pe)) == NULLOID)
+                       goto bad_pe;
+                   VPRINT (oid2ode (oid));
+                   break;
+           }
+           break;
+
+       case PE_FORM_CONS: 
+           switch (PE_ID (pe -> pe_class, pe -> pe_id)) {
+               case PE_ID (PE_CLASS_UNIV, PE_CONS_SEQ):
+               case PE_ID (PE_CLASS_UNIV, PE_CONS_SET):
+                   break;
+
+               case PE_ID (PE_CLASS_UNIV, PE_CONS_EXTN):
+                   (void) print_UNIV_EXTERNAL (pe, 1, NULLIP, NULLVP,
+                                               NULLCP);
+                   return;
+
+               default:
+                   vtag ((int) pe -> pe_class, (int) pe -> pe_id);
+                   break;
+           }
+           vpush ();
+           for (p = pe -> pe_cons; p; p = p -> pe_next)
+               vunknown (p);
+           vpop ();
+           break;
+
+       case PE_FORM_ICONS:
+           vtag ((int) pe -> pe_class, (int) pe -> pe_id);
+           vstring (pe);
+           break;
+    }
+}
+
+/* \f   VPUSHFP/VPOPFP */
+
+vpushfp (fp, pe, s, rw)
+FILE   *fp;
+PE     pe;
+char   *s;
+int    rw;
+{
+    vpushpp ((caddr_t) fp, fprintf, pe, s, rw);
+}
+
+vsetfp (fp, s)
+FILE   * fp;
+char   * s;
+{
+    vfp = fp;
+    vfnx = (IFP) fprintf;
+
+    if(s != NULLCP)
+       (*vfnx) (vfp, "%s\n", s);
+
+    vlevel = didname = didvpush = didvpop = docomma = 0;
+}
+
+vpopfp ()
+{
+    (*vfnx) (vfp, "-------\n");
+    (void) fflush (vfp);
+
+    vpopp ();
+}
+
+/* \f   VPUSHSTR/VPOPSTR */
+
+vpushstr (cp)
+char   *cp;
+{
+    vfp = NULL;
+    vbp = vsp = cp;
+
+    vlevel = didname = didvpush = didvpop = docomma = 0;
+}
+
+
+vpopstr ()
+{
+    while (--vbp >= vsp)
+       if (*vbp != ' ')
+           break;
+    *++vbp = NULL;
+
+    vfp = stdout;
+}
+
+/* \f   VPUSHPP */
+
+vpushpp (pv, pfnx, pe, text, rw)
+caddr_t pv;
+IFP    pfnx;
+register PE    pe;
+char   *text;
+int    rw;
+{
+    vfp = (FILE *) pv, vfnx = pfnx;
+
+    (*vfnx) (vfp, "%s %s", rw ? "read" : "wrote", text ? text : "pdu");
+    if (pe -> pe_context != PE_DFLT_CTX)
+       (*vfnx) (vfp, ", context %d", pe -> pe_context);
+    (*vfnx) (vfp, "\n");
+
+    vlevel = didname = didvpush = didvpop = docomma = 0;
+}
+
+vpopp ()
+{
+    vfp = stdout, vfnx = (IFP) fprintf;
+}
+
+
+vpushquipu (ps)
+PS     ps;
+{
+    vps = ps;
+    vfp = NULL;
+
+    vlevel = didname = didvpush = didvpop = docomma = 0;
+}
+
+
+vpopquipu ()
+{
+       vpopp();
+       vps = NULLPS;
+}
+
+/* \f   PVPDU - for pepsy */
+
+#undef pvpdu
+
+pvpdu (lp, ind, mod, pe, text, rw)
+register LLog *lp;
+int    ind;            /* index into tables */
+modtyp *mod;           /* pointer to tables */
+register PE pe;
+char   *text;
+int    rw;
+{
+    register char   *bp;
+    char   buffer[BUFSIZ];
+
+    vfp = (FILE *) lp, vfnx = ll_printf;
+
+    bp = buffer;
+    (void) sprintf (bp, "%s %s", rw ? "read" : "wrote",
+                   text ? text : "pdu");
+    bp += strlen (bp);
+    if (pe -> pe_context != PE_DFLT_CTX) {
+       (void) sprintf (bp, ", context %d", pe -> pe_context);
+       bp += strlen (bp);
+    }
+    LLOG (lp, LLOG_ALL, ("%s", buffer));
+
+    vlevel = didname = didvpush = didvpop = docomma = 0;
+
+    if (mod == NULL)
+        (void) vunknown (pe);
+    else
+        (void) prnt_f (ind, mod, pe, 1, NULLIP, NULLVP);
+
+    (void) ll_printf (lp, "-------\n");
+
+    (void) ll_sync (lp);
+
+    vfp = stdout, vfnx = (IFP) fprintf;
+}
+
+/* \f   MISC */
+
+static char *bufp = NULL;
+
+static char *newbuf (i)
+int    i;
+{
+    static unsigned int len = 0;
+
+    if (i++ < len)
+       return bufp;
+
+    if (bufp)
+       free (bufp);
+    if ((bufp = malloc ((unsigned int) i)))
+       len = i;
+    else
+       len = 0;
+
+    return bufp;
+}
+/*  VPDU - support for backwards compatibility */
+
+_vpdu (lp, fnx, pe, text, rw)
+register LLog *lp;
+IFP    fnx;
+register PE pe;
+char   *text;
+int    rw;
+{
+    register char   *bp;
+    char   buffer[BUFSIZ];
+
+    vfp = (FILE *) lp, vfnx = ll_printf;
+
+    bp = buffer;
+    (void) sprintf (bp, "%s %s", rw ? "read" : "wrote",
+                   text ? text : "pdu");
+    bp += strlen (bp);
+    if (pe -> pe_context != PE_DFLT_CTX) {
+       (void) sprintf (bp, ", context %d", pe -> pe_context);
+       bp += strlen (bp);
+    }
+    LLOG (lp, LLOG_ALL, ("%s", buffer));
+
+    vlevel = didname = didvpush = didvpop = docomma = 0;
+
+    (void) (*fnx) (pe, 1, NULLIP, NULLVP, NULLCP);
+
+    (void) ll_printf (lp, "-------\n");
+
+    (void) ll_sync (lp);
+
+    vfp = stdout, vfnx = (IFP) fprintf;
+}
+
+#ifdef PEP_TEST
+free_bp()
+{
+    if (bufp)
+       free(bufp);
+}
+#endif
diff --git a/src/isode/pepsy/yacc.y.gnrc b/src/isode/pepsy/yacc.y.gnrc
new file mode 100644 (file)
index 0000000..21e14f9
--- /dev/null
@@ -0,0 +1,1643 @@
+/* yacc.y - yacc ASN.1 parser */
+/* %WARNING% */
+
+%{
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:31:58  eichin
+ * autoconfed isode for kerberos work
+ *
+# Revision 1.1  1994/05/31 20:40:55  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+ * Revision 8.0  91/07/17  12:43:20  isode
+ * Release 7.0
+ * 
+ * Revision 7.9  91/05/17  12:28:39  isode
+ * lint and include fixes
+ * 
+ * Revision 7.8  91/05/12  09:34:50  mrose
+ * svr4
+ * 
+ * Revision 7.7  91/02/22  09:50:19  mrose
+ * Interim 6.8
+ * 
+ * Revision 7.6  91/01/09  11:17:59  mrose
+ * pow
+ * 
+ * Revision 7.5  91/01/08  12:51:06  mrose
+ * update
+ * 
+ * Revision 7.4  90/12/23  18:42:15  mrose
+ * update
+ * 
+ * Revision 7.3  90/12/11  10:41:16  mrose
+ * sync
+ * 
+ * Revision 7.2  90/11/11  10:54:24  mrose
+ * update
+ * 
+ * Revision 7.1  90/11/04  19:17:31  mrose
+ * update
+ * 
+ * Revision 7.0  90/11/03  21:18:17  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 <ctype.h>
+%BEGIN(PEPSY)%
+#include "pepsydefs.h"
+%END(PEPSY)%
+%BEGIN(PEPY)%
+#include "pepy.h"
+%END(PEPY)%
+%BEGIN(ROSY)%
+#include "rosy-defs.h"
+%END(ROSY)%
+%BEGIN(MOSY)%
+#include "mosy-defs.h"
+%END(MOSY)%
+
+#define        YYSTYPE YYSTKTYPE
+
+
+#define        YYDEBUG 1
+
+extern int pepydebug;
+extern int doexternals;
+
+int    tagcontrol = TAG_UNKNOWN;
+static int     tagdefault;
+static int     listtype;
+static OID     modid;
+
+static int     yyporting = 0;
+
+typedef struct ypa {
+    char   *ya_text;
+    int            ya_lineno;
+}              ypa, *YA;
+#define        NULLYA  ((YA) 0)
+extern double pow ();
+
+%BEGIN(PEPSY)%
+/* encoding/decoding/printing/freeing functions */
+static char    *efn, *dfn, *pfn, *ffn;
+
+/*
+ * clear the ?fn variables for the next coding functions
+ */
+clrfn()
+{
+    if (efn) {
+       efn = NULLCP;
+    }
+    if (dfn) {
+       dfn = NULLCP;
+    }
+    if (pfn) {
+       pfn = NULLCP;
+    }
+    if (ffn) {
+       ffn = NULLCP;
+    }
+}
+
+%END(PEPSY)%
+
+static YA  new_action (text, lineno)
+char   *text;
+int    lineno;
+{
+    register YA            ya;
+
+    if ((ya = (YA) calloc (1, sizeof *ya)) == NULLYA)
+       yyerror ("out of memory");
+
+    ya -> ya_text = text;
+    ya -> ya_lineno = lineno;
+
+    return ya;
+}
+#define        free_action(ya) (void) free ((char *) (ya))
+
+typedef struct {
+    char *ys_structname;
+    char *ys_ptrname;
+} ysa, *YS;
+#define NULLYS ((YS) 0)
+
+static YS new_ys (str)
+char   *str;
+{
+    register YS        ys;
+    register char *p, *q;
+    char c;
+
+    if((ys = (YS) malloc (sizeof *ys)) == NULLYS)
+       yyerror ("out of memory");
+    q = str;
+    while (isspace (*q)) q++;
+    for (p = q; isalnum(*p) || *p == '_'; p++)
+       continue;
+    if (*p != '\0') {
+       c = *p;
+       *p = '\0';
+       ys -> ys_structname = new_string (q);
+       *p = c;
+    }
+    else {
+       ys -> ys_structname = new_string (q);
+       ys -> ys_ptrname = NULLCP;
+       free (str);
+       return ys;
+    }
+    for (q = p; *q != '$'; q++)
+       if (! *q) {
+           free (str);
+           ys -> ys_ptrname = NULLCP;
+           return ys;
+       }
+    q++;
+    while (isspace (*q)) q++;
+    for (p = q; isalnum(*p) || *p == '_'; p++)
+       continue;
+    *p = '\0';
+    ys -> ys_ptrname = new_string (q);
+    free (str);
+    return ys;
+}
+#define        free_ys(ys) (void) free ((char *) (ys))
+
+static int  final_actions = 0;
+static int  start_actions = 0;
+
+char   *
+hex2bin (s, pi)
+register char   *s;
+int    *pi;
+{
+    register char *d;
+    char       *start;
+    register int    c,
+                   i;
+
+
+    if ((d = malloc((unsigned)strlen(s)/2 + 2)) == NULLCP)
+       yyerror ("out of memory");
+    start = d;
+    for (i = 0; *s; i++) {
+       if ((c = *s++) >= 'a' && c <= 'f')
+           c -= 'a' - 0x0a;
+       else
+           if (c >= 'A' && c <= 'F')
+               c -= 'A' - 0x0a;
+           else
+               if (c >= '0' && c <= '9')
+                   c -= '0';
+               else
+                   c = 0;
+
+       if (i & 1)
+           *d++ |= c & 0xf;
+       else
+           *d = (c & 0xf) << 4;
+    }
+
+    *pi = i;   /* We use number semi-octets ! */
+    return start;
+}
+
+char   *
+bit2bin (s, pi)
+register char   *s;
+int    *pi;
+{
+    register char *d;
+    char       *start;
+    register int    c,
+                   shft,
+                   i;
+
+
+    if ((d = malloc((unsigned)strlen(s)/8 + 2)) == NULLCP)
+       yyerror ("out of memory");
+    start = d;
+    *d = 0;
+    for (i = 0; *s; i++) {
+       if ((c = *s++) == '1')
+           c = 1;
+       else if (c == '0')
+           c = 0;
+       else
+           break;      /* ?? */
+
+       shft = 7 - i % 8;       /* shift to get to its bit */
+       *d |= c << shft;
+       if (shft == 0)  /* last bit in this octet so goto next octet */
+           *++d = 0;   /* initialise it to zero */
+    }
+
+    *pi = i;
+    return start;
+}
+
+bin2hex (s, d, len)
+register    u_char *s;
+register char  *d;
+int     len;
+{
+    register int    i,
+                   g;
+
+    for (i = 0; i < len; i++) {
+       g = s[i >> 1];
+       if ((i & 1) == 0)
+           g >>= 4;
+       g &= 0xf;
+
+       if (g < 0x0a)
+           *d++ = g + '0';
+       else
+           *d++ = g + 'a' - 0x0a;
+    }
+
+    *d = NULL;
+
+    return len;
+}
+
+int
+hex2int(s)
+register char  *s;
+{
+    register int       sum = 0;
+    register int               i;
+
+    while (*s) {
+       if (!isxdigit(*s))
+           break;
+       if (isdigit(*s))
+           i = *s - '0';
+       else
+           i = tolower(*s) - 'a' + 10;
+       sum = sum << 4 + i;
+       s++;
+    }
+
+    return (sum);
+}
+
+int
+bit2int(s)
+register char  *s;
+{
+    register int       sum = 0;
+
+    while (*s) {
+       if (*s != '0' && *s != '1')
+           break;
+       if (*s == '1')
+           sum <<= 1;
+       else
+           sum = sum << 1 + 1;
+       s++;
+    }
+    return (sum);
+}
+
+%}
+
+%start ModuleDefinition
+
+
+%union {
+    int            yy_number;
+    char   *yy_string;
+    YP     yy_type;
+    YV     yy_value;
+    YT     yy_tag;
+    YA     yy_action;
+    OID            yy_oid;
+    YS     yy_sctrl;
+    double  yy_real;
+%BEGIN(PEPSY)%
+    YFN     yy_yfn;
+    YAL     yy_yal;
+%END(PEPSY)%
+}
+
+
+%token  ABSENT ACTION ANY APPLICATION BAR BGIN BIT BITSTRING BOOLEAN
+       BSTRING BY CCE CHOICE COMMA COMPONENT COMPONENTS COMPONENTSOF
+       CONTROL DEC_FN DECODER DEFAULT DEFINED DEFINITIONS DOT DOTDOT
+       DOTDOTDOT ENC_FN ENCODER ENCRYPTED END ENUMERATED EXPORTS
+       EXPLICIT FALSE FRE_FN FROM HSTRING ID IDENTIFIER IMPLICIT
+       IMPORTS INCLUDES INTEGER LANGLE LBRACE LBRACKET LITNUMBER
+       LITSTRING LPAREN MIN MINUS MAX NAME NIL OBJECT OCTET
+       OCTETSTRING OF OPTIONAL PARAMETERTYPE PLUS PREFIXES PRESENT
+       PRINTER PRIVATE PRT_FN RBRACE RBRACKET REAL RPAREN STAR
+       SECTIONS SEMICOLON SEQUENCE SEQUENCEOF SET SETOF SIZE STRING
+       TAGS TRUE UNIVERSAL VALA VALB VALI VALS VALP VALO VALOID VALR
+       VALT VALTYPE VALQ VALX VLENGTH WITH SCTRL PLUSINFINITY
+       MINUSINFINITY
+%BEGIN(ROSY)%
+        OPERATION ARGUMENT RESULT ERRORS LINKED ERROR PARAMETER
+/* new stuff */
+       ABSTRACT OPERATIONS CONSUMER SUPPLIER INVOKES PORT PORTS
+       OBJECTCONSUMER OBJECTSUPPLIER REFINE AS RECURRING VISIBLE
+       PAIRED BIND UNBIND
+/* end new stuff */
+%END(ROSY)%
+%BEGIN(MOSY)%
+       OBJECTYPE SYNTAX ACCESS STATUS
+%END(MOSY)%
+%BEGIN(PEPSY)%
+       EACTION DACTION PACTION ECHOICE DCHOICE PCHOICE
+%END(PEPSY)%
+
+%type  <yy_number>     LITNUMBER 
+%type  <yy_number>     ABSENT ANY BGIN APPLICATION BIT BITSTRING
+                       BOOLEAN CHOICE COMPONENT COMPONENTS COMPONENTSOF
+                       DECODER DEFAULT DEFINED DEFINITIONS ENCODER 
+                       ENCRYPTED END ENUMERATED EXPLICIT EXPORTS
+                       FALSE FROM IDENTIFIER IMPLICIT IMPORTS INCLUDES
+                       INTEGER MIN MAX NIL OBJECT OCTET OCTETSTRING
+                       OF OPTIONAL PREFIXES PRESENT PRINTER PRIVATE REAL
+                       SECTIONS SEQUENCE SEQUENCEOF SET STRING TAGS
+                       TRUE UNIVERSAL WITH PLUSINFINITY MINUSINFINITY
+                       AnyType
+%type  <yy_real>       RealValue NumericRealValue SpecialRealValue
+%type   <yy_string>     DEC_FN ENC_FN PRT_FN FRE_FN ID NAME LITSTRING
+                       BSTRING HSTRING VALA VALB VALI VALS VALP VALQ
+                       VALR VALT VALTYPE VALO VALX VLENGTH VALOID
+                       CONTROL PARAMETERTYPE ParameterType Control
+                       ValParameter String PassInt PassBool PassOid
+                       PassAny PassReal ModuleIdentifier Symbol
+                       SymbolList SCTRL
+%type   <yy_type>       Type BuiltinType DefinedType PassValue PassBit
+                       PassString NullPass ElementTypes
+                       OptionalTypeList OptionalType NamedType
+                       ComponentsOf AlternativeTypeList MemberTypes
+                       SubType Valtype
+%BEGIN(ROSY)%
+                       Argument Result Parameter
+%END(ROSY)%
+%type   <yy_value>      NamedNumberList NamedNumber
+NumericValue
+                       Value BuiltinValue DefinedValue IdentifierList
+                       Values NamedValueList NamedValue NNlist
+%BEGIN(ROSY)%
+                       Errors ErrorNames LinkedOperations
+                       LinkedOperationNames
+%END(ROSY)%
+%BEGIN(MOSY)%
+                       ObjectID ObjectIDComponentList ObjectSubID
+%END(MOSY)%
+%BEGIN(PEPSY)%
+%type   <yy_yfn>        CodingFn
+%type   <yy_yal>        UAction CAction
+%type   <yy_action>    EACTION DACTION PACTION ECHOICE DCHOICE PCHOICE
+%END(PEPSY)%
+%type   <yy_tag>        Tag Class
+%type   <yy_action>     ACTION
+%type   <yy_oid>        ObjIdComponentList ObjectIdentifierValue
+                       ObjIdComponent NumberForm NameAndNumberForm
+%type   <yy_sctrl>      Sctrl
+%%
+
+ModuleDefinition:      ModuleIdentifier DEFINITIONS TagDefault CCE
+                               {
+                                   mymodule = $1;
+                                   mymoduleid = modid;
+                                   pass1 ();
+                               }
+                       ModuleActions ModulePrefixes { start_actions++; }
+                       BGIN ModuleBody END
+                       ModuleActions { pass2 (); final_actions++; }
+       ;
+
+TagDefault:            EXPLICIT TAGS { 
+                           tagdefault = 0;
+                           tagcontrol = TAG_EXPLICIT;
+                       }
+       |               IMPLICIT TAGS {
+                           tagdefault = YP_IMPLICIT;
+                           tagcontrol = TAG_IMPLICIT;
+                       }
+       |               empty {
+                           tagdefault = 0;
+                           tagcontrol = TAG_UNKNOWN;
+                       }
+       ;
+
+ModuleIdentifier:      ID AssignedIdentifier { $$ = $1; }
+       ;
+
+AssignedIdentifier:    ObjectIdentifierValue { modid = $1; }
+       |               empty
+       ;
+
+ModuleActions:         ACTION {
+%BEGIN(PEPSY)%
+                               { Action a;
+
+                                 a = new_action_t($1 -> ya_text,
+                                                  $1 -> ya_lineno,
+                                                  0);
+                                   if (start_actions)
+                                       final_action =  a;
+                                   else
+                                       start_action = a;
+                                   free_action ($1);
+                                   break;
+                                   /*NOTREACHED*/
+                               }
+%END(PEPSY)%
+                       /*
+%BEGIN(PEPY)%
+                           if (bflag) {
+                               if (final_actions) 
+                                   init_new_file ();
+                               else {
+                                   module_actions = $1 -> ya_text;
+                                   free_action ($1);
+                                   break;
+                               }
+                           }
+%END(PEPY)%
+                           if (!dflag) {
+                               if (Cflag > 0) {
+                                   if (!Pflag && *sysin)
+                                       (void) printf ("# line %d \"%s\"\n",
+                                               $1 -> ya_lineno, sysin);
+                                   fputs ($1 -> ya_text, stdout);
+                               }
+                               else {
+                                   (void) printf ("%%{\n#include \"%s-types.h\"\n",
+                                           mymodule);
+                                   (void) printf ("%s%%}\n", $1 -> ya_text);
+                                   Cflag = -1;
+                               }
+                           }
+                           free_action ($1);
+%BEGIN(PEPY)%
+                           if (bflag)
+                               end_file ();
+%END(PEPY)%
+                   */
+                       }
+       |               empty
+       ;
+ModulePrefixes:
+                       PREFIXES String String String
+                       {
+                           yyencdflt = $2;
+                           yydecdflt = $3;
+                           yyprfdflt = $4;
+                       }
+       |               empty
+       ;
+ModuleBody:            Exports Imports AssignmentList
+       ;
+
+Exports:               EXPORTS  { listtype = TBL_EXPORT; doexternals = 0;
+                                  yyporting = 1; }
+                                SymbolsExported SEMICOLON {
+                           yyporting = 0;
+                           if (mymoduleid == NULLOID)
+                               warning ("EXPORTS but no ModuleIdentifier");
+                               
+                       }
+       |               empty
+       ;
+
+SymbolsExported:       SymbolList
+       |               empty
+       ;
+
+Imports:               IMPORTS  { listtype = TBL_IMPORT; yyporting = 1; }
+                                SymbolsImported SEMICOLON {
+                           yyporting = 0;
+                           if (mymoduleid == NULLOID)
+                               warning ("IMPORTS but no ModuleIdentifier");
+                       }
+
+       |               empty
+       ;
+
+SymbolsImported:       SymbolsFromModuleList
+       |               empty
+       ;
+
+SymbolsFromModuleList: SymbolsFromModuleList SymbolsFromModule
+       |               SymbolsFromModule
+       ;
+
+SymbolsFromModule:     SymbolList FROM ModuleIdentifier
+                               {
+                                   addtableref ($3, modid, listtype);
+                               }
+       ;
+
+SymbolList:            SymbolList COMMA Symbol {
+                           addtable($3, listtype, ER_UNKNOWN);
+                       }
+       |               Symbol { addtable ($1, listtype, ER_UNKNOWN); }
+
+       |               SymbolList COMMA MINUS Symbol {
+                           addtable($4, listtype, ER_NORMAL);
+                       }
+       |               MINUS Symbol { addtable ($2, listtype, ER_NORMAL); }
+
+       |               SymbolList COMMA PLUS Symbol {
+                           addtable($4, listtype, ER_EXPLICIT);
+                       }
+       |               PLUS Symbol { addtable ($2, listtype, ER_EXPLICIT); }
+       ;
+
+Symbol:                        ID
+       |               NAME
+       ;
+
+AssignmentList:                AssignmentList Section Assignment
+       |               empty
+       ;
+
+Section:               ENCODER String
+                       { yysection = YP_ENCODER; yyencpref = $2;
+                         yyprint (NULLCP, 0, 1); }
+       |               DECODER String
+                       { yysection = YP_DECODER; yydecpref = $2;
+                         yyprint (NULLCP, 0, 1); }
+       |               PRINTER String
+                       { yysection = YP_PRINTER; yyprfpref = $2;
+                         yyprint (NULLCP, 0, 1); }
+       |               SECTIONS String String String
+                       {
+                           yysection = NULL;
+                           if (strcmp (yyencpref = $2, "none"))
+                               yysection |= YP_ENCODER;
+                           if (strcmp (yydecpref = $3, "none"))
+                               yysection |= YP_DECODER;
+                           if (strcmp (yyprfpref = $4, "none"))
+                               yysection |= YP_PRINTER;
+                           yyprint (NULLCP, 0, 1); 
+                       }
+       |               empty
+       ;
+
+String:                        ID { $$ = $1; }
+       |               NAME { $$ = $1; }
+       ;
+
+Assignment:            Typeassignment
+%BEGIN(ROSY)%
+       |               OperationDefinition
+       |               ErrorDefinition
+/* new stuff */
+       |               PortDefinition
+       |               ObjectDefinition
+/*     |               RefineDefinition        -- impossible!!!! (JPO) */
+/*     |               BindDefinition          -- lacking defs... */
+/*     |               UnBindDefinition        -- ditto */
+/* end new stuff */
+%END(ROSY)%
+%BEGIN(MOSY)%
+       |               ObjectTypeDefinition
+       |               ObjectIDefinition
+%END(MOSY)%
+       |               Valueassignment
+       ;
+
+%BEGIN(ROSY)%
+OperationDefinition:   NAME OPERATION Argument Result Errors LinkedOperations
+                       CCE LITNUMBER {
+                           pass1_op (mymodule, $1, $3, $4, $5, $6, $8);
+                       }
+       ;
+
+Argument:              ARGUMENT NamedType { $$ = $2; }
+       |               empty { $$ = NULLYP; }
+       ;
+
+Result:                        RESULT NamedType { $$ = $2; }
+       |               empty { $$ = NULLYP; }
+       ;
+
+Errors:                        ERRORS LBRACE ErrorNames RBRACE { $$ = $3; }
+       |               empty { $$ = NULLYV; }
+
+LinkedOperations:      LINKED LBRACE LinkedOperationNames RBRACE { $$ = $3; }
+       |               empty { $$ = NULLYV; }
+    
+
+ErrorNames:            NamedValueList {
+                           $$ = new_value (YV_VALIST);
+                           $$ -> yv_idlist = $1;
+                       }
+       |               empty { $$ = NULLYV; }
+
+
+LinkedOperationNames:  NamedValueList {
+                           $$ = new_value (YV_VALIST);
+                           $$ -> yv_idlist = $1;
+                       }
+       |               empty { $$ = NULLYV; }
+
+
+ErrorDefinition:       NAME ERROR Parameter CCE LITNUMBER {
+                           pass1_err (mymodule, $1, $3, $5);
+                       }
+       ;
+
+Parameter:             PARAMETER NamedType { $$ = $2; }
+       |               empty { $$ = NULLYP; }
+       ;
+
+/* new stuff start */
+PortDefinition:                NAME PORT PortOperations CCE PortValue
+       ;
+
+PortValue:             ObjectIdentifierValue
+       |               NAME
+       ;
+
+PortOperations:                PortSymmetrical
+       |               PortAsymetrical
+       |               empty
+
+PortSymmetrical:       ABSTRACT OPERATIONS LBRACE PortOperationList RBRACE
+       ;
+
+PortAsymetrical:       PortOneSided
+       |               PortTwoSided
+       ;
+
+PortOneSided:          PortConsumer
+       |               PortSupplier
+       ;
+
+PortTwoSided:          PortConsumer PortSupplier
+       |               PortSupplier PortConsumer
+       ;
+
+PortConsumer:          CONSUMER INVOKES LBRACE PortOperationList RBRACE
+       ;
+
+PortSupplier:          SUPPLIER INVOKES LBRACE PortOperationList RBRACE
+       ;
+
+PortOperationList:     OperationValue
+       |               OperationValue COMMA PortOperationList
+       ;
+
+OperationValue:                NAME
+       |               ID
+       |               LITNUMBER
+       |               ObjectIdentifierValue
+       ;
+
+ObjectDefinition:      NAME OBJECT ObjectType CCE PortValue
+       ;
+
+ObjectType:            PORTS LBRACE ObjectPortList RBRACE
+       |               empty
+       ;
+
+ObjectPortList:                ObjectPort COMMA ObjectPortList
+       |               ObjectPort
+       ;
+
+ObjectPort:            PortValue ObjectPortType
+       ;
+
+ObjectPortType:                ObjectSymetric
+       |               ObjectAsymetric
+       ;
+
+ObjectSymetric:                empty
+       ;
+
+ObjectAsymetric:       OBJECTCONSUMER
+       |               OBJECTSUPPLIER
+       ;
+
+/* New stuff end */
+%END(ROSY)%
+
+%BEGIN(MOSY)%
+ObjectTypeDefinition:  NAME OBJECTYPE SYNTAX NamedType ACCESS NAME
+                       STATUS NAME CCE ObjectID {
+                           pass1_obj (mymodule, $1, $4, $10, $6, $8);
+                       }
+       ;
+
+ObjectIDefinition:     NAME OBJECT IDENTIFIER CCE ObjectID {
+                           pass1_oid (mymodule, $1, $5);
+                       }
+       ;
+
+ObjectID:              NAME {
+                           $$ = new_value (YV_OIDLIST);
+                           $$ -> yv_idlist = new_value (YV_IDEFINED);
+                           $$ -> yv_idlist -> yv_identifier = $1;
+                           $$ -> yv_idlist -> yv_flags |= YV_BOUND;
+                       }
+       |               LBRACE ObjectIDComponentList RBRACE {
+                           $$ = new_value (YV_OIDLIST);
+                           $$ -> yv_idlist = $2;
+                       }
+       ;
+ObjectIDComponentList: ObjectSubID { $$ = $1; }
+       |               ObjectIDComponentList ObjectSubID {
+                           $$ = add_value ($1, $2);
+                       }
+       ;
+ObjectSubID:           LITNUMBER {
+                           $$ = new_value (YV_NUMBER);
+                           $$ -> yv_number = $1;
+                       }
+       |               NAME {
+                           $$ = new_value (YV_IDEFINED);
+                           $$ -> yv_identifier = $1;
+                           $$ -> yv_flags |= YV_BOUND;
+                       }
+       |               NAME LPAREN LITNUMBER RPAREN {
+                           $$ = new_value (YV_NUMBER);
+                           $$ -> yv_number = $3;
+                           $$ -> yv_named = $1;
+                           $$ -> yv_flags |= YV_NAMED;
+                       }
+       ;
+%END(MOSY)%
+%BEGIN(PEPSY)%
+UAction:               UAction EACTION {
+                           if ($1 == NULLYAL)
+                               $$ = new_yal();
+                           else
+                               $$ = $1;
+                           if ($$->yal_enc)
+                               yyerror("multiple encoding actions at the one place\n");
+                           $$->yal_enc = new_action_t($2->ya_text,
+                               $2->ya_lineno, e_actions++);
+                       }
+       |               UAction DACTION {
+                           if ($1 == NULLYAL)
+                               $$ = new_yal();
+                           else
+                               $$ = $1;
+                           if ($$->yal_dec)
+                               yyerror("multiple decoding actions at the one place\n");
+                           $$->yal_dec = new_action_t($2->ya_text, $2->ya_lineno, d_actions++);
+                       }
+       |               UAction PACTION {
+                           if ($1 == NULLYAL)
+                               $$ = new_yal();
+                           else
+                               $$ = $1;
+                           if ($$->yal_prn)
+                               yyerror("multiple printing actions at the one place\n");
+                           $$->yal_prn = new_action_t($2->ya_text, $2->ya_lineno, p_actions++);
+                       }
+       |               empty
+                       { $$ = NULLYAL; }
+       ;
+
+CAction:               CAction ECHOICE {
+                           if ($1 == NULLYAL)
+                               $$ = new_yal();
+                           else
+                               $$ = $1;
+                           if ($$->yal_enc)
+                               yyerror("multiple choice encoding actions at the one place\n");
+                           $$->yal_enc = new_action_t($2->ya_text,
+                               $2->ya_lineno, e_actions++);
+                       }
+       |               CAction DCHOICE {
+                           if ($1 == NULLYAL)
+                               $$ = new_yal();
+                           else
+                               $$ = $1;
+                           if ($$->yal_dec)
+                               yyerror("multiple choice decoding actions at the one place\n");
+                           $$->yal_dec = new_action_t($2->ya_text, $2->ya_lineno, d_actions ++);
+                       }
+       |               CAction PCHOICE {
+                           if ($1 == NULLYAL)
+                               $$ = new_yal();
+                           else
+                               $$ = $1;
+                           if ($$->yal_prn)
+                               yyerror("multiple choice printing actions at the one place\n");
+                           $$->yal_prn = new_action_t($2->ya_text, $2->ya_lineno, 0);
+                       }
+       |               empty
+                       { $$ = NULLYAL; }
+       ;
+
+%END(PEPSY)%
+
+Typeassignment:                ID ParameterType CCE UAction Type {
+                           if ($2)
+                               $5 -> yp_param_type = $2;
+                           if ($4)
+                               $5->yp_bef_alist=yal_join($4, $5->yp_bef_alist);
+                           pass1_type (yyencpref, yydecpref, yyprfpref,
+                                   mymodule, $1, $5);
+                       } ;
+
+Type:                  BuiltinType CodingFn UAction {
+                           $$ = $1;
+                           $$ -> yp_direction = yysection;
+                           if ($2)
+                               $$->yp_yfn = join_yfn($$->yp_yfn, $2);
+                           if ($3)
+                               $$->yp_aft_alist=yal_join($3, $$->yp_aft_alist);
+                       }
+       |               DefinedType CodingFn UAction {
+                           $$ = $1;
+                           $$ -> yp_direction = yysection;
+                           if ($2)
+                               $$->yp_yfn = join_yfn($$->yp_yfn, $2);
+                           if ($3)
+                               $$->yp_aft_alist=yal_join($3, $$->yp_aft_alist);
+                       }
+       |               SubType CodingFn UAction {
+                           $$ = $1;
+                           $$ -> yp_direction = yysection;
+                           if ($2)
+                               $$->yp_yfn = join_yfn($$->yp_yfn, $2);
+                           if ($3)
+                               $$->yp_aft_alist=yal_join($3, $$->yp_aft_alist);
+                       }
+       ;
+
+
+Control:               CONTROL
+       |               empty { $$ = NULLCP; }
+       ;
+
+ParameterType:         PARAMETERTYPE
+       |               empty { $$ = NULLCP; }
+       ;
+
+Valtype:               VALTYPE {
+                           $$ = new_type(YP_UNDF, -1);
+                           if (setvaltype($$, $1) == 0)
+                               yyerror("syntax error in [[ T ... ]]");
+                           free($1);
+                       }
+       |               empty { $$ = new_type(YP_UNDF, -1); }
+       ;
+
+BuiltinType:           BOOLEAN PassBool {
+                           $$ = new_type (YP_BOOL, $1);
+                           $$ -> yp_intexp = $2;
+                       }
+       |               INTEGER PassInt NNlist {
+                           $$ = new_type ($3 ? YP_INTLIST : YP_INT, $1);
+                           $$ -> yp_intexp = $2;
+                           if ($3)
+                                   $$ -> yp_value = $3;
+                       }
+       |               ENUMERATED PassInt LBRACE NamedNumberList
+                           RBRACE {
+                           $$ = new_type (YP_ENUMLIST, $1);
+                           $$ -> yp_intexp = $2;
+                           $$ -> yp_value = $4;
+                       }
+
+       |               Bitstring PassBit NNlist {
+                           $$ = $2;
+                           $$ -> yp_code = $3 ? YP_BITLIST: YP_BIT;
+                           if ($3)
+                               $$ -> yp_value = $3;
+                       }
+       |               Octetstring PassString {
+                           $$ = $2;
+                           $$ -> yp_code = YP_OCT;
+                       }
+       |               NIL {
+                           $$ = new_type (YP_NULL, $1);
+                       }
+       |               SEQUENCE Sctrl PassAny {
+                           $$ = new_type (YP_SEQ, $1);
+                           $$ -> yp_strexp = $3;
+                       }
+       |               SequenceOf Sctrl Valtype Control UAction Type {
+                           $$ = $3;
+                           $$->yp_code = YP_SEQTYPE;
+                           $$ -> yp_type = $6;
+                           if ($2) {
+                               $$ -> yp_structname = $2 -> ys_structname;
+                               $$ -> yp_ptrname = $2 -> ys_ptrname;
+                               free_ys ($2);
+                           }
+                           if ($4) {
+                               $$ -> yp_control = $4;
+                               $$ -> yp_flags |= YP_CONTROLLED;
+                           }
+                           if ($5)
+                               $6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
+                       }
+       |       SEQUENCE Sctrl Valtype LBRACE UAction ElementTypes RBRACE {
+                           $$ = $3;
+                           $$->yp_code = YP_SEQLIST;
+                           $$ -> yp_type = $6;
+                           if ($2) {
+                                $$ -> yp_structname = $2 -> ys_structname;
+                                $$ -> yp_ptrname = $2 -> ys_ptrname;
+                                free_ys ($2);
+                            }
+                           if ($6 && $5)
+                               $6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
+                       }
+       |               SET Sctrl PassAny {
+                           $$ = new_type (YP_SET, $1);
+                           $$ -> yp_strexp = $3;
+                       }
+       |               SetOf Sctrl Valtype Control UAction Type {
+                           $$ = $3;
+                           $$->yp_code = YP_SETTYPE;
+                           $$ -> yp_type = $6;
+                           if ($2) {
+                               $$ -> yp_structname = $2 -> ys_structname;
+                               $$ -> yp_ptrname = $2 -> ys_ptrname;
+                               free_ys ($2);
+                           }
+                           if ($4) {
+                               $$ -> yp_control = $4;
+                               $$ -> yp_flags |= YP_CONTROLLED;
+                           }
+                           if ($5)
+                               $6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
+                       }
+
+       |               SET Sctrl Valtype LBRACE UAction MemberTypes RBRACE {
+                           $$ = $3;
+                           $$->yp_code = YP_SETLIST;
+                           $$ -> yp_type = $6;
+                           if ($2) {
+                               $$ -> yp_structname = $2 -> ys_structname;
+                               $$ -> yp_ptrname = $2 -> ys_ptrname;
+                               free_ys ($2);
+                           }
+                           if ($6 && $5)
+                               $6->yp_bef_alist=yal_join($5, $6->yp_bef_alist);
+                       }
+       |               Tag UAction IMPLICIT Type {
+                           $$ = $4;
+                           $$ -> yp_tag = $1;
+                           $$ -> yp_flags |= (YP_IMPLICIT | YP_TAG);
+                           if ($2)
+                               $$->yp_bef_alist=yal_join($2, $$->yp_bef_alist);
+                       }
+       |               Tag UAction EXPLICIT Type {
+                           $$ = $4;
+                           $$ -> yp_tag = $1;
+                           $$ -> yp_flags |= YP_TAG;
+                           if ($2)
+                               $$->yp_bef_alist=yal_join($2, $$->yp_bef_alist);
+                       }
+       |               Tag UAction Type {
+                           $$ = $3;
+                           $$ -> yp_tag = $1;
+                           $$ -> yp_flags |= (YP_TAG| tagdefault);
+                           if ($2)
+                               $$->yp_bef_alist=yal_join($2, $$->yp_bef_alist);
+                       }
+       |               CHOICE Sctrl Valtype Control CAction LBRACE UAction
+                                       AlternativeTypeList RBRACE {
+                           $$ = $3;
+                           $$->yp_code = YP_CHOICE;
+                           $$ -> yp_type = $8;
+                           if ($2) {
+                               $$ -> yp_structname = $2 -> ys_structname;
+                               $$ -> yp_ptrname = $2 -> ys_ptrname;
+                               free_ys ($2);
+                           }
+                           if ($4) {
+                               $$ -> yp_control = $4;
+                               $$ -> yp_flags |= YP_CONTROLLED;
+                           }
+                           if ($5)
+                               $$ -> yp_control_act = $5;
+                           if ($8 && $7)
+                               $8->yp_bef_alist=yal_join($7, $8->yp_bef_alist);
+                       }
+       |               NAME LANGLE Type {
+                           $$ = $3;
+                           $$ -> yp_bound = $1;
+                           $$ -> yp_flags |= YP_BOUND;
+                       }
+       |               AnyType PassAny {
+                           $$ = new_type (YP_ANY, $1);
+                           $$ -> yp_strexp = $2;
+                       }
+       |               STAR AnyType PassAny {
+                           $$ = new_type (YP_ANY, $2);
+                           $$ -> yp_strexp = $3;
+                           $$ -> yp_flags |= YP_WANTIMPLICIT;
+                       }
+       |               OBJECT IDENTIFIER PassOid {
+                           $$ = new_type (YP_OID, $1);
+                           $$ -> yp_strexp = $3;
+                       }
+       |               ENCRYPTED Type {
+                           $$ = $2;
+                           $$ -> yp_tag = new_tag (PE_CLASS_UNIV);
+                           $$ -> yp_tag -> yt_value = new_value(YV_NUMBER);
+                           $$ -> yp_tag -> yt_value -> yv_number = PE_PRIM_ENCR;
+                           $$ -> yp_flags |=
+                               (YP_ENCRYPTED | YP_TAG | YP_IMPLICIT);
+                       }
+       |               REAL PassReal {
+                           $$ = new_type(YP_REAL, $1);
+                           $$ -> yp_strexp = $2;
+                       }
+       ;
+
+NNlist:                        LBRACE NamedNumberList RBRACE { $$ = $2; }
+       |               empty { $$ = NULL; }
+       ;
+DefinedType:           ID PassValue ValParameter {
+                           $$ = $2;
+                           $$ -> yp_code = YP_IDEFINED;
+                           $$ -> yp_identifier = $1;
+                           if ($3) {
+                               $$ -> yp_parm = $3;
+                               $$ -> yp_flags |= YP_PARMVAL;
+                           }
+%BEGIN(ROSY)%
+#ifndef        lint
+%END(ROSY)%
+                           check_impexp ($$);
+%BEGIN(ROSY)%
+#endif
+%END(ROSY)%
+                       }
+       |               ID DOT ID PassValue ValParameter {
+                           $$ = $4;
+                           $$ -> yp_code = YP_IDEFINED;
+                           $$ -> yp_identifier = $3;
+                           $$ -> yp_module = $1;
+                           if ($5) {
+                               $$ -> yp_parm = $5;
+                               $$ -> yp_flags |= YP_PARMVAL;
+                           }
+                       }
+       ;
+
+PassValue:             VALA {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = NULLCP;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 'a';
+                       }
+       |               VALB {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $1;
+                           $$ -> yp_strexp = NULLCP;
+                           $$ -> yp_prfexp = 'b';
+                       }
+       |               VALI {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $1;
+                           $$ -> yp_strexp = NULLCP;
+                           $$ -> yp_prfexp = 'i';
+                       }
+       |               VALX VLENGTH {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $2;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 'x';
+                       }
+       |               VALOID {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = NULLCP;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 'O';
+                       }
+       |               VALR  {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = NULLCP;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 'r';
+                       }
+       |               VALT  {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $1;
+                           $$ -> yp_prfexp = 't';
+                       }
+       |               PassString
+       ;
+
+AnyType:               ANY
+       |               ANY DEFINED BY NAME
+       ;
+                       
+PassOid:               VALOID
+       |               empty { $$ = NULLCP; }
+       ;
+
+PassAny:               VALA
+       |               empty { $$ = NULLCP; }
+       ;
+
+PassBool:              VALB
+       |               empty { $$ = NULLCP; }
+       ;
+
+PassInt:               VALI
+       |               empty { $$ = NULLCP; }
+       ;
+
+PassBit:               VALX VLENGTH {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $2;
+                           $$ -> yp_strexp = $1;
+                       }
+       |               VALT {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $1;
+                           $$ -> yp_strexp = NULLCP;
+                       }
+       |               NullPass
+       ;
+
+PassString:            VALS {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = NULLCP;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 's';
+                       }
+       |               VALO VLENGTH {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = $2;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 'o';
+                       }
+       |               VALQ {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = NULLCP;
+                           $$ -> yp_strexp = $1;
+                           $$ -> yp_prfexp = 'q';
+                       }
+       |               NullPass
+       ;
+
+PassReal:              VALR 
+       |               empty { $$ = NULLCP; }
+       ;
+
+NullPass:              empty {
+                           $$ = new_type (YP_UNDF, -1);
+                           $$ -> yp_intexp = NULLCP;
+                           $$ -> yp_strexp = NULLCP;
+                       }
+       ;
+
+CodingFn:              fnlist {
+                           $$ = new_yfn(efn, dfn, pfn, ffn);
+                           clrfn();
+                       }
+       |               { $$ = NULLYFN; }
+       ;
+
+fn:            ENC_FN  {
+                   if (efn)
+                       myyerror("extra encoding function %s ignored\n", $1);
+                   else
+                       efn = $1;
+               }
+       |       DEC_FN {
+                   if (dfn)
+                       myyerror("extra decoding function %s ignored\n", $1);
+                   else
+                       dfn = $1;
+               }
+       |       PRT_FN {
+                   if (pfn)
+                       myyerror("extra printing function %s ignored\n", $1);
+                   else
+                       pfn = $1;
+               }
+       |       FRE_FN {
+                   if (ffn)
+                       myyerror("extra freeing function %s ignored\n", $1);
+                   else
+                       ffn = $1;
+               }
+       ;
+
+fnlist:                fn
+       |       fnlist fn
+
+ValParameter:          VALP
+       |               empty { $$ = NULLCP; }
+       ;
+
+NamedNumberList:       NamedNumber { $$ = $1; }
+       |               NamedNumberList COMMA NamedNumber {
+                           $$ = add_value ($1, $3);
+                       }
+       ;
+NamedNumber:           NAME LPAREN NumericValue RPAREN {
+                           $$ = $3;
+                           $$ -> yv_named = $1;
+                           $$ -> yv_flags |= YV_NAMED;
+                       }
+       ;
+NumericValue:          LITNUMBER {
+                           $$ = new_value (YV_NUMBER);
+                           $$ -> yv_number = $1;
+                       }
+       |               DefinedValue
+       ;
+
+ElementTypes:          OptionalTypeList { $$ = $1; }
+       |               empty { $$ = NULLYP; }
+       ;
+MemberTypes:           OptionalTypeList { $$ = $1; }
+
+       |               empty { $$ = NULLYP; }
+       ;
+OptionalTypeList:      OptionalType { $$ = $1; }
+       |               OptionalTypeList COMMA UAction OptionalType {
+                           if ($3)
+                               $4->yp_bef_alist=yal_join($3, $4->yp_bef_alist);
+                           $$ = add_type ($1, $4);
+                       }
+       ;
+OptionalType:          NamedType { $$ = $1; }
+       |               NamedType OPTIONAL Control {
+                           $$ = $1;
+                           $$ -> yp_flags |= YP_OPTIONAL;
+                           if ($3) {
+                               $$ -> yp_optcontrol = $3;
+                               $$ -> yp_flags |= YP_OPTCONTROL;
+                           }
+                       }
+       |               NamedType OPTIONAL CAction {
+                           $$ = $1;
+                           $$ -> yp_flags |= YP_OPTIONAL;
+                           if ($3) {
+                               $$ -> yp_flags |= YP_OPTCONTROL;
+                               $$ -> yp_optional_act = $3;
+                           }
+                       }
+       |               NamedType DEFAULT Value Control {
+                           $$ = $1;
+                           $$ -> yp_default = $3;
+                           $$ -> yp_flags |= YP_DEFAULT;
+                           if ($4) {
+                               $$ -> yp_optcontrol = $4;
+                               $$ -> yp_flags |= YP_OPTCONTROL;
+                           }
+                       }
+       |               ComponentsOf { $$ = $1; }
+       |               NAME ComponentsOf { $$ = $2; $$->yp_id = $1; }
+       ;
+NamedType:             NAME Type {
+                           $$ = $2;
+                           $$ -> yp_id = $1;
+                           $$ -> yp_flags |= YP_ID;
+                       }
+       |               Type { $$ = $1; }
+       ;
+ComponentsOf:          Components Type {
+                           $$ = $2;
+                           $$ -> yp_flags |= YP_COMPONENTS;
+                       }
+       ;
+AlternativeTypeList:   NamedType { $$ = $1; }
+       |               AlternativeTypeList COMMA UAction NamedType {
+                           if ($3)
+                               $4->yp_bef_alist=yal_join($3, $4->yp_bef_alist);
+                           $$ = add_type ($1, $4);
+                       }
+       ;
+
+Tag:                   LBRACKET Class NumericValue RBRACKET {
+                           $$ = $2;
+                           $$ -> yt_value = $3;
+                       }
+       ;
+Class:                 UNIVERSAL { $$ = new_tag (PE_CLASS_UNIV); }
+       |               APPLICATION { $$ = new_tag (PE_CLASS_APPL); }
+       |               PRIVATE { $$ = new_tag (PE_CLASS_PRIV); }
+       |               empty { $$ = new_tag (PE_CLASS_CONT); }
+       ;
+
+
+Valueassignment:       NAME Type CCE Value
+       ;
+
+Value:                 BuiltinValue
+       |               DefinedValue
+       ;
+BuiltinValue:          TRUE {
+                           $$ = new_value (YV_BOOL);
+                           $$ -> yv_number = 1;
+                       }
+       |               FALSE {
+                           $$ = new_value (YV_BOOL);
+                           $$ -> yv_number = 0;
+                       }
+       |               LITNUMBER {
+                           $$ = new_value (YV_NUMBER);
+                           $$ -> yv_number = $1;
+                       }
+       |               BSTRING {
+                           $$ = new_value (YV_BSTRING);
+                           $$ -> yv_xstring = bit2bin($1, &$$->yv_xlength);
+                           free($1);
+                       }
+       |               HSTRING {
+                           $$ = new_value (YV_HSTRING);
+                           $$ -> yv_xstring = hex2bin($1, &$$->yv_xlength);
+                           free($1);
+                       }
+       |               LBRACE ID IdentifierList RBRACE {
+                           $$ = new_value (YV_IDLIST);
+                           $$ -> yv_idlist = new_value (YV_IDEFINED);
+                           $$ -> yv_idlist -> yv_identifier = $2;
+                           if ($3)
+                               $$ = add_value ($$, $3);
+                       }
+       |               LITSTRING {
+                           $$ = new_value (YV_STRING);
+                           $$ -> yv_string = $1;
+                       }
+       |               NIL { $$ = new_value (YV_NULL); }
+       |               LBRACE Values RBRACE {
+                           $$ = new_value (YV_VALIST);
+                           $$ -> yv_idlist = $2;
+                       }
+       |               NAME Value {
+                           $$ = $2;
+                           $$ -> yv_id = $1;
+                           $$ -> yv_flags |= YV_ID;
+                       }
+       |               Type Value {
+                           $$ = $2;
+                           $$ -> yv_type = $1;
+                           $$ -> yv_flags |= YV_TYPE;
+                       }
+       |               RealValue {
+                           $$ = new_value (YV_REAL);
+                           $$ -> yv_real = $1;
+                       }
+       ;
+
+RealValue:             NumericRealValue
+       |               SpecialRealValue
+       ;
+
+SpecialRealValue:      PLUSINFINITY { $$ = PE_REAL_INFINITY;} 
+       |               MINUSINFINITY { $$ = - PE_REAL_INFINITY; }
+       ;
+
+NumericRealValue:      LBRACE LITNUMBER COMMA LITNUMBER COMMA
+                                LITNUMBER RBRACE {
+                               if ($4 != 2 && $4 != 10)
+                                       myyerror ("Illegal base value %d", $4);
+                               $$ = $2 * pow ((double)$4, (double)$6);
+                       }
+       ;
+
+DefinedValue:          ID {
+                           $$ = new_value (YV_IDEFINED);
+                           $$ -> yv_identifier = $1;
+                       }
+       |               NAME {  /* XXX */
+                           $$ = new_value (YV_IDEFINED);
+                           $$ -> yv_identifier = $1;
+                           $$ -> yv_flags |= YV_BOUND;
+                       }
+       |               ID DOT ID {
+                           $$ = new_value (YV_IDEFINED);
+                           $$ -> yv_identifier = $3;
+                           $$ -> yv_module = $1;
+                       }
+       ;
+
+IdentifierList:                IdentifierList COMMA ID {
+                           $$ = new_value (YV_IDEFINED);
+                           $$ -> yv_identifier = $3;
+                           if ($1)
+                               $$ = add_value ($1, $$);
+                       }
+       |               empty { $$ = NULLYV; }
+       ;
+
+Values:                        NamedValueList { $$ = $1; }
+       |               empty { $$ = NULLYV; }
+       ;
+NamedValueList:                NamedValue { $$ = $1; }
+       |               NamedValueList COMMA NamedValue {
+                           $$ = add_value ($1, $3);
+                       }
+       ;
+NamedValue:            Value { $$ = $1; }
+       ;
+
+empty: ;
+
+Octetstring:           OCTET STRING
+       |               OCTETSTRING
+       ;
+
+Bitstring:             BITSTRING
+       |               BIT STRING
+       ;
+
+SequenceOf:            SEQUENCEOF
+       |               SEQUENCE OF
+       ;
+SetOf:                 SETOF
+       |               SET OF
+       ;
+Components:            COMPONENTSOF
+       |               COMPONENTS OF
+       ;
+
+ObjectIdentifierValue: LBRACE ObjIdComponentList RBRACE
+                       { $$ = $2; }
+       ;
+
+ObjIdComponentList:    ObjIdComponent
+       |               ObjIdComponentList ObjIdComponent
+                       {
+                               $$ = addoid($1, $2);
+                               oid_free ($1);
+                               oid_free ($2);
+                       }
+       ;
+
+ObjIdComponent:                NumberForm
+       |               NameAndNumberForm
+       ;
+
+NumberForm:            LITNUMBER { $$ = int2oid ($1); }
+       |               DefinedValue {
+                               $$ = oidlookup($1->yv_identifier);
+                               free((char *)$1);
+                       }
+       ;
+
+NameAndNumberForm:     NAME LPAREN NumberForm RPAREN {
+                               free ($1);
+                               $$ = $3;
+                       }
+       ;
+
+SubType:               Type SubtypeSpec
+       |               SET SizeConstraint OF Sctrl UAction Control Type {
+                           $$ = new_type (YP_SETTYPE, $1);
+                           $$ -> yp_type = $7;
+                           if ($4) {
+                               $$ -> yp_structname = $4 -> ys_structname;
+                               $$ -> yp_ptrname = $4 -> ys_ptrname;
+                               free_ys ($4);
+                           }
+                           if ($6) {
+                               $$ -> yp_control = $6;
+                               $$ -> yp_flags |= YP_CONTROLLED;
+                           }
+                           if ($5)
+                               $7->yp_bef_alist=yal_join($5, $7->yp_bef_alist);
+                       }
+
+       |               SEQUENCE SizeConstraint OF Sctrl UAction Control Type {
+                           $$ = new_type (YP_SEQTYPE, $1);
+                           $$ -> yp_type = $7;
+                           if ($4) {
+                               $$ -> yp_structname = $4 -> ys_structname;
+                               $$ -> yp_ptrname = $4 -> ys_ptrname;
+                               free_ys ($4);
+                           }
+                           if ($6) {
+                               $$ -> yp_control = $6;
+                               $$ -> yp_flags |= YP_CONTROLLED;
+                           }
+                           if ($5)
+                               $7->yp_bef_alist=yal_join($5, $7->yp_bef_alist);
+                       }
+       ;
+
+SubtypeSpec:           LPAREN SubtypeAlternative SubtypeAlternativeList RPAREN
+       ;
+
+SubtypeAlternative:    SubtypeValueSet
+       |               SubtypeConstraint
+       ;
+
+SubtypeAlternativeList:        BAR SubtypeAlternative SubtypeAlternativeList
+       |               empty
+       ;
+
+SubtypeValueSet:       Value
+       |               ContainedSubType
+       |               ValueRange
+       |               PermittedAlphabet
+       ;
+
+SubtypeConstraint:     SizeConstraint
+       |               InnerTypeConstraint
+       ;
+
+ContainedSubType:      INCLUDES Type   ;
+
+ValueRange:            LowerEndPoint DOTDOT UpperEndpoint
+       ;
+
+LowerEndPoint:         LowerEndValue
+       |               LowerEndValue LANGLE
+       ;
+
+UpperEndpoint:         UpperEndValue
+       |               LANGLE UpperEndValue
+       ;
+
+LowerEndValue:         Value
+       |               MIN
+       ;
+
+UpperEndValue:         Value
+       |               MAX
+       ;
+
+SizeConstraint:                SIZE SubtypeSpec
+       ;
+
+PermittedAlphabet:     FROM SubtypeSpec
+       ;
+
+InnerTypeConstraint:   WITH COMPONENT SingleTypeConstraint
+       |               WITH COMPONENTS MultipleTypeConstraints
+       ;
+
+SingleTypeConstraint:  SubtypeSpec
+       ;
+
+MultipleTypeConstraints:FullSpecification
+       |               PartialSpecification
+       ;
+
+FullSpecification:     LBRACE TypeConstraints RBRACE
+       ;
+
+PartialSpecification:  LBRACE DOTDOTDOT COMMA TypeConstraints RBRACE
+       ;
+
+TypeConstraints:       NamedConstraint
+       |               NamedConstraint COMMA TypeConstraints
+       ;
+
+NamedConstraint:       NAME Constraint
+       |               Constraint
+       ;
+
+Constraint:            ValueConstraint
+       |               PresenceConstraint
+       |               empty
+       ;
+
+ValueConstraint:       SubtypeSpec
+       ;
+
+PresenceConstraint:    PRESENT
+       |               ABSENT
+       ;
+
+Sctrl:                 SCTRL { $$ = new_ys ($1); }
+       |               empty { $$ = NULLYS; }
+       ;
+%%
+
+#ifdef HPUX
+#define        uchar   Uchar
+#endif
+#include "lex.c"
diff --git a/src/isode/psap/Makefile.in b/src/isode/psap/Makefile.in
new file mode 100644 (file)
index 0000000..451b692
--- /dev/null
@@ -0,0 +1,276 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE PSAP processes
+###############################################################################
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+BUILDTOP = ../../
+TOPDIR = $(BUILDTOP)
+LIBDIR =       $(TOPDIR)lib/
+
+OPTIONS        =       -I. -I$(HDIR) $(PEPYPATH) $(KRBOPT)
+CFLAGS  =       $(OPTIONS) $(LOPTIONS) 
+
+HDIR   =       $(TOPDIR)isode/h/
+UTILDIR        =       $(TOPDIR)isode/util/
+INCDIRM        =       $(HDIR)
+INCDIR =       $(INCDIRM)/
+PEPSYDIRM=     $(INCDIR)pepsy
+PEPSYDIR=      $(PEPSYDIRM)/
+LIBISODE=      $(TOPDIR)libisode.a
+LIBDSAP        =       $(TOPDIR)libdsap.a
+
+LLIBS   =
+LN     =       ln
+LDCC   =       $(CC)
+LIBS = @LIBS@
+LSOCKET        =       $(LIBS)
+
+###############################################################################
+#
+#                               NOTICE
+#
+#    Acquisition, use, and distribution of this module and related
+#    materials 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  =       libpsap.a ../compat/libcompat.a
+LLIBS   =      $(TOPDIR)llib-lcompat
+HFILES =       $(HDIR)psap.h \
+               $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           libpsap psaptest hex2pe dec2pe
+inst-all:      # inst-libpsap manuals
+install:       inst-all clean
+lint:          l-libpsap l-psaptest
+
+
+################################################################
+# libpsap
+################################################################
+
+CFILES =       addr2ref.c bit2prim.c bitstr2strb.c bit_ops.c dg2ps.c \
+               fdx2ps.c flag2prim.c gtime.c int2strb.c isobject.c num2prim.c \
+               obj2prim.c objectbyname.c objectbyoid.c ode2oid.c oid_cmp.c \
+               oid_cpy.c oid_free.c oid2ode.c pe2pl.c pe2ps.c pe2qb_f.c \
+               pe2ssdu.c pe2text.c pe2uvec.c pe_alloc.c pe_cmp.c pe_cpy.c \
+               pe_error.c pe_expunge.c pe_extract.c pe_free.c pe_pullup.c \
+               pl2pe.c pl_tables.c prim2bit.c prim2flag.c prim2num.c \
+               prim2oid.c prim2qb.c prim2real.c prim2set.c prim2str.c \
+               prim2time.c ps2pe.c ps_alloc.c ps_error.c ps_flush.c \
+               ps_free.c ps_get_abs.c ps_io.c ps_prime.c qb2pe.c qb2prim.c \
+               qb2str.c qb_free.c qb_pullup.c qbuf2pe.c qbuf2pe_f.c \
+               qbuf2ps.c real2prim.c seq_add.c seq_addon.c seq_del.c \
+               seq_find.c set_add.c set_addon.c set_del.c set_find.c \
+               sprintoid.c sprintref.c ssdu2pe.c std2ps.c str2oid.c \
+               str2pe.c str2prim.c str2ps.c str2qb.c strb2bitstr.c \
+               strb2int.c time2prim.c time2str.c tm2ut.c ts2ps.c ut2tm.c \
+               uvec2ps.c
+
+OFILES =       addr2ref.o bit2prim.o bitstr2strb.o bit_ops.o dg2ps.o \
+               fdx2ps.o flag2prim.o gtime.o int2strb.o isobject.o num2prim.o \
+               obj2prim.o objectbyname.o objectbyoid.o ode2oid.o oid_cmp.o \
+               oid_cpy.o oid_free.o oid2ode.o pe2pl.o pe2ps.o pe2qb_f.o \
+               pe2ssdu.o pe2text.o pe2uvec.o pe_alloc.o pe_cmp.o pe_cpy.o \
+               pe_error.o pe_expunge.o pe_extract.o pe_free.o pe_pullup.o \
+               pl2pe.o pl_tables.o prim2bit.o prim2flag.o prim2num.o \
+               prim2oid.o prim2qb.o prim2real.o prim2set.o prim2str.o \
+               prim2time.o ps2pe.o ps_alloc.o ps_error.o ps_flush.o \
+               ps_free.o ps_get_abs.o ps_io.o ps_prime.o qb2pe.o qb2prim.o \
+               qb2str.o qb_free.o qb_pullup.o qbuf2pe.o qbuf2pe_f.o \
+               qbuf2ps.o real2prim.o seq_add.o seq_addon.o seq_del.o \
+               seq_find.o set_add.o set_addon.o set_del.o set_find.o \
+               sprintoid.o sprintref.o ssdu2pe.o std2ps.o str2oid.o \
+               str2pe.o str2prim.o str2ps.o str2qb.o strb2bitstr.o \
+               strb2int.o time2prim.o time2str.o tm2ut.o ts2ps.o ut2tm.o \
+               uvec2ps.o \
+               $(OSTRINGS)
+
+inst-libpsap:  $(LIBDIR)libpsap.a $(LINTDIR)llib-lpsap
+
+$(LIBDIR)libpsap.a:    libpsap.a
+               -rm -f $@
+               cp libpsap.a $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+               -@ls -gls $@
+               -@echo ""
+
+$(LINTDIR)llib-lpsap:  llib-lpsap
+               -cp $@ zllib-lpsap
+               -rm -f $@
+               sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+                       < llib-lpsap | \
+                       sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+               @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+               -@ls -gls $@ $@.ln
+               -@echo ""
+
+libpsap:       libpsap.a
+
+libpsap.a:     psapvrsn.o
+               -rm -f $@
+               @$(UTILDIR)make-lib.sh $(SYSTEM) $@ $(OFILES) \
+                       psapvrsn.o
+               -@rm -f $(TOPDIR)libpsap.a $(TOPDIR)llib-lpsap
+               -@$(LN) libpsap.a $(TOPDIR)libpsap.a || cp libpsap.a $(TOPDIR)libpsap.a
+               -@$(LN) llib-lpsap $(TOPDIR)llib-lpsap
+               -@ls -l $@
+               -@echo "PSAP library built normally"
+
+psapvrsn.c:    $(OFILES)
+               @$(UTILDIR)version.sh psap > $@
+
+l-libpsap:;    $(LINT) $(LFLAGS) $(CFILES) psapvrsn.c $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+addr2ref.o:    $(HFILES) $(HDIR)ssap.h
+bit2prim.o:    $(HFILES)
+bitstr2strb.o: $(HFILES)
+bit_ops.o:     $(HFILES)
+dg2ps.o:       $(HFILES)
+fdx2ps.o:      $(HFILES)
+flag2prim.o:   $(HFILES)
+gtime.o:       $(HFILES)
+int2strb.o:    $(HFILES)
+isobject.o:    $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+num2prim.o:    $(HFILES)
+obj2prim.o:    $(HFILES)
+objectbyname.o:        $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+objectbyoid.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ode2oid.o:     $(HFILES)
+oid_cmp.o:     $(HFILES)
+oid_cpy.o:     $(HFILES)
+oid_free.o:    $(HFILES)
+oid2ode.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+pe2pl.o:       $(HFILES)
+pe2ps.o:       $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+pe2qb_f.o:     $(HFILES)
+pe2ssdu.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+pe2text.o:     $(HFILES) $(HDIR)logger.h
+pe2uvec.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+pe_alloc.o:    $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+pe_cmp.o:      $(HFILES)
+pe_cpy.o:      $(HFILES)
+pe_error.o:    $(HFILES)
+pe_expunge.o:  $(HFILES)
+pe_extract.o:  $(HFILES)
+pe_free.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+pe_pullup.o:   $(HFILES)
+pl2pe.o:       $(HFILES)
+pl_tables.o:   $(HFILES)
+prim2bit.o:    $(HFILES)
+prim2flag.o:   $(HFILES)
+prim2num.o:    $(HFILES)
+prim2oid.o:    $(HFILES)
+prim2qb.o:     $(HFILES)
+prim2set.o:    $(HFILES)
+prim2str.o:    $(HFILES)
+prim2time.o:   $(HFILES)
+ps2pe.o:       $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ps_alloc.o:    $(HFILES)
+ps_error.o:    $(HFILES)
+ps_flush.o:    $(HFILES)
+ps_free.o:     $(HFILES)
+ps_get_abs.o:  $(HFILES)
+ps_io.o:       $(HFILES)
+ps_prime.o:    $(HFILES)
+qb2pe.o:       $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+qb2prim.o:     $(HFILES)
+qb2str.o:      $(HFILES)
+qb_free.o:     $(HFILES)
+qb_pullup.o:   $(HFILES)
+qbuf2pe.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+qbuf2pe_f.o:   $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+qbuf2ps.o:     $(HFILES)
+seq_add.o:     $(HFILES)
+seq_addon.o:   $(HFILES)
+seq_del.o:     $(HFILES)
+seq_find.o:    $(HFILES)
+set_add.o:     $(HFILES)
+set_addon.o:   $(HFILES)
+set_del.o:     $(HFILES)
+set_find.o:    $(HFILES)
+sprintoid.o:   $(HFILES)
+sprintref.o:   $(HFILES) $(HDIR)ssap.h
+ssdu2pe.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+std2ps.o:      $(HFILES)
+str2oid.o:     $(HFILES)
+str2pe.o:      $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+str2prim.o:    $(HFILES)
+str2ps.o:      $(HFILES)
+str2qb.o:      $(HFILES)
+strb2bitstr.o: $(HFILES)
+strb2int.o:    $(HFILES)
+time2prim.o:   $(HFILES)
+time2str.o:    $(HFILES)
+tm2ut.o:       $(HFILES)
+ts2ps.o:       $(HFILES) $(HDIR)tsap.h $(HDIR)tailor.h $(HDIR)logger.h
+ut2tm.o:       $(HFILES)
+uvec2ps.o:     $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+
+
+################################################################
+# psaptest
+################################################################
+
+psaptest:      psaptest.o $(LIBES)
+               $(LDCC) $(LDFLAGS) -o $@ psaptest.o $(LIBES) $(LSOCKET)
+
+psaptest.o:    $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h psaptest.c
+               $(CC) $(CFLAGS) -c psaptest.c
+
+l-psaptest:;   $(LINT) $(LFLAGS) psaptest.c llib-lpsap $(LLIBS) \
+                       | grep -v "warning: possible pointer alignment problem"
+
+
+################################################################
+# hex2pe/dec2pe
+################################################################
+
+hex2pe:                hex2pe.o
+               $(LDCC) $(LDFLAGS) -o $@ hex2pe.o
+
+hex2pe.o:      $(HFILES) hex2pe.c
+               $(CC) $(CFLAGS) -c hex2pe.c
+
+
+dec2pe:                dec2pe.o
+               $(LDCC) $(LDFLAGS) -o $@ dec2pe.o
+
+dec2pe.o:      $(HFILES) dec2pe.c
+               $(CC) $(CFLAGS) -c dec2pe.c
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS        =       libpsap.3
+
+manuals:;      @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+               -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a z* _* core psaptest dec2pe hex2pe psapvrsn.c
+
+grind:;                iprint Makefile
+               tgrind -lc $(CFILES) psapvrsn.c psaptest.c dec2pe.c hex2pe.c \
+                       llib-lpsap
+               @echo $(MANUALS) | \
+                       tr " " "\012" | \
+                       sed -e "s%.*%itroff -man &%" | \
+                       sh -ve
diff --git a/src/isode/psap/addr2ref.c b/src/isode/psap/addr2ref.c
new file mode 100644 (file)
index 0000000..b96b52c
--- /dev/null
@@ -0,0 +1,96 @@
+/* addr2ref.c - manage encoded session addresses */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:22  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:36:51  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:39  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "ssap.h"
+
+static int  stuff ();
+/* \f */
+
+struct SSAPref *addr2ref (addr)
+register char   *addr;
+{
+    int     result;
+    long    clock;
+    register    PE pe;
+    register struct tm *tm;
+    struct UTCtime  uts;
+    register struct UTCtime *ut = &uts;
+    static struct SSAPref   srs;
+    register struct SSAPref *sr = &srs;
+
+    bzero ((char *) sr, sizeof *sr);
+
+    if ((pe = t61s2prim (addr, strlen (addr))) == NULLPE)
+       return NULL;
+    result = stuff (pe, sr -> sr_udata, &sr -> sr_ulen);
+    pe_free (pe);
+    if (result == NOTOK)
+       return NULL;
+
+    if (time (&clock) == NOTOK || (tm = gmtime (&clock)) == NULL)
+       return NULL;
+    tm2ut (tm, ut);
+
+    if ((pe = utct2prim (ut)) == NULLPE)
+       return NULL;
+    result = stuff (pe, sr -> sr_cdata, &sr -> sr_clen);
+    pe_free (pe);
+    if (result == NOTOK)
+       return NULL;
+
+    return sr;
+}
+
+/* \f */
+
+static int  stuff (pe, dbase, dlen)
+register PE pe;
+register char *dbase;
+register u_char *dlen;
+{
+    int     len;
+    char   *base;
+
+    if (pe2ssdu (pe, &base, &len) == NOTOK)
+       return NOTOK;
+
+    bcopy (base, dbase, (int) (*dlen = len));
+    free (base);
+
+    return OK;
+}
diff --git a/src/isode/psap/bit2prim.c b/src/isode/psap/bit2prim.c
new file mode 100644 (file)
index 0000000..56df40e
--- /dev/null
@@ -0,0 +1,99 @@
+/* bit2prim.c - bit string to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:23  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:36:53  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:40  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+PE     bit2prim_aux ();
+
+/* \f */
+
+PE     bit2prim (pe)
+register PE    pe;
+{
+    if (pe == NULLPE)
+       return NULLPE;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM:
+           if (pe -> pe_prim == NULLPED) {
+               if ((pe -> pe_prim = PEDalloc (1)) == NULLPED)
+                   return NULLPE;
+               pe -> pe_len = 1;
+               pe -> pe_nbits = 0;
+           }
+           /* and fall */
+
+       case PE_FORM_CONS:
+           if (bit2prim_aux (pe) == NULLPE)
+               return NULLPE;
+           break;
+    }
+
+    return pe;
+}
+
+/* \f */
+
+static PE  bit2prim_aux (pe)
+register PE    pe;
+{
+    int            i;
+    register PE            p;
+
+    if (pe == NULLPE)
+       return NULLPE;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM:
+           if (pe -> pe_prim && pe -> pe_len) {
+               if ((i = (((pe -> pe_len - 1) * 8) - pe -> pe_nbits)) > 7)
+                   return pe_seterr (pe, PE_ERR_BITS, NULLPE);
+               pe -> pe_prim[0] = i & 0xff;
+
+           }
+           break;
+
+       case PE_FORM_CONS:
+           for (p = pe -> pe_cons; p; p = p -> pe_next)
+               if (bit2prim (p) == NULLPE)
+                   return NULLPE;
+           break;
+    }
+
+    return pe;
+}
diff --git a/src/isode/psap/bit_ops.c b/src/isode/psap/bit_ops.c
new file mode 100644 (file)
index 0000000..df2379c
--- /dev/null
@@ -0,0 +1,219 @@
+/* bit_opts.c - operations on bit strings */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:25  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:36:55  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:40  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+/* the first octet indicates how many unused bits are in the last octet --
+
+       prim2bit  -     presentation element to bit string
+       bit2prim  -     bit string to presentation element
+       bit_on    -     turn a bit ON
+       bit_off   -     turn a bit OFF
+       bit_test  -     test a bit
+ */
+
+
+PElementData ffb (), ffb_aux ();
+PE     ffb_pe ();
+
+/* \f */
+
+int    bit_on (pe, i)
+register PE    pe;
+register int   i;
+{
+    int            mask;
+    register PElementData bp;
+
+    if ((bp = ffb (pe, i, &mask, 1)) == NULLPED)
+       return pe_seterr (pe, PE_ERR_NMEM, NOTOK);
+
+    *bp |= mask;
+
+    return OK;
+}
+
+/* \f */
+
+int    bit_off (pe, i)
+register PE    pe;
+register int   i;
+{
+    int            mask;
+    register PElementData bp;
+
+    if ((bp = ffb (pe, i, &mask, 1)) == NULLPED)
+       return pe_seterr (pe, PE_ERR_NMEM, NOTOK);
+
+    *bp &= ~mask;
+
+    return OK;
+}
+
+/* \f */
+
+int    bit_test (pe, i)
+register PE    pe;
+register int   i;
+{
+    int            mask;
+    register PElementData bp;
+
+    if ((bp = ffb (pe, i, &mask, 0)) == NULLPED)
+       return pe_seterr (pe, PE_ERR_BIT, NOTOK);
+
+    return (*bp & mask ? 1 : 0);
+}
+
+/* \f */
+
+static PElementData ffb (pe, n, mask, xtnd)
+register PE    pe;
+register int   n,
+              *mask,
+               xtnd;
+{
+    register int    len,
+                   i;
+    int     j;
+    register PElementData bp;
+    register PE    *p,
+                   q,
+                   r;
+
+    i = (j = n) / 8 + 1;
+    if ((bp = ffb_aux (pe, &j, mask)) != NULLPED || !xtnd)
+       return bp;
+
+    if (pe -> pe_form == PE_FORM_CONS)
+       pe = ffb_pe (pe);
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if (pe -> pe_len < (PElementLen) (len = i + 1)) {
+               if ((bp = PEDalloc (len)) == NULLPED)
+                   return NULLPED;
+               bzero ((char *) bp, len);
+               if (pe -> pe_prim) {
+                   PEDcpy (pe -> pe_prim, bp, pe -> pe_len);
+                   if (pe -> pe_inline)
+                       pe -> pe_inline = 0;
+                   else
+                       PEDfree (pe -> pe_prim);
+               }
+               pe -> pe_prim = bp, pe -> pe_len = len;
+           }
+           pe -> pe_nbits = n + 1;
+           *mask = 1 << (7 - (n % 8));
+           return (pe -> pe_prim + i);
+
+       case PE_FORM_CONS: 
+           if ((r = pe_alloc (pe -> pe_class, PE_FORM_PRIM, pe -> pe_id))
+                   == NULLPE)
+               return NULLPED;
+           if ((r -> pe_prim = PEDalloc (len = r -> pe_len = j / 8 + 2))
+                   == NULLPED) {
+               pe_free (r);
+               return NULLPED;
+           }
+           bzero ((char *) r -> pe_prim, len);
+           r -> pe_nbits = j + 1;
+           *mask = 1 << (7 - (j % 8));
+           for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next)
+               continue;
+           *p = r;
+           return (r -> pe_prim + len - 1);
+
+       default:
+           return NULLPED;
+    }
+}
+
+/* \f */
+
+static PElementData ffb_aux (pe, n, mask)
+register PE    pe;
+register int   *n,
+              *mask;
+{
+    register int    i,
+                   nbits;
+    register PElementData bp;
+    register PE            p;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if ((nbits = pe -> pe_nbits) > (i = *n)) {
+               *mask = 1 << (7 - (i % 8));
+               return (pe -> pe_prim + i / 8 + 1);
+           }
+           *n -= nbits;
+           break;
+
+       case PE_FORM_CONS: 
+           for (p = pe -> pe_cons; p; p = p -> pe_next)
+               if ((bp = ffb_aux (p, n, mask)) != NULLPED)
+                   return bp;
+           break;
+    }
+
+    return NULLPED;
+}
+
+/* \f */
+
+static PE      ffb_pe (pe)
+register PE    pe;
+{
+    register PE            p,
+                   q;
+
+    for (p = pe -> pe_cons, q = NULLPE; p; q = p, p = p -> pe_next)
+       continue;
+
+    if (q != NULLPE)
+       switch (q -> pe_form) {
+           case PE_FORM_PRIM: 
+               return q;
+
+           case PE_FORM_CONS: 
+               return ffb_pe (q);
+       }
+
+    return pe;
+}
diff --git a/src/isode/psap/bitstr2strb.c b/src/isode/psap/bitstr2strb.c
new file mode 100644 (file)
index 0000000..a102a3c
--- /dev/null
@@ -0,0 +1,73 @@
+/* bitstr2strb.c - bit string to string of bits */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:27  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:36:56  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:41  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+char   *bitstr2strb (pe, k)
+PE     pe;
+int    *k;
+{
+    register int    i,
+                   j,
+                   len,
+                   bit,
+                   mask;
+    register char   *dp;
+    char   *cp;
+
+    if (pe == NULLPE)
+       return NULLCP;
+
+    *k = len = pe -> pe_nbits;
+    if ((cp = dp = calloc (1, (unsigned) (len / 8 + 2))) == NULLCP)
+       return NULLCP;
+
+    for (bit = i = 0, mask = 1 << (j = 7); i < len; i++) {
+       if (bit_test (pe, i))
+           bit |= mask;
+       if (j-- == 0)
+           *dp++ = bit & 0xff, bit = 0, mask = 1 << (j = 7);
+       else
+           mask >>= 1;
+    }
+    if (j != 7)
+       *dp = bit & 0xff;
+
+    return cp;
+}
diff --git a/src/isode/psap/configure.in b/src/isode/psap/configure.in
new file mode 100644 (file)
index 0000000..c7b4a2b
--- /dev/null
@@ -0,0 +1,4 @@
+AC_INIT(configure.in)
+AC_HAVE_LIBRARY(nsl)
+AC_HAVE_LIBRARY(socket)
+AC_OUTPUT(Makefile)
diff --git a/src/isode/psap/dec2pe.c b/src/isode/psap/dec2pe.c
new file mode 100644 (file)
index 0000000..f6af13b
--- /dev/null
@@ -0,0 +1,21 @@
+
+# include <stdio.h>
+
+main()
+{      
+       unsigned int i;
+       char buf[1];
+       register int result, count;
+
+       while ((result = scanf("%d", &i)) != EOF){
+               count++;
+               buf[0]=(char) i;
+               if (result) write(1, buf, 1);
+               else
+               {
+                   (void) fprintf(stderr,"Conversion failed at byte number %d\n", count);
+                       exit(1);
+               }
+       }
+       exit(0);
+}
diff --git a/src/isode/psap/dg2ps.c b/src/isode/psap/dg2ps.c
new file mode 100644 (file)
index 0000000..5a34abe
--- /dev/null
@@ -0,0 +1,257 @@
+/* dg2ps.c - datagram-backed abstraction for PStreams */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:33  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:00  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:42  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+struct ps_dg {
+    int            ps_fd;
+    int            ps_maxsize;
+
+    struct ps_inout {
+       struct qbuf *pio_qb;
+       char   *pio_ptr;
+       int     pio_cnt;
+
+       IFP     pio_fnx;
+    }      ps_input,
+           ps_output;
+
+    IFP            ps_check;
+};
+
+
+extern IFP     set_check_fd ();
+
+/* \f */
+
+static int  dg_prime (ps, waiting)
+register PS    ps;
+int    waiting;
+{
+    struct qbuf *qb;
+    register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
+    register struct ps_inout *pi = &pt -> ps_input;
+
+    switch (waiting) {
+       case 0:
+           if (pi -> pio_cnt > 0)
+               return OK;
+           break;
+
+       case 1:
+       default:
+           return (pi -> pio_cnt > 0 ? DONE : OK);
+
+       case -1:
+           if (pi -> pio_cnt <= 0)
+               return OK;
+           break;
+    }
+
+    if (pi -> pio_qb != NULL) {
+       qb_free (pi -> pio_qb);
+       pi -> pio_qb = NULL;
+    }
+    pi -> pio_cnt = 0;
+
+    if (waiting < 0)
+       return ps_seterr (ps, PS_ERR_EXTRA, NOTOK);
+
+    if ((*pi -> pio_fnx) (pt -> ps_fd, &qb) == NOTOK)
+       return ps_seterr (ps, PS_ERR_IO, NOTOK);
+
+    if (pi -> pio_qb = qb)
+       pi -> pio_ptr = qb -> qb_data, pi -> pio_cnt = qb -> qb_len;
+    else
+       pi -> pio_ptr = NULL, pi -> pio_cnt = 0;
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+    
+static int  dg_read (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    int            cc;
+    register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
+    register struct ps_inout *pi = &pt -> ps_input;
+
+    if ((cc = pi -> pio_cnt) <= 0)
+       return 0;
+    if (cc > n)
+       cc = n;
+
+    bcopy (pi -> pio_ptr, (char *) data, cc);
+    pi -> pio_ptr += cc, pi -> pio_cnt -= cc;
+
+    return cc;
+}
+
+
+/* ARGSUSED */
+
+static int  dg_write (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
+    register struct ps_inout *po = &pt -> ps_output;
+
+    if (po -> pio_cnt < n)
+       return 0;
+
+    bcopy ((char *) data, po -> pio_ptr, n);
+    po -> pio_ptr += n, po -> pio_cnt -= n;
+
+    return n;
+}
+
+
+static int  dg_flush (ps)
+register PS    ps;
+{
+    register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
+    register struct ps_inout *po = &pt -> ps_output;
+    register struct qbuf *qb = po -> pio_qb;
+
+    qb -> qb_len = po -> pio_ptr - qb -> qb_data;
+    if ((*po -> pio_fnx) (pt -> ps_fd, qb) != qb -> qb_len)
+       return ps_seterr (ps, PS_ERR_IO, NOTOK);
+
+    po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize;
+
+    return OK;
+}
+
+
+static int  dg_close (ps)
+register PS    ps;
+{
+    register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
+
+    if (pt == NULL)
+       return OK;
+
+    if (pt -> ps_input.pio_qb)
+       qb_free (pt -> ps_input.pio_qb);
+    if (pt -> ps_output.pio_qb)
+       qb_free (pt -> ps_output.pio_qb);
+
+    (void) set_check_fd (pt -> ps_fd, NULLIFP, NULLCP);
+
+    free ((char *) pt);
+
+    return OK;
+}
+
+
+static int  dg_check (fd, data)
+int    fd;
+caddr_t        data;
+{
+    int            n;
+    PS     ps = (PS) data;
+    register struct ps_dg *pt = (struct ps_dg *) ps -> ps_addr;
+
+    if (pt -> ps_check && (n = (*pt -> ps_check) (fd)))
+       return n;
+
+    return (ps_prime (ps, 1) > 0 ? DONE : OK);
+}
+
+/* \f */
+
+int    dg_open (ps)
+register PS    ps;
+{
+    ps -> ps_primeP = dg_prime;
+    ps -> ps_readP = dg_read;
+    ps -> ps_writeP = dg_write;
+    ps -> ps_flushP = dg_flush;
+    ps -> ps_closeP = dg_close;
+
+    return OK;
+}
+
+
+int    dg_setup (ps, fd, size, rfx, wfx, cfx)
+register PS    ps;
+int    fd,
+       size;
+IFP    rfx,
+       wfx,
+       cfx;
+{
+    register struct ps_dg *pt;
+    register struct ps_inout *po;
+    register struct qbuf *qb;
+
+    if ((pt = (struct ps_dg *) calloc (1, sizeof *pt)) == NULL)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+    ps -> ps_addr = (caddr_t) pt;
+
+    pt -> ps_fd = fd;
+    pt -> ps_maxsize = size;
+
+    if ((qb = (struct qbuf *) malloc (sizeof *qb
+                                         + (unsigned) pt -> ps_maxsize))
+           == NULL)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+    qb -> qb_forw = qb -> qb_back = qb;
+    qb -> qb_len = 0;
+    qb -> qb_data = qb -> qb_base;
+
+    po = &pt -> ps_output;
+    po -> pio_qb = qb;
+    po -> pio_ptr = qb -> qb_data, po -> pio_cnt = pt -> ps_maxsize;
+    if ((pt -> ps_input.pio_fnx = rfx) == NULLIFP
+           || (po -> pio_fnx = wfx) == NULLIFP)
+       return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+
+    pt -> ps_check = cfx;
+    (void) set_check_fd (fd, dg_check, (caddr_t) ps);
+
+    return OK;
+}
diff --git a/src/isode/psap/fdx2ps.c b/src/isode/psap/fdx2ps.c
new file mode 100644 (file)
index 0000000..ead80ab
--- /dev/null
@@ -0,0 +1,258 @@
+/* fdx2ps.c - full-duplex abstraction for PStreams */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:35  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:01  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:42  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+static int  fdx_flush ();
+/* \f   DATA */
+
+struct ps_fdx {
+    int            ps_fd;
+
+    struct ps_inout {
+       char   *pio_base;
+       int     pio_bufsiz;
+
+       char   *pio_ptr;
+       int     pio_cnt;
+    }      ps_input,
+           ps_output;
+
+    int            ps_nflush;
+};
+
+
+extern IFP     set_check_fd ();
+
+/* \f*/
+
+static int  fdx_prime (ps, waiting)
+register PS    ps;
+int    waiting;
+{
+    register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr;
+    register struct ps_inout *pi = &pt -> ps_input;
+
+    return (waiting > 0 && pi -> pio_cnt > 0 ? DONE : OK);
+}
+
+/* \f */
+
+/* ARGSUSED */
+    
+static int  fdx_read (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    int            cc;
+    register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr;
+    register struct ps_inout *pi = &pt -> ps_input;
+
+    if ((cc = pi -> pio_cnt) <= 0) {
+       if (n > pi -> pio_bufsiz) {
+           if ((cc = read (pt -> ps_fd, (char *) data, n)) == NOTOK)
+               return ps_seterr (ps, PS_ERR_IO, NOTOK);
+
+           return cc;
+       }
+
+       if ((cc = read (pt -> ps_fd, pi -> pio_base, pi -> pio_bufsiz))
+               == NOTOK)
+           return ps_seterr (ps, PS_ERR_IO, NOTOK);
+       pi -> pio_ptr = pi -> pio_base, pi -> pio_cnt = cc;
+    }
+
+    if (cc > n)
+       cc = n;
+
+    bcopy (pi -> pio_ptr, (char *) data, cc);
+    pi -> pio_ptr += cc, pi -> pio_cnt -= cc;
+
+    return cc;
+}
+
+
+/* ARGSUSED */
+
+static int  fdx_write (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    int            cc;
+    register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr;
+    register struct ps_inout *po = &pt -> ps_output;
+
+#ifdef oldef
+    if (n > po -> pio_bufsiz) {
+       if (fdx_flush (ps) == NOTOK
+               || (cc = write (pt -> ps_fd, (char *) data, n)) != n)
+#else
+    if (n > po -> pio_bufsiz && po -> pio_ptr <= po -> pio_base) {
+       if ((cc = write (pt -> ps_fd, (char *) data, n)) != n)
+#endif
+           return ps_seterr (ps, PS_ERR_IO, NOTOK);
+
+       return cc;
+    }
+
+    if (n > po -> pio_cnt)
+       n = po -> pio_cnt;
+
+    bcopy ((char *) data, po -> pio_ptr, n);
+    po -> pio_ptr += n, po -> pio_cnt -= n;
+
+    if (po -> pio_cnt <= 0 && fdx_flush (ps) == NOTOK)
+       return ps_seterr (ps, PS_ERR_IO, NOTOK);
+
+    return n;
+}
+
+
+static int  fdx_flush (ps)
+register PS    ps;
+{
+    int            cc;
+    register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr;
+    register struct ps_inout *po = &pt -> ps_output;
+
+    if ((cc = po -> pio_ptr - po -> pio_base) <= 0)
+       return OK;
+    pt -> ps_nflush++;
+
+    if (write (pt -> ps_fd, po -> pio_base, cc) != cc)
+       return ps_seterr (ps, PS_ERR_IO, NOTOK);
+    po -> pio_ptr = po -> pio_base, po -> pio_cnt = po -> pio_bufsiz;
+
+    return OK;
+}
+
+
+static int  fdx_close (ps)
+register PS    ps;
+{
+    register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr;
+
+    if (pt == NULL)
+       return OK;
+
+    if (pt -> ps_input.pio_base)
+       free (pt -> ps_input.pio_base);
+    if (pt -> ps_output.pio_base)
+       free (pt -> ps_output.pio_base);
+
+    (void) set_check_fd (pt -> ps_fd, NULLIFP, NULLCP);
+
+    free ((char *) pt);
+
+    return OK;
+}
+
+
+/* ARGSUSED */
+static int  fdx_check (fd, data)
+int    fd;
+caddr_t        data;
+{
+    return (ps_prime ((PS) data, 1) > 0 ? DONE : OK);
+}
+
+/* \f */
+
+int    fdx_open (ps)
+register PS    ps;
+{
+    ps -> ps_primeP = fdx_prime;
+    ps -> ps_readP = fdx_read;
+    ps -> ps_writeP = fdx_write;
+    ps -> ps_flushP = fdx_flush;
+    ps -> ps_closeP = fdx_close;
+
+    return OK;
+}
+
+
+int    fdx_setup (ps, fd)
+register PS    ps;
+int    fd;
+{
+    int            pz;
+    register struct ps_fdx *pt;
+
+    if ((pt = (struct ps_fdx *) calloc (1, sizeof *pt)) == NULL)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+    ps -> ps_addr = (caddr_t) pt;
+
+    pt -> ps_fd = fd;
+
+#ifdef BSD42
+    if ((pz = getpagesize ()) <= 0)
+#endif
+       pz = BUFSIZ;
+
+    if ((pt -> ps_input.pio_base = malloc ((unsigned) pz)) == NULL
+           || (pt -> ps_output.pio_base = malloc ((unsigned) pz)) == NULL)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+    pt -> ps_input.pio_bufsiz = pz, pt -> ps_output.pio_cnt = 0;
+    pt -> ps_input.pio_ptr = pt -> ps_input.pio_base;
+
+    pt -> ps_output.pio_bufsiz = pt -> ps_output.pio_cnt = pz;
+    pt -> ps_output.pio_ptr = pt -> ps_output.pio_base;
+
+    (void) set_check_fd (fd, fdx_check, (caddr_t) ps);
+
+    return OK;
+}
+
+
+int    fdx_reset (ps)
+register PS    ps;
+{
+    register struct ps_fdx *pt = (struct ps_fdx *) ps -> ps_addr;
+    register struct ps_inout *po = &pt -> ps_output;
+
+    if (pt -> ps_nflush == 0)
+       po -> pio_ptr = po -> pio_base, po -> pio_cnt = po -> pio_bufsiz;
+    else
+       return ps_seterr (ps, PS_ERR_NONE, NOTOK);
+
+    return OK;
+
+}
diff --git a/src/isode/psap/flag2prim.c b/src/isode/psap/flag2prim.c
new file mode 100644 (file)
index 0000000..3b14ec9
--- /dev/null
@@ -0,0 +1,60 @@
+/* flag2prim.c - boolean to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:03  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:43  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     flag2prim (b, class, id)
+register int b;
+PElementClass  class;
+PElementID     id;
+{
+    register PE            pe;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    if ((pe -> pe_prim = PEDalloc (pe -> pe_len = 1)) == NULLPED) {
+       pe_free (pe);
+       return NULLPE;
+    }
+
+    *pe -> pe_prim = b ? 0xff : 0x00;
+
+    return pe;
+}
diff --git a/src/isode/psap/gtime.c b/src/isode/psap/gtime.c
new file mode 100644 (file)
index 0000000..e1a0b9e
--- /dev/null
@@ -0,0 +1,116 @@
+/* gtime.c - inverse gmtime */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:38  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:04  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:43  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#ifdef OSX
+#include <sys/time.h>
+#endif
+#ifdef notdef
+#include <sys/timeb.h>
+#endif
+
+/* \f   DATA */
+
+/* gtime(): the inverse of localtime().
+       This routine was supplied by Mike Accetta at CMU many years ago.
+ */
+
+#ifdef masscomp
+extern int     dmsize[];
+#else
+int    dmsize[] = {
+    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+};
+#endif
+
+#define        dysize(y)       \
+       (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+
+#define        YEAR(y)         ((y) >= 100 ? (y) : (y) + 1900)
+
+/* \f */
+
+long   gtime (tm)
+register struct tm *tm;
+{
+    register int    i,
+                    sec,
+                    mins,
+                    hour,
+                    mday,
+                    mon,
+                    year;
+    register long   result;
+#ifdef notdef
+    long    local;
+    struct timeb    tb;
+#endif
+
+    if ((sec = tm -> tm_sec) < 0 || sec > 59
+           || (mins = tm -> tm_min) < 0 || mins > 59
+           || (hour = tm -> tm_hour) < 0 || hour > 24
+           || (mday = tm -> tm_mday) < 1 || mday > 31
+           || (mon = tm -> tm_mon + 1) < 1 || mon > 12)
+       return ((long) NOTOK);
+    if (hour == 24) {
+       hour = 0;
+       mday++;
+    }
+    year = YEAR (tm -> tm_year);
+
+    result = 0L;
+    for (i = 1970; i < year; i++)
+       result += dysize (i);
+    if (dysize (year) == 366 && mon >= 3)
+       result++;
+    while (--mon)
+       result += dmsize[mon - 1];
+    result += mday - 1;
+    result = 24 * result + hour;
+    result = 60 * result + mins;
+    result = 60 * result + sec;
+
+#ifdef notdef
+    (void) ftime (&tb);
+    result += 60 * tb.timezone;
+    local = result;
+    if ((tm = localtime (&local)) && tm -> tm_isdst)
+       result -= 60 * 60;
+#endif
+
+    return result;
+}
diff --git a/src/isode/psap/hex2pe.c b/src/isode/psap/hex2pe.c
new file mode 100644 (file)
index 0000000..2aefea5
--- /dev/null
@@ -0,0 +1,21 @@
+
+# include <stdio.h>
+
+main()
+{      
+       unsigned int i;
+       char buf[1];
+       register int result, count;
+
+       while ((result = scanf("%02x", &i)) != EOF){
+               count++;
+               buf[0]=(char) i;
+               if (result) write(1, buf, 1);
+               else
+               {
+                   (void) fprintf(stderr,"Conversion failed at byte number %d\n", count);
+                   exit(1);
+               }
+       }
+       exit(0);
+}
diff --git a/src/isode/psap/int2strb.c b/src/isode/psap/int2strb.c
new file mode 100644 (file)
index 0000000..aa81247
--- /dev/null
@@ -0,0 +1,55 @@
+/* int2strb.c - integer to string of bits */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:42  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:09  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:44  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+char   *int2strb (n, len)
+register int    n;
+int     len;
+{
+    register int    i;
+    static char buffer[sizeof (int) + 1];
+
+    bzero (buffer, sizeof (buffer));
+    for (i = 0; i < len; i++)
+       if (n & (1 << i))
+           buffer[i / 8] |= (1 << (7 - (i % 8)));
+
+    return buffer;
+}
diff --git a/src/isode/psap/isobject.c b/src/isode/psap/isobject.c
new file mode 100644 (file)
index 0000000..3460680
--- /dev/null
@@ -0,0 +1,107 @@
+/* isobject.c - lookup Object IDentifiers/DEscriptors */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:45  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:11  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:45  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "psap.h"
+#include "tailor.h"
+
+/* \f   DATA */
+
+static char *isobjects = "isobjects";
+
+static FILE *servf = NULL;
+static int  stayopen = 0;
+
+static struct isobject    ios;
+
+/* \f */
+
+int    setisobject (f)
+int    f;
+{
+    if (servf == NULL)
+       servf = fopen (isodefile (isobjects, 0), "r");
+    else
+       rewind (servf);
+    stayopen |= f;
+
+    return (servf != NULL);
+}
+
+
+int    endisobject () {
+    if (servf && !stayopen) {
+       (void) fclose (servf);
+       servf = NULL;
+    }
+
+    return 1;
+}
+
+/* \f */
+
+struct isobject  *getisobject () {
+    register int i;
+    register struct isobject *io = &ios;
+    register char  *cp;
+    static char buffer[BUFSIZ + 1];
+    static char *vec[NVEC + NSLACK + 1];
+    static unsigned int elements[NELEM + 1];
+
+    if (servf == NULL
+           && (servf = fopen (isodefile (isobjects, 0), "r")) == NULL)
+       return NULL;
+
+    while (fgets (buffer, sizeof buffer, servf) != NULL) {
+       if (*buffer == '#')
+           continue;
+       if (cp = index (buffer, '\n'))
+           *cp = NULL;
+       if (str2vec (buffer, vec) < 2)
+           continue;
+
+       if ((i = str2elem (vec[1], elements)) <= 1)
+           continue;
+
+       io -> io_descriptor = vec[0];
+       io -> io_identity.oid_elements = elements;
+       io -> io_identity.oid_nelem = i;
+
+       return io;
+    }
+    return NULL;
+}
diff --git a/src/isode/psap/libpsap.3 b/src/isode/psap/libpsap.3
new file mode 100644 (file)
index 0000000..6de1ac5
--- /dev/null
@@ -0,0 +1,237 @@
+.TH LIBPSAP 3 "15 APR 1986"
+.\" $header: /f/iso/psap/rcs/libpsap.3,v 4.4 88/05/31 15:19:26 mrose exp $
+.\"
+.\"
+.\" $log: $
+.\" 
+.SH NAME
+libpsap \- asn.1 presentation services library
+.SH SYNOPSIS
+.B "#include <isode/psap.h>"
+.sp
+\fIcc\fR\0...\0\fB\-lpsap\fR
+.SH DESCRIPTION
+the \fIlibpsap\fR library contains a set of routines which implement
+presentation syntax abstractions.
+two primary objects are manipulated:
+presentation \fIelements\fR and presentation \fIstreams\fR.
+.SH "PRESENTATION STREAMS"
+a stream is an object, similar to a \fBfile*\fR object in \fIstdio\fR\0(3),
+which is used to read and write elements.
+a stream is created by calling \fBps_alloc\fR with the address of an
+integer\-valued routine that will initialize certain stream\-dependent
+variables (presently, the read and write routines).
+two standard initialization routines are available:
+\fBstd_open\fR,
+which is used for presentation streams connected to \fIstdio\fR objects;
+and,
+\fBstr_open\fR,
+which is used for presentation streams connected to \fIstring\fR objects.
+after \fBps_alloc\fR successfully returns,
+final initialization is performed,
+usually by calling either
+\fBstd_setup\fR with the \fIstdio\fR object to be bound;
+or,
+\fBstr_setup\fR with the string object to be bound.
+after the setup routine successfully returns,
+the presentation stream is ready for reading or writing.
+.PP
+currently streams which have been initialized by these routines are
+uni-directional.
+This might change in a future distribution.
+Streams which have been initialized by \fBstd_open\fR and \fBstr_open\fR
+will automatically allocate additional resources when necessary,
+to the limits allowed by the operating system
+(e.g., repeated calls to a stream connected to a \fIstring\fR object will
+result in additional memory being allocated from UNIX).
+.PP
+Low\-level I/O is done from/to the stream by the macros \fBps_read\fR and
+\fBps_write\fR.
+These both call an internal routine which switches to the object\-specific
+read or write routine as appropriate.
+This internal routine, \fBps_io\fR, implements the consistent presentation
+stream abstraction.
+.PP
+Finally,
+when a stream has been exhausted, 
+it can be closed and de\-allocated with \fBps_free\fR.
+.PP
+The user may implement additional stream objects.
+Examine the source to the \fBstd_\fR and \fBstr_\fR routines
+to understand the internal protocol and uniform interface.
+.SH TRANSLATION
+The routine \fBps2pe\fR can be used to read the next presentation element
+from a stream.
+This routine returns a pointer to the element or \fBNULLPE\fR on error.
+Similarly, \fBpe2ps\fR can be used to write a presentation element at the end
+of the stream.
+This returns returns \fBOK\fR if all went well, \fBNOTOK\fR otherwise.
+On errors with either routine,
+the \fBps_errno\fR field of the stream can be consulted to see what happened.
+.PP
+When writing to a presentation stream,
+the variable \fBps_len_strategy\fR controls how long CONStructor types are
+represented.
+If this variable is equal to \fBPS_LEN_SPAG\fR (the default),
+then the indefinite form is used whenever the length field of the element can
+not be represented in one octet.
+If \fBPS_LEN_INDF\fR,
+then the indefinite form is used regardless of the length of the element.
+Otherwise,
+if \fBPS_LEN_LONG\fR,
+then the indefinite form is never used.
+.PP
+For debugging purposes,
+instead of treating a presentation stream as a binary object,
+the routines \fBpl2pe\fR and \fBpe2pl\fR can be used.
+These translate between presentation \fIlists\fR and presentation elements.
+A list is an ASCII text representation,
+with a simple LISP\-like syntax which contains semantic information
+identical to its presentation stream counterpart.
+.SH "PRESENTATION ELEMENTS"
+Once a presentation stream has been initialized and elements are being read,
+there are several routines that can be used to translate between the
+machine\-independent representation of the element and machine\-specific
+objects such as integers, strings, and the like.
+It is extremely important that programs use these routines to perform the
+translation between objects.
+They have been carefully coded to present a simple, uniform interface between
+machine\-specifics and the machine\-independent presentation protocol.
+.PP
+A new element can be created with \fBpe_alloc\fR,
+and de\-allocated with \fBpe_free\fR
+(see the warning in the \fBBUGS\fR section below).
+Two elements can be compared with \fBpe_cmp\fR,
+and an element can be copied with \fBpe_cpy\fR.
+.PP
+A \fIboolean\fR is an integer taking on the values \fB0\fR or \fB1\fR.
+The routine \fBprim2bool\fR takes an element and returns the boolean value
+encoded therein.
+Similarly, \fBbool2prim\fR takes a boolean and returns an element which
+encodes that value.
+.PP
+An \fIinteger\fR is a signed\-quantity, whose precision is specific to a
+particular host.
+The routine \fBprim2int\fR takes an element and returns the integer value
+encoded therein (if the value is \fBNOTOK\fR, check the \fBpe_errno\fR field
+of the element to see if there was an error).
+The routine \fBint2prim\fR performs the inverse operation.
+.PP
+An \fIoctetstring\fR is a pair of values,
+a character pointer and an integer length.
+The pointer addresses the first octet in the string
+(which need not be null\-terminated),
+the length indicates how many octets are in the string.
+The routine \fBprim2oct\fR takes an element and allocates a new string
+containing the value encoded therein.
+The routine \fBoct2prim\fR performs the inverse operation,
+copying the original string (and not de\-allocating it).
+.PP
+A \fIbitvector\fR is an arbitrarily long string of bits with three operations:
+\fBbit_on\fR which turns the indicated bit on,
+\fBbit_off\fR which turns the indicated bit off,
+and,
+\fBbit_test\fR which returns a boolean value telling if the indicated bit was
+on.
+The routine \fBprim2bit\fR takes an element and builds such an abstraction
+containing the value encoded therein.
+The routine \fBbit2prim\fR performs the inverse operation.
+.PP
+A \fItimestring\fR represents a date/time in many forms.
+Consult \fB<isode/psap.h>\fR for the elements in this structure.
+The routines \fBprim2utc\fR and \fButc2prim\fR are used to translate between
+a machine\-specific internal form and the machine\-independent form.
+.PP
+Two list disciplines are implemented:
+\fIsets\fR, in which each member is distinguished by a unique identifier;
+and,
+\fIsequences\fR, in which each element is distinguished by its offset from
+the head of the list.
+On both types of lists,
+the macro \fBfirst_member\fR returns the first member in the list,
+while \fBnext_member\fR returns the next member.
+.PP
+The routines \fBprim2set\fR and \fBset2prim\fR are used to translate between
+presentation elements and the set list;
+\fBset_add\fR may be called to add a new member to the set;
+\fBset_del\fR may be called to remove the identified member from the set;
+and,
+\fBset_find\fR may be called to locate the identified member.
+.PP
+The routines \fBprim2seq\fR and \fBseq2prim\fR are used to translate between
+presentation elements and the sequence list;
+\fBseq_add\fR may be called to add a new element to the sequence;
+\fBseq_del\fR may be called to remove the identified element from the sequence;
+and,
+\fBseq_find\fR may be called to locate the identified element.
+.PP
+With both lists,
+a convenient way of stepping through all the members is:
+.sp
+.in +.5i
+.nf
+.B "for (p = first_member (pe); p; p = next_member (pe, p))"
+.B "\0\0\0\0switch (\fIdiscriminator\fR) {"
+.B "\0\0\0\0\0\0\0\0...."
+.B "\0\0\0\0}"
+.fi
+.in -.5i
+.sp
+where \fIdiscriminator\fR is:
+.sp
+.in +.5i
+.B "PE_ID (p \-> pe_class, p \-> pe_id)"
+.in -.5i
+.sp
+for sets,
+and:
+.sp
+.in +.5i
+.B "p \-> pe_offset"
+.in -.5i
+.sp
+for sequences.
+.SH FILES
+None
+.SH "SEE ALSO"
+pepy(1),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO 8825:
+\fIInformation Processing \-\- Open Systems
+Interconnection \-\- Specification of basic encoding rules for Abstract Syntax
+Notation One (ASN.1)\fR,
+.br
+CCITT Recommendation X.409:
+\fIMessage Handling Systems:
+Presentation Transfer Syntax and Notation\fR
+.SH DIAGNOSTICS
+Most routines either return the manifest constant \fBNULL\fR (0) or
+\fBNOTOK\fR (\-1) on error.
+In addition,
+routines called with a pointer to a presentation stream also update the
+\fBps_errno\fR field of the stream on error.
+The routine \fBps_error\fR returns a null\-termianted diagnostic string when
+given the value of this field.
+Similarly,
+routines called with a pointer to a presentation element also update the
+\fBpe_errno\fR field of the stream on error.
+The routine \fBpe_error\fR returns a null\-termianted diagnostic string when
+given the value of this field.
+.SH AUTHOR
+Marshall T. Rose
+.SH BUGS
+A \*(lqvirtual\*(rq presentation element option should be available to avoid
+reading everything in\-core during parsing.
+.PP
+When using \fBpe_free\fR on an element,
+care must be taken to remove any references to that element in other
+structures.
+For example,
+if you have a sequence containing a sequence,
+and you free the child sequence,
+be sure to zero\-out the parent's pointer to the child,
+otherwise subsequent calls using the parent will go romping through
+hyperspace.
+
diff --git a/src/isode/psap/num2prim.c b/src/isode/psap/num2prim.c
new file mode 100644 (file)
index 0000000..9f0d152
--- /dev/null
@@ -0,0 +1,70 @@
+/* num2prim.c - integer to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:49  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:16  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:49  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     num2prim (i, class, id)
+register integer i;
+PElementClass  class;
+PElementID     id;
+{
+    register integer mask,
+                    sign,
+                    n;
+    register PElementData dp;
+    register PE            pe;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    sign = i >= 0 ? i : i ^ (-1);
+    mask = 0x1ff << (((n = sizeof i) - 1) * 8 - 1);
+    while (n > 1 && (sign & mask) == 0)
+       mask >>= 8, n--;
+
+    if ((pe -> pe_prim = PEDalloc (n)) == NULLPED) {
+       pe_free (pe);
+       return NULLPE;
+    }
+
+    for (dp = pe -> pe_prim + (pe -> pe_len = n); n-- > 0; i >>= 8)
+       *--dp = i & 0xff;
+
+    return pe;
+}
diff --git a/src/isode/psap/obj2prim.c b/src/isode/psap/obj2prim.c
new file mode 100644 (file)
index 0000000..d3c7519
--- /dev/null
@@ -0,0 +1,114 @@
+/* obj2prim.c - object identifier to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:51  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:17  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:49  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     obj2prim (o, class, id)
+register OID   o;
+PElementClass  class;
+PElementID     id;
+{
+    register int    i,
+                   m,
+                   n,
+                  *mp,
+                  *np;
+    register unsigned int j,
+                        *ip;
+    register PElementData dp,
+                         ep;
+    register PE            pe;
+
+    if (o == NULLOID
+           || o -> oid_nelem <= 1
+           || o -> oid_elements[0] > 2
+           || (o -> oid_elements[0] < 2 && o -> oid_elements[1] > 39))
+       return NULLPE;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    if ((np = (int *) malloc ((unsigned) (o -> oid_nelem) * sizeof *np))
+           == NULL) {
+       pe_free (pe);
+       return NULLPE;
+    }
+
+    for (i = n = 0, ip = o -> oid_elements, mp = np;
+           i < o -> oid_nelem;
+           i++, ip++) {
+       if (ip == o -> oid_elements)
+           j = *ip++ * 40, i++, j+= *ip;
+       else
+           j = *ip;
+       m = 0;
+       do {
+           m++;
+           j >>= 7;
+       }
+       while (j);
+       n += (*mp++ = m);
+    }
+
+    if ((pe -> pe_prim = PEDalloc (pe -> pe_len = n)) == NULLPED) {
+       free ((char *) np);
+       pe_free (pe);
+       return NULLPE;
+    }
+
+    dp = pe -> pe_prim; 
+    for (i = 0, ip = o -> oid_elements, mp = np;
+           i < o -> oid_nelem;
+           i++, ip++) {
+       if (ip == o -> oid_elements)
+           j = *ip++ * 40, i++, j += *ip;
+       else
+           j = *ip;
+
+       ep = dp + (m = *mp++) - 1;
+       for (dp = ep; m-- > 0; j >>= 7)
+           *dp-- = (j & 0x7f) | 0x80;
+       *ep &= ~0x80;
+       dp = ep + 1;
+    }
+
+    free ((char *) np);
+
+    return pe;
+}
diff --git a/src/isode/psap/objectbyname.c b/src/isode/psap/objectbyname.c
new file mode 100644 (file)
index 0000000..4b0f8bd
--- /dev/null
@@ -0,0 +1,72 @@
+/* objectbyname.c - getisobjectbyname */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:52  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:19  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:50  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+struct isobject *getisobjectbyname (descriptor)
+char   *descriptor;
+{
+    register struct isobject   *io;
+
+    isodetailor (NULLCP, 0);
+#ifdef DEBUG
+    SLOG (addr_log, LLOG_TRACE, NULLCP,
+         ("getisobjectbyname \"%s\"", descriptor));
+#endif
+
+    (void) setisobject (0);
+    while (io = getisobject ())
+       if (strcmp (descriptor, io -> io_descriptor) == 0)
+           break;
+    (void) endisobject ();
+
+    if (io) {
+#ifdef DEBUG
+       SLOG (addr_log, LLOG_DEBUG, NULLCP,
+             ("\tODE: \"%s\"\tOID: %s",
+              io -> io_descriptor, sprintoid (&io -> io_identity)));
+#endif
+    }
+    else
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("lookup of object \"%s\" failed", descriptor));
+
+    return io;
+}
diff --git a/src/isode/psap/objectbyoid.c b/src/isode/psap/objectbyoid.c
new file mode 100644 (file)
index 0000000..06391ed
--- /dev/null
@@ -0,0 +1,72 @@
+/* objectbyname.c - getisobjectbyoid */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:21  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:50  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+struct isobject *getisobjectbyoid (oid)
+register OID   oid;
+{
+    register struct isobject   *io;
+
+    isodetailor (NULLCP, 0);
+#ifdef DEBUG
+    SLOG (addr_log, LLOG_TRACE, NULLCP,
+         ("getisobjectbyoid %s", sprintoid (oid)));
+#endif
+
+    (void) setisobject (0);
+    while (io = getisobject ())
+       if (oid_cmp (oid, &io -> io_identity) == 0)
+           break;
+    (void) endisobject ();
+
+    if (io) {
+#ifdef DEBUG
+       SLOG (addr_log, LLOG_DEBUG, NULLCP,
+             ("\tODE: \"%s\"\tOID: %s",
+                   io -> io_descriptor, sprintoid (&io -> io_identity)));
+#endif
+    }
+    else
+       SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+             ("lookup of object %s failed", sprintoid (oid)));
+
+    return io;
+}
diff --git a/src/isode/psap/ode2oid.c b/src/isode/psap/ode2oid.c
new file mode 100644 (file)
index 0000000..3d4ee69
--- /dev/null
@@ -0,0 +1,143 @@
+/* ode2oid.c - object descriptor to object identifier */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:56  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:23  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:51  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "ppkt.h"
+
+/* work around define collisions */
+#undef missingP
+#undef pylose
+#include "rtpkt.h"
+
+/* work around type clashes */
+#undef missingP
+#undef pylose
+#undef toomuchP
+#define ACSE
+#define assocblk assocblkxxx
+#define newacblk newacblkxxx
+#define findacblk findacblkxxx
+#include "acpkt.h"
+
+/* \f */
+#define ODECACHESIZE 10
+static struct la_cache {
+       char    *descriptor;    
+       int     ref;
+       OID     oid;
+} Cache[ODECACHESIZE];
+
+static void preloadcache (str)
+char   *str;
+{
+    struct la_cache *cp = &Cache[0];
+    register struct isobject *io;
+
+    (void) setisobject (0);
+    while (io = getisobject ()) {
+       if (strcmp (str, io -> io_descriptor) == 0 ||
+           strcmp (DFLT_ASN, io -> io_descriptor) == 0 ||
+           strcmp (AC_ASN, io -> io_descriptor) == 0 ||
+           strcmp (BER, io -> io_descriptor) == 0 ||
+           strcmp (RT_ASN, io -> io_descriptor) == 0) {
+           if ((cp -> oid = oid_cpy (&io -> io_identity)) == NULLOID ||
+               (cp -> descriptor = malloc ((unsigned) (strlen (io -> io_descriptor) + 1)))
+               == NULLCP) {
+               if (cp -> oid) {
+                   oid_free (cp -> oid);
+                   cp -> oid = NULLOID;
+               }
+           }
+           else {
+               (void) strcpy (cp -> descriptor, io -> io_descriptor);
+               cp -> ref = 1;
+               cp ++;
+           }
+       }
+    }
+    (void) endisobject ();
+}
+
+OID    ode2oid (descriptor)
+char   *descriptor;
+{
+    register struct isobject *io;
+    int i, least;
+    struct la_cache *cp, *cpn;
+    static char firsttime = 0;
+
+    if (firsttime == 0) {
+       preloadcache (descriptor);
+       firsttime = 1;
+    }
+
+    least = Cache[0].ref;
+    for (cpn = cp = &Cache[0], i = 0; i < ODECACHESIZE; i++, cp++) {
+       if (cp -> ref < least) {
+           least = cp -> ref;
+           cpn = cp;
+       }
+       if (cp -> ref <= 0)
+               continue;
+       if (strcmp (descriptor, cp -> descriptor) == 0) {
+           cp -> ref ++;
+           return cp -> oid;
+       }
+    }
+
+    if ((io = getisobjectbyname (descriptor)) == NULL)
+       return NULLOID;
+
+    if (cpn -> oid)
+           oid_free (cpn -> oid);
+    if (cpn -> descriptor)
+           free (cpn -> descriptor);
+
+    cpn -> ref = 1;
+    if ((cpn -> oid = oid_cpy (&io -> io_identity)) == NULLOID ||
+       (cpn -> descriptor = malloc ((unsigned) (strlen (descriptor) + 1))) == NULLCP) {
+       if (cpn -> oid) {
+           oid_free (cpn -> oid);
+           cpn -> oid = NULLOID;
+       }
+        cpn -> ref = 0;
+    }
+    else
+       (void) strcpy (cpn -> descriptor, descriptor);
+
+    return (&io -> io_identity);
+}
diff --git a/src/isode/psap/oid2ode.c b/src/isode/psap/oid2ode.c
new file mode 100644 (file)
index 0000000..1bbde59
--- /dev/null
@@ -0,0 +1,65 @@
+/* oid2ode.c - object identifier to object descriptor  */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:32:58  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:24  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:51  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+char   *oid2ode_aux (identifier, quoted)
+OID    identifier;
+int    quoted;
+{
+    int            events;
+    register struct isobject *io;
+    static char buffer[BUFSIZ];
+    
+    events = addr_log -> ll_events;
+    addr_log -> ll_events = LLOG_FATAL;
+
+    io = getisobjectbyoid (identifier);
+
+    addr_log -> ll_events = events;
+
+    if (io) {
+       (void) sprintf (buffer, quoted ? "\"%s\"" : "%s",
+                       io -> io_descriptor);
+       return buffer;
+    }
+
+    return sprintoid (identifier);
+}
diff --git a/src/isode/psap/oid_cmp.c b/src/isode/psap/oid_cmp.c
new file mode 100644 (file)
index 0000000..809c113
--- /dev/null
@@ -0,0 +1,74 @@
+/* oid_cmp.c - compare two object identifiers */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:00  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:26  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:52  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    oid_cmp (p, q)
+register OID   p,
+               q;
+{
+    if (p == NULLOID)
+       return (q ? -1 : 0);
+
+    return elem_cmp (p -> oid_elements, p -> oid_nelem,
+                    q -> oid_elements, q -> oid_nelem);
+}
+
+/* \f */
+
+int    elem_cmp (ip, i, jp, j)
+register int   i,
+              j;
+register unsigned int *ip,
+                     *jp;
+{
+    while (i > 0) {
+       if (j == 0)
+           return 1;
+       if (*ip > *jp)
+           return 1;
+       else
+           if (*ip < *jp)
+               return (-1);
+
+       ip++, i--;
+       jp++, j--;
+    }
+    return (j == 0 ? 0 : -1);
+}
diff --git a/src/isode/psap/oid_cpy.c b/src/isode/psap/oid_cpy.c
new file mode 100644 (file)
index 0000000..d56bfac
--- /dev/null
@@ -0,0 +1,69 @@
+/* oid_cpy.c - copy an object identifier */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:02  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:27  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:52  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+OID    oid_cpy (q)
+register OID q;
+{
+    register unsigned int   i,
+                          *ip,
+                          *jp;
+    register OID       oid;
+
+    if (q == NULLOID)
+       return NULLOID;
+    if ((i = q -> oid_nelem) < 1)
+       return NULLOID;
+    if ((oid = (OID) malloc (sizeof *oid)) == NULLOID)
+       return NULLOID;
+
+    if ((ip = (unsigned int *) malloc ((unsigned) (i + 1) * sizeof *ip))
+           == NULL) {
+       free ((char *) oid);
+       return NULLOID;
+    }
+
+    oid -> oid_elements = ip, oid -> oid_nelem = i;
+
+    for (i = 0, jp = q -> oid_elements; i < oid -> oid_nelem; i++, jp++)
+       *ip++ = *jp;
+
+    return oid;
+}
diff --git a/src/isode/psap/oid_free.c b/src/isode/psap/oid_free.c
new file mode 100644 (file)
index 0000000..87deb41
--- /dev/null
@@ -0,0 +1,52 @@
+/* oid_free.c - free an object identifier */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:04  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:29  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    oid_free (oid)
+register OID oid;
+{
+    if (oid == NULLOID)
+       return;
+
+    if (oid -> oid_elements)
+       free ((char *) oid -> oid_elements);
+
+    free ((char *) oid);
+}
diff --git a/src/isode/psap/pe2pl.c b/src/isode/psap/pe2pl.c
new file mode 100644 (file)
index 0000000..1b92587
--- /dev/null
@@ -0,0 +1,235 @@
+/* pe2pl.c - presentation element to presentation list */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:06  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:31  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:53  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+/* Presentation lists are a human-readable, unambiguous way of describing
+   a presentation element.
+
+    SYNTAX:            list    ::      "(" class code arguments ")"
+
+                       class   ::      "UNIV" / "APPL" / "CONT" / "PRIV"
+
+                       code    ::      name / number
+
+                       name    ::      letter (letter / digit / dash)*
+
+                       number  ::      "0x" [0-f] [0-f]* /
+                                       "0" [0-7] [0-7]* /
+                                       [1-9] [0-9]* /
+                                       "\"" (IA5 subset)* "\""
+
+                       arguments::     primitive / constructor
+
+                       primitive::     number number*
+
+                       constructor::   list*
+
+   NOTE WELL:  A single "number" must be representable in no more than
+               (sizeof (int)) bytes.
+ */
+
+
+/* LINTLIBRARY */
+
+#include <ctype.h>
+#include <stdio.h>
+#include "psap.h"
+
+static int  pe2pl_aux ();
+
+#define        bf_write()      \
+    if (ps_write (ps, (PElementData) buffer, (PElementLen) strlen (buffer)) == NOTOK) \
+       return NOTOK
+
+/* \f */
+
+int    pe2pl (ps, pe)
+register PS    ps;
+register PE    pe;
+{
+    int     result;
+
+    if ((result = pe2pl_aux (ps, pe, 0)) != NOTOK)
+       result = ps_flush (ps);
+
+    return result;
+}
+
+/* \f */
+
+static int  pe2pl_aux (ps, pe, level)
+register PS    ps;
+register PE    pe;
+int    level;
+{
+    register int    i,
+                   ia5,
+                   ia5ok;
+    register char  *bp;
+    char    buffer[BUFSIZ];
+    register PE            p;
+    register PElementID id;
+    register PElementData dp,
+                         ep,
+                         fp,
+                         gp;
+
+    (void) sprintf (buffer, "%*s( %s ",
+           level * 4, "", pe_classlist[pe -> pe_class]);
+    bf_write ();
+
+    switch (pe -> pe_class) {
+       case PE_CLASS_UNIV: 
+           if ((int)(id = pe -> pe_id) < pe_maxuniv && (bp = pe_univlist[id])) {
+               if (ps_write (ps, (PElementData) bp, (PElementLen) strlen (bp))
+                       == NOTOK)
+                   return NOTOK;
+           }
+           else
+               goto no_code;
+           break;
+
+       case PE_CLASS_APPL: 
+           if ((int)(id = pe -> pe_id) < pe_maxappl && (bp = pe_applist[id])) {
+               if (ps_write (ps, (PElementData) bp, (PElementLen) strlen (bp))
+                       == NOTOK)
+                   return NOTOK;
+           }
+           else
+               goto no_code;
+
+       case PE_CLASS_PRIV: 
+           if ((int)(id = pe -> pe_id) < pe_maxpriv && (bp = pe_privlist[id])) {
+               if (ps_write (ps, (PElementData) bp, (PElementLen) strlen (bp))
+                       == NOTOK)
+                   return NOTOK;
+           }                   /* else fall */
+
+       case PE_CLASS_CONT: 
+    no_code: ;
+           (void) sprintf (buffer, "0x%x", pe -> pe_id);
+           bf_write ();
+           break;
+    }
+
+    level++;
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+       case PE_FORM_ICONS: 
+           (void) sprintf (buffer, " 0x%x%c",
+                       pe -> pe_len, pe -> pe_len ? '\n' : ' ');
+           bf_write ();
+
+           if (pe -> pe_len) {
+               ia5ok = 0;
+               if (pe -> pe_form == PE_FORM_PRIM
+                       && pe -> pe_class == PE_CLASS_UNIV)
+                   switch (pe -> pe_id) {
+                       case PE_PRIM_OCTS:
+                       case PE_DEFN_IA5S:
+                       case PE_DEFN_NUMS: 
+                       case PE_DEFN_PRTS: 
+                       case PE_DEFN_T61S:
+                       case PE_DEFN_VTXS:
+                       case PE_DEFN_VISS:
+                       case PE_DEFN_GENT:
+                       case PE_DEFN_UTCT:
+                       case PE_DEFN_GFXS:
+                       case PE_PRIM_ODE:
+                       case PE_DEFN_GENS:
+                           ia5ok = 1;
+                           break;
+
+                       default:
+                           break;
+                   }
+
+               for (ep = (dp = pe -> pe_prim) + pe -> pe_len; dp < ep;) {
+                   i = min (ep - dp, sizeof (int));
+                   if (ia5 = ia5ok) {
+                       for (gp = (fp = dp) + i; fp < gp; fp++) {
+                           switch (*fp) {
+                               case ' ':
+                                   continue;
+                               case '"':
+                                   break;
+                               default:
+                                   if (iscntrl ((u_char) *fp)
+                                           || isspace ((u_char) *fp)
+                                           || (*fp & 0x80))
+                                       break;
+                                   continue;
+                           }
+                           ia5 = 0;
+                           break;
+                       }
+                   }
+                   (void) sprintf (buffer, ia5 ? "%*s\"" : "%*s0x",
+                               level * 4, "");
+                   bp = buffer + strlen (buffer);
+                   while (i-- > 0) {
+                       (void) sprintf (bp, ia5 ? (i ? "%c" : "%c\"\n")
+                                   : (i ? "%02x" : "%02x\n"), *dp++);
+                       bp += strlen (bp);
+                   }
+                   bf_write ();
+               }
+           }
+           else
+               level = 1;
+           break;
+
+       case PE_FORM_CONS: 
+           if (p = pe -> pe_cons) {
+               if (ps_write (ps, (PElementData) "\n", (PElementLen) 1)
+                   == NOTOK)
+                   return NOTOK;
+               for (p = pe -> pe_cons; p; p = p -> pe_next)
+                   if (pe2pl_aux (ps, p, level) == NOTOK)
+                       return NOTOK;
+           }
+           else {
+               if (ps_write (ps, (PElementData) " ", (PElementLen) 1)
+                   == NOTOK)
+                   return NOTOK;
+               level = 1;
+           }
+           break;
+    }
+    level--;
+
+    (void) sprintf (buffer, "%*s)\n", level * 4, "");
+    bf_write ();
+
+    return OK;
+}
diff --git a/src/isode/psap/pe2ps.c b/src/isode/psap/pe2ps.c
new file mode 100644 (file)
index 0000000..f577bc7
--- /dev/null
@@ -0,0 +1,192 @@
+/* pe2ps.c - presentation element to presentation stream */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:09  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:33  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:54  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f   DATA */
+
+static PElement pe_eoc = { PE_CLASS_UNIV, PE_FORM_PRIM, PE_UNIV_EOC, 0 };
+static int  pe2ps_aux2 ();
+static int  ps_write_id ();
+static int  ps_write_len ();
+
+/* \f */
+
+int    pe2ps_aux (ps, pe, eval)
+register PS    ps;
+register PE    pe;
+int    eval;
+{
+    int     result;
+
+    if (eval > 0)
+       switch (pe -> pe_form) {
+           case PE_FORM_PRIM: 
+           case PE_FORM_ICONS: 
+               break;
+
+           case PE_FORM_CONS: 
+               (void) ps_get_abs (pe);
+               break;
+       }
+
+    if ((result = pe2ps_aux2 (ps, pe, eval)) != NOTOK)
+       result = ps_flush (ps);
+
+    return result;
+}
+
+
+static int  pe2ps_aux2 (ps, pe, eval)
+register PS    ps;
+register PE    pe;
+int    eval;
+{
+    register PE            p;
+
+    if (pe -> pe_form == PE_FORM_ICONS) {
+       if (ps_write_aux (ps, pe -> pe_prim, pe -> pe_len, 1) == NOTOK)
+           return NOTOK;
+
+       return OK;
+    }
+    
+    if (ps_write_id (ps, pe) == NOTOK || ps_write_len (ps, pe) == NOTOK)
+       return NOTOK;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if (ps_write_aux (ps, pe -> pe_prim, pe -> pe_len, 1) == NOTOK)
+               return NOTOK;
+           break;
+
+       case PE_FORM_CONS: 
+           if (eval < 0)
+                   break;
+           if (pe -> pe_len) {
+               for (p = pe -> pe_cons; p; p = p -> pe_next)
+                   if (pe2ps_aux2 (ps, p, 0) == NOTOK)
+                       return NOTOK;
+
+               if (pe -> pe_len == PE_LEN_INDF
+                       && pe2ps_aux2 (ps, &pe_eoc, 0) == NOTOK)
+                   return NOTOK;
+           }
+           break;
+    }
+
+    return OK;
+}
+
+/* \f */
+
+static int  ps_write_id (ps, pe)
+register PS    ps;
+register PE    pe;
+{
+    byte    buffer[1 + sizeof (PElementID)];
+    register byte  *bp = buffer;
+    PElementForm    form;
+    register PElementID id;
+
+    if ((form = pe -> pe_form) == PE_FORM_ICONS)
+       form = PE_FORM_CONS;
+    *bp = ((pe -> pe_class << PE_CLASS_SHIFT) & PE_CLASS_MASK)
+               | ((form << PE_FORM_SHIFT) & PE_FORM_MASK);
+
+    if ((id = pe -> pe_id) < PE_ID_XTND)
+       *bp++ |= id;
+    else {
+       register byte *ep;
+       register PElementID jd;
+
+       *bp |= PE_ID_XTND;
+
+       ep = buffer;
+       for (jd = id; jd != 0; jd >>= PE_ID_SHIFT)
+           ep++;
+
+       for (bp = ep; id != 0; id >>= PE_ID_SHIFT)
+           *bp-- = id & PE_ID_MASK;
+       for (bp = buffer + 1; bp < ep; bp++)
+           *bp |= PE_ID_MORE;
+
+       bp = ++ep;
+    }
+
+    if (ps_write (ps, buffer, bp - buffer) == NOTOK)
+       return NOTOK;
+
+    return OK;
+}
+
+/* \f */
+
+/* probably should integrate the non-PE_LEN_SMAX case with the algorithm in
+   num2prim() for a single, unified routine */
+
+static int  ps_write_len (ps, pe)
+register PS    ps;
+register PE    pe;
+{
+    byte    buffer[1 + sizeof (PElementLen)];
+    register byte  *bp = buffer,
+                  *ep;
+    register PElementLen len;
+
+    if ((len = pe -> pe_len) == PE_LEN_INDF)
+       *bp++ = PE_LEN_XTND;
+    else
+       if (len <= PE_LEN_SMAX)
+           *bp++ = len & 0xff;
+       else {
+           ep = buffer + sizeof buffer - 1;
+           for (bp = ep; len != 0 && buffer < bp; len >>= 8)
+               *bp-- = len & 0xff;
+           *bp = PE_LEN_XTND | ((ep - bp) & 0xff);
+           if (ps_write (ps, bp, ep - bp + 1) == NOTOK)
+               return NOTOK;
+
+           return OK;
+       }
+
+    if (ps_write (ps, buffer, bp - buffer) == NOTOK)
+       return NOTOK;
+
+    return OK;
+}
diff --git a/src/isode/psap/pe2qb_f.c b/src/isode/psap/pe2qb_f.c
new file mode 100644 (file)
index 0000000..85135be
--- /dev/null
@@ -0,0 +1,134 @@
+/* pe2qb_f.c - presentation element to qbuf, the qbuf must be one piece. */
+
+/*
+ *                                NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include "psap.h"
+
+/* \f   DATA */
+
+#define moveit(c, l)        if(Qcp + l > Ecp) { \
+                               (void) printf("pe2qb_f: Qcp %o Ecp %o len %d\n", \
+                                       Qcp, Ecp, l); \
+                               return(NOTOK); \
+                           } \
+                           if(l == 1) { \
+                               *Qcp++ = *c; \
+                               Len++; \
+                           }  \
+                           else { \
+                                   bcopy((char *)c, Qcp, l); \
+                                   Qcp += l; \
+                                   Len  += l; \
+                           }
+
+static PElement pe_eoc = { PE_CLASS_UNIV, PE_FORM_PRIM, PE_UNIV_EOC, 0 };
+
+char *Qcp, *Ecp;
+
+int Len;
+
+/* \f */
+
+int    pe2qb_f (pe)
+register PE    pe;
+{
+    register PE            p;
+    register int elm_len;
+    byte    elmbuffer[1 + sizeof(PElementLen)];
+    register byte  *bp,  *ep;
+    PElementForm    form;
+    register PElementID id;
+    register PElementLen len;
+
+    if ((form = pe -> pe_form) == PE_FORM_ICONS) {
+       elm_len = pe->pe_len;
+       moveit(pe->pe_prim, elm_len);
+       return(Len);
+    }
+
+    /* Put the id into the qbuf */
+
+    *Qcp = ((pe -> pe_class << PE_CLASS_SHIFT) & PE_CLASS_MASK)
+               | ((form << PE_FORM_SHIFT) & PE_FORM_MASK);
+
+    if ((id = pe -> pe_id) < PE_ID_XTND) {
+       *Qcp++ |= id;
+       Len++;
+    }
+    else {
+        byte    idbuffer[1 + sizeof (PElementID)];
+       register PElementID jd;
+
+       ep = (bp = idbuffer);
+       *bp = *Qcp | PE_ID_XTND;
+       for (jd = id; jd != 0; jd >>= PE_ID_SHIFT)
+           ep++;
+
+       for (bp = ep; id != 0; id >>= PE_ID_SHIFT)
+           *bp-- = id & PE_ID_MASK;
+       for (bp = idbuffer + 1; bp < ep; bp++)
+           *bp |= PE_ID_MORE;
+
+       bp = ++ep;
+        elm_len = bp - idbuffer;
+        moveit(idbuffer, elm_len);
+    }
+
+
+    /* Put the length into the qbuf */
+
+    if ((len = pe -> pe_len) == PE_LEN_INDF) {
+       *Qcp++ = PE_LEN_XTND;
+       Len++;
+    }
+    else
+       if (len <= PE_LEN_SMAX) {
+           *Qcp++ = len & 0xff;
+           Len++;
+       }
+       else {
+           ep = elmbuffer + sizeof elmbuffer - 1;
+           for (bp = ep; len != 0 && elmbuffer < bp; len >>= 8)
+               *bp-- = len & 0xff;
+           *bp = PE_LEN_XTND | ((ep - bp) & 0xff);
+           elm_len = ep - bp + 1;
+           moveit(bp, elm_len);
+       }
+
+    /* Now put the actual value into the qbuf */
+    
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           elm_len = pe->pe_len;
+           moveit(pe->pe_prim, elm_len);
+           break;
+
+       case PE_FORM_CONS: 
+           if (pe -> pe_len) {
+               for (p = pe -> pe_cons; p; p = p -> pe_next)
+                   if (pe2qb_f (p) == NOTOK)
+                       return NOTOK;
+
+               if (pe -> pe_len == PE_LEN_INDF
+                       && pe2qb_f (&pe_eoc) == NOTOK)
+                   return NOTOK;
+           }
+           break;
+
+       default:
+           abort();
+    }
+
+    return(Len);
+}
diff --git a/src/isode/psap/pe2ssdu.c b/src/isode/psap/pe2ssdu.c
new file mode 100644 (file)
index 0000000..ace6670
--- /dev/null
@@ -0,0 +1,73 @@
+/* pe2ssdu.c - write a PE to a SSDU */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:13  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:36  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:55  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+int    pe2ssdu (pe, base, len)
+register PE pe;
+char  **base;
+int    *len;
+{
+    register int plen, ret;
+
+    *len = 0;
+    plen  = ps_get_abs (pe);
+    Qcp = (char *)malloc((unsigned)plen);
+    *base = Qcp;
+
+    if (Qcp == NULL)
+        return NOTOK;
+
+    Len = 0;
+    Ecp = Qcp + plen;
+    if ((ret = pe2qb_f(pe)) != plen) {
+        (void) printf("pe2ssdu: bad length returned %d should be %d\n",
+                ret, plen);
+       return NOTOK;
+    }
+    *len = plen;
+
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_PDUS)
+       pe2text (psap_log, pe, 0, *len);
+#endif
+
+    return OK;
+}
diff --git a/src/isode/psap/pe2text.c b/src/isode/psap/pe2text.c
new file mode 100644 (file)
index 0000000..beff7d7
--- /dev/null
@@ -0,0 +1,122 @@
+/* pe2text.c - write a PE thru a debug filter */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:16  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:37  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:55  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "logger.h"
+
+/* \f */
+
+/* logfile-backed abstract for PStreams */
+
+/* ARGSUSED */
+
+static int  ll_pswrite (ps, data, n, in_line)
+PS     ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    register LLog    *lp = (LLog *) ps -> ps_addr;
+
+    if (lp -> ll_stat & LLOGTTY) {
+       (void) fflush (stdout);
+
+       (void) fwrite ((char *) data, sizeof *data, (int) n, stderr);
+       (void) fflush (stderr);
+    }
+
+    if (lp -> ll_fd == NOTOK) {
+       if ((lp -> ll_stat & (LLOGERR | LLOGTTY)) == (LLOGERR | LLOGTTY))
+           return ((int) n);
+       if (ll_open (lp) == NOTOK)
+           return NOTOK;
+    }
+    else
+       if (ll_check (lp) == NOTOK)
+           return NOTOK;
+
+    return write (lp -> ll_fd, (char *) data, (int) n);
+}
+
+/* \f */
+
+static int  ll_psopen (ps)
+register PS ps;
+{
+    ps -> ps_writeP = ll_pswrite;
+
+    return OK;
+}
+
+#define        ll_psetup(ps, lp)       ((ps) -> ps_addr = (caddr_t) (lp), OK)
+
+/* \f */
+
+void   pe2text (lp, pe, rw, cc)
+register LLog *lp;
+register PE pe;
+int    rw,
+       cc;
+{
+    register char   *bp;
+    char   buffer[BUFSIZ];
+    register PS ps;
+
+    bp = buffer;
+    (void) sprintf (bp, "%s PE", rw ? "read" : "wrote");
+    bp += strlen (bp);
+    if (pe -> pe_context != PE_DFLT_CTX) {
+       (void) sprintf (bp, ", context %d", pe -> pe_context);
+       bp += strlen (bp);
+    }
+    if (cc != NOTOK) {
+       (void) sprintf (bp, ", length %d", cc);
+       bp += strlen (bp);
+    }
+    LLOG (lp, LLOG_ALL, ("%s", buffer));
+
+    if ((ps = ps_alloc (ll_psopen)) != NULLPS) {
+       if (ll_psetup (ps, lp) != NOTOK)
+           (void) pe2pl (ps, pe);
+
+       ps_free (ps);
+    }
+
+    (void) ll_printf (lp, "-------\n");
+
+    (void) ll_sync (lp);
+}
diff --git a/src/isode/psap/pe2uvec.c b/src/isode/psap/pe2uvec.c
new file mode 100644 (file)
index 0000000..a81025b
--- /dev/null
@@ -0,0 +1,95 @@
+/* pe2uvec.c - write a PE to a udvec */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:18  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:39  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:56  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+int    pe2uvec (pe, uv)
+register PE pe;
+struct udvec **uv;
+{
+    int            cc;
+#ifdef DEBUG
+    int            len;
+#endif
+    register PS        ps;
+
+    *uv = NULL;
+
+    if ((ps = ps_alloc (uvec_open)) == NULLPS)
+       return NOTOK;
+    cc = ps_get_abs (pe) - ps_get_plen (pe);
+#ifdef DEBUG
+    len = ps -> ps_byteno;
+#endif
+    if (uvec_setup (ps, cc) == NOTOK || pe2ps_aux (ps, pe, 0) == NOTOK) {
+       ps_free (ps);
+       return NOTOK;
+    }
+
+    *uv = ps -> ps_head;
+#ifdef DEBUG
+    len = ps -> ps_byteno - len;
+#endif
+
+    ps -> ps_head = NULL;
+    ps -> ps_extra = NULL;
+    ps_free (ps);
+
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_PDUS) {
+       register int    i,
+                       j,
+                       k;
+       register struct udvec *vv;
+
+       i = j = k = 0;
+       for (vv = *uv; vv -> uv_base; vv++, i++)
+           if (vv -> uv_inline)
+               j++, k += vv -> uv_len;
+
+       LLOG (psap_log, LLOG_PDUS,
+             ("PE written in %d elements, %d inline (%d octet%s)",
+              i, j, k, k != 1 ? "s" : ""));
+       pe2text (psap_log, pe, 0, len);
+    }
+#endif
+
+    return OK;
+}
diff --git a/src/isode/psap/pe_alloc.c b/src/isode/psap/pe_alloc.c
new file mode 100644 (file)
index 0000000..4be1c0f
--- /dev/null
@@ -0,0 +1,123 @@
+/* pe_alloc.c - allocate a presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:20  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:40  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:56  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+
+/* A Presentation Element (or PElement) is an internal representation for
+   a presentation type from ISO8825.  The fields of the structure are:
+
+       pe_class:       UNIVersal, APPLication, CONText, or PRIVate
+       pe_form:        PRIMative, CONStructor, InlineCONStructor
+       pe_id:          identifier
+
+       pe_len:         if a PRIMative, then the length of pe_prim,
+                       else a scratch value; "indefinite" length elements
+                       have a pe_len of -1 (PE_LEN_INDF)
+       pe_ilen:        if an InlineCONStructor, then the offset to the real
+                       data portion
+
+       pe_prim:        if a PRIMative or an Inline CONStructor, the
+                       byte-string
+       pe_cons:        if a CONStructor, the first element in the
+                       singly-linked list of elements
+
+       pe_next:        if the immediate parent is a constructor, the
+                       next element in the singly-linked list of elements
+
+       pe_cardinal:    if a LIST (SET or SEQ CONStructor), the cardinality
+                       of the list
+       pe_offset:      if a member of a SEQ LIST, the offset in the SEQUENCE
+
+       pe_nbits:       if a BITSTRING, the number of bits in the string
+
+       pe_refcnt:      a hack for ANYs in pepy
+ */
+
+#define PE_LIST_CNT 100
+
+
+int    pe_allocs;
+int    pe_frees;
+int    pe_most;
+
+PE     pe_list = NULLPE;
+#ifdef DEBUG
+PE     pe_active = NULLPE;
+#endif
+
+/* \f */
+
+PE     pe_alloc (class, form, id)
+PElementClass class;
+PElementForm  form;
+PElementID id;
+{
+    register int    i;
+    register PE            pe;
+
+    if (pe = pe_list)
+        pe_list = pe -> pe_next;
+    else {
+        pe_list = (pe = (PE) calloc (PE_LIST_CNT, sizeof *pe));
+        if (pe == NULLPE)
+           return NULLPE;
+
+        for (i = 0; i < (PE_LIST_CNT - 1); i++, pe++)
+           pe -> pe_next = pe + 1;
+
+        pe = pe_list;
+        pe_list = pe -> pe_next;
+    }
+
+    bzero ((char *)pe, sizeof *pe);
+    pe -> pe_class = class;
+    pe -> pe_form = form;
+    pe -> pe_id = id;
+
+    if ((i = ++pe_allocs - pe_frees) > pe_most)
+        pe_most = i;
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_DEBUG) {
+       pe -> pe_link = pe_active;
+       pe_active = pe;
+    }
+#endif
+
+    return pe;
+}
diff --git a/src/isode/psap/pe_cmp.c b/src/isode/psap/pe_cmp.c
new file mode 100644 (file)
index 0000000..4baacb7
--- /dev/null
@@ -0,0 +1,84 @@
+/* pe_cmp.c - compare two presentation elements */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:22  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:42  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:57  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    pe_cmp (p, q)
+register PE    p,
+               q;
+{
+    register int    i;
+
+    if (p == NULLPE)
+       return (q ? 1 : 0);
+    if (q == NULLPE
+           || p -> pe_class != q -> pe_class
+           || p -> pe_form != q -> pe_form
+           || p -> pe_id != q -> pe_id)
+       return 1;
+
+/* XXX: perhaps compare pe_context ??? */
+
+    switch (p -> pe_form) {
+       case PE_FORM_ICONS:
+           if (p -> pe_ilen != q -> pe_ilen)
+               return 1;
+           /* else fall */
+       case PE_FORM_PRIM: 
+           if (i = p -> pe_len) {
+               if (i != q -> pe_len || PEDcmp (p -> pe_prim, q -> pe_prim, i))
+                   return 1;
+           }
+           else
+               if (q -> pe_len)
+                   return 1;
+           return 0;
+
+       case PE_FORM_CONS: 
+           for (p = p -> pe_cons, q = q -> pe_cons;
+                   p;
+                   p = p -> pe_next, q = q -> pe_next)
+               if (pe_cmp (p, q))
+                   return 1;
+           return (q ? 1 : 0);
+
+       default:                /* XXX */
+           return 1;
+    }
+}
diff --git a/src/isode/psap/pe_cpy.c b/src/isode/psap/pe_cpy.c
new file mode 100644 (file)
index 0000000..6d3da84
--- /dev/null
@@ -0,0 +1,83 @@
+/* pe_cpy.c - copy a presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:24  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:43  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:57  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     pe_cpy (pe)
+register PE    pe;
+{
+    register PE            p,
+                  *q,
+                   r;
+
+    if ((p = pe_alloc (pe -> pe_class, pe -> pe_form, pe -> pe_id)) == NULLPE)
+       return NULLPE;
+
+    p -> pe_context = pe -> pe_context;
+
+    p -> pe_len = pe -> pe_len;
+    switch (p -> pe_form) {
+       case PE_FORM_ICONS:
+           p -> pe_ilen = pe -> pe_ilen;
+           /* and fall */
+       case PE_FORM_PRIM: 
+           if (pe -> pe_prim == NULLPED)
+               break;
+           if ((p -> pe_prim = PEDalloc (p -> pe_len)) == NULLPED)
+               goto you_lose;
+           PEDcpy (pe -> pe_prim, p -> pe_prim, p -> pe_len);
+           break;
+
+       case PE_FORM_CONS: 
+           for (q = &p -> pe_cons, r = pe -> pe_cons;
+                   r;
+                   q = &((*q) -> pe_next), r = r -> pe_next)
+               if ((*q = pe_cpy (r)) == NULLPE)
+                   goto you_lose;
+           break;
+    }
+
+    p -> pe_nbits = pe -> pe_nbits;
+
+    return p;
+
+you_lose: ;
+    pe_free (p);
+    return NULLPE;
+}
diff --git a/src/isode/psap/pe_error.c b/src/isode/psap/pe_error.c
new file mode 100644 (file)
index 0000000..3c74cfd
--- /dev/null
@@ -0,0 +1,76 @@
+/* pe_error.c - presentation element error to string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:45  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+/* \f */
+
+static char *pe_errorlist[] = {
+    "Error 0",
+    "Overflow",
+    "Out of memory",
+    "No such bit",
+    "Malformed universal timestring",
+    "Malformed generalized timestring",
+    "No such member",
+    "Not a primitive form",
+    "Not a constructor form",
+    "Class/ID mismatch in constructor",
+    "Malformed object identifier",
+    "Malformed bitstring",
+    "Type not supported",
+    "Signed integer not expected"
+};
+
+static int pe_maxerror = sizeof pe_errorlist / sizeof pe_errorlist[0];
+
+/* \f */
+
+char   *pe_error (c)
+int    c;
+{
+    register char  *bp;
+    static char buffer[30];
+
+    if (c < pe_maxerror && (bp = pe_errorlist[c]))
+       return bp;
+
+    (void) sprintf (buffer, "Error %d", c);
+    return buffer;
+}
diff --git a/src/isode/psap/pe_expunge.c b/src/isode/psap/pe_expunge.c
new file mode 100644 (file)
index 0000000..c72e9c9
--- /dev/null
@@ -0,0 +1,62 @@
+/* pe_expunge.c - expunge a PE */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:28  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:46  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:58  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     pe_expunge (pe, r)
+PE     pe,
+       r;
+{
+    if (r) {
+       if (pe == r)
+           return r;
+
+       if (pe_extract (pe, r))
+           if (pe -> pe_realbase && !r -> pe_realbase) {
+               r -> pe_realbase = pe -> pe_realbase;
+               pe -> pe_realbase = NULL;
+           }
+
+       r -> pe_refcnt++;
+    }
+
+    pe_free (pe);
+
+    return r;
+}
diff --git a/src/isode/psap/pe_extract.c b/src/isode/psap/pe_extract.c
new file mode 100644 (file)
index 0000000..200f808
--- /dev/null
@@ -0,0 +1,72 @@
+/* pe_extract.c - extract a PE */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:30  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:48  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:59  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+/* assumes that q appears at most once directly under p... */
+
+int    pe_extract (pe, r)
+PE     pe,
+       r;
+{
+    register PE           *p,
+                   q;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+       case PE_FORM_ICONS: 
+           break;
+
+       case PE_FORM_CONS: 
+           for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next)
+               if (q == r) {
+                   (*p) = q -> pe_next;
+                   q -> pe_next = NULLPE;
+                   if (r->pe_refcnt > 0)
+                           r->pe_refcnt--;
+                   return 1;
+               }
+               else
+                   if (pe_extract (q, r))
+                       return 1;
+           break;
+    }
+
+    return 0;
+}
diff --git a/src/isode/psap/pe_free.c b/src/isode/psap/pe_free.c
new file mode 100644 (file)
index 0000000..2f16790
--- /dev/null
@@ -0,0 +1,114 @@
+/* pe_free.c - free a presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:32  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:49  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:46:59  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+int    pe_free (pe)
+register PE    pe;
+{
+    register PE            p,
+                   q;
+    register struct qbuf *qb,
+                         *qp;
+
+    if (!pe)
+        abort ();
+
+    if( pe->pe_refcnt < 0) {
+      DLOG (psap_log, LLOG_DEBUG,
+           ("WARNING: duplicately free'd pe 0x%x!", pe));
+      return;
+    }
+
+    if (pe -> pe_refcnt-- > 0)
+       return;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+       case PE_FORM_ICONS: 
+           if (pe -> pe_prim && !pe -> pe_inline)
+               PEDfree (pe -> pe_prim);
+            else
+               if (pe -> pe_inline && Hqb) {
+                   if(Fqb && (--Qbrefs == 0)) {
+                       for (qb = Fqb; qb && (qb != Hqb); qb = qp) {
+                           qp = qb -> qb_forw;
+                           free ((char *) qb);
+                       }
+                       if (!qb)
+                           abort ();
+                       Fqb = Hqb = NULL;
+                   }
+               }
+           break;
+
+       case PE_FORM_CONS: 
+           for (p = pe -> pe_cons; p; p = q) {
+               q = p -> pe_next;
+               pe_free (p);
+           }
+           break;
+
+        default:
+            abort();
+           /* NOTREACHED */
+    }
+
+    if (pe -> pe_realbase)
+       free (pe -> pe_realbase);
+       
+    pe_frees++;
+    pe -> pe_next = pe_list;
+    pe_list = pe;
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_DEBUG) {
+       PE     *pep;
+
+       for (pep = &pe_active; p = *pep; pep = &p -> pe_link)
+           if (p == pe) {
+               *pep = p -> pe_link;
+               break;
+           }
+       if (!p)
+           DLOG (psap_log, LLOG_DEBUG,
+                 ("WARNING: free'd pe (0x%x) not on active list", pe));
+    }
+#endif
+}
diff --git a/src/isode/psap/pe_pullup.c b/src/isode/psap/pe_pullup.c
new file mode 100644 (file)
index 0000000..e628bdb
--- /dev/null
@@ -0,0 +1,121 @@
+/* pe_pullup.c - "pullup" a presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:34  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:51  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:00  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+PElementData   pe_pullup_aux ();
+
+/* \f */
+
+int    pe_pullup (pe)
+register PE    pe;
+{
+    PElementLen            len;
+    register PElementData dp;
+    register PE            p;
+
+    if (pe -> pe_form != PE_FORM_CONS)
+       return OK;
+
+    if ((dp = pe_pullup_aux (pe, &len)) == NULLPED)
+       return NOTOK;
+
+    for (p = pe -> pe_cons; p; p = p -> pe_next)
+       pe_free (p);
+
+    pe -> pe_form = PE_FORM_PRIM;
+    pe -> pe_len = len;
+    pe -> pe_prim = dp;
+
+    return OK;
+}
+
+/* \f */
+
+static PElementData  pe_pullup_aux (pe, len)
+register PE    pe;
+register int   *len;
+{
+    register int    i,
+                    k;
+    int     j;
+    register PElementClass class;
+    register PElementID id;
+    register PElementData dp,
+                         ep,
+                         fp;
+    register PE            p;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if ((dp = PEDalloc (i = pe -> pe_len)) == NULLPED)
+               return NULLPED;
+           PEDcpy (pe -> pe_prim, dp, i);
+           break;
+
+       case PE_FORM_CONS: 
+           dp = NULLPED, i = 0;
+           class = pe -> pe_class, id = pe -> pe_id;
+           for (p = pe -> pe_cons; p; p = p -> pe_next) {
+               if (p -> pe_class != class
+                       || p -> pe_id != id
+                       || (ep = pe_pullup_aux (p, &j)) == NULLPED) {
+                   if (dp)
+                       PEDfree (dp);
+                   return NULLPED;
+               }
+               if (dp) {
+                   if ((fp = PEDrealloc (dp, k = i + j)) == NULLPED) {
+                       PEDfree (dp);
+                       return NULLPED;
+                   }
+                   PEDcpy (ep, fp + i, j);
+                   dp = fp, i = k;
+               }
+               else
+                   dp = ep, i += j;
+           }
+           break;
+
+       case PE_FORM_ICONS:
+           return NULLPED;
+    }
+
+    *len = i;
+    return (dp);
+}
diff --git a/src/isode/psap/pl2pe.c b/src/isode/psap/pl2pe.c
new file mode 100644 (file)
index 0000000..9c503d1
--- /dev/null
@@ -0,0 +1,484 @@
+/* pl2pe.c - presentation list to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:52  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:01  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+/* Presentation lists are a human-readable, unambiguous way of describing
+   a presentation element.
+
+    SYNTAX:            list    ::      "(" class code arguments ")"
+
+                       class   ::      "UNIV" / "APPL" / "CONT" / "PRIV"
+
+                       code    ::      name / number
+
+                       name    ::      letter (letter / digit / dash)*
+
+                       number  ::      "0x" [0-f] [0-f]* /
+                                       "0" [0-7] [0-7]* /
+                                       [1-9] [0-9]* /
+                                       "\"" (IA5 subset)* "\""
+
+                       arguments::     primitive / constructor
+
+                       primitive::     number number*
+
+                       constructor::   list*
+
+   NOTE WELL:  A single "number" must be representable in no more than
+               (sizeof (int)) bytes.
+ */
+
+
+/* LINTLIBRARY */
+
+#include <ctype.h>
+#include <stdio.h>
+#include "psap.h"
+
+/* \f   DATA */
+
+typedef struct PList {
+    u_char pl_code;
+#define        PL_CODE_LPAR    0
+#define        PL_CODE_NAME    1
+#define        PL_CODE_NUM     2
+#define        PL_CODE_RPAR    3
+
+    union {
+       char    un_pl_name[BUFSIZ];
+       int     un_pl_num;
+    }                       pl_un;
+#define        pl_name pl_un.un_pl_name
+#define        pl_num  pl_un.un_pl_num
+}                      PList, *PL;
+
+
+PE  pl2pe_aux ();
+static int pl_read_class ();
+static int pl_read_id ();
+static int  pl_read_name ();
+static int  pl_read_cons ();
+static int  pl_read_prim ();
+static int  pl_read_lex ();
+static int pl_read ();
+
+/* \f */
+
+PE     pl2pe (ps)
+register PS    ps;
+{
+    struct PList    pls;
+    register PL            pl = &pls;
+
+    if (pl_read_lex (ps, pl) == NOTOK) {
+       if (ps -> ps_errno == PS_ERR_EOF)
+           ps -> ps_errno = PS_ERR_NONE;
+       return NULLPE;
+    }
+    if (pl -> pl_code != PL_CODE_LPAR)
+       return ps_seterr (ps, PS_ERR_XXX, NULLPE);
+
+    return pl2pe_aux (ps, pl);
+}
+    
+/* \f */
+
+static PE  pl2pe_aux (ps, pl)
+register PS    ps;
+register PL    pl;
+{
+    PElementClass   class;
+    PElementID     id;
+    register PE            pe;
+
+    if (pl_read_class (ps, pl, &class) == NOTOK)
+       return NULLPE;
+    if (pl_read_id (ps, pl, class, &id) == NOTOK)
+       return NULLPE;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return ps_seterr (ps, PS_ERR_NMEM, NULLPE);
+
+    if (pl_read_lex (ps, pl) == NOTOK)
+       return NULLPE;
+    switch (pl -> pl_code) {
+       case PL_CODE_LPAR: 
+           if (pl_read_cons (ps, pl, &pe -> pe_cons) == NOTOK)
+               goto you_lose;  /* else fall */
+       case PL_CODE_RPAR: 
+           pe -> pe_form = PE_FORM_CONS;
+           break;
+
+       case PL_CODE_NUM: 
+           if (pl_read_prim (ps, pl, pe) == NOTOK)
+               goto you_lose;
+           break;
+
+       default: 
+           ps -> ps_errno = PS_ERR_XXX;
+           goto you_lose;
+    }
+    return pe;
+
+you_lose: ;
+    pe_free (pe);
+    return NULLPE;
+}
+
+/* \f */
+
+static int pl_read_class (ps, pl, class)
+register PS    ps;
+register PL    pl;
+register PElementClass *class;
+{
+    register int    i;
+
+    if (pl_read_lex (ps, pl) == NOTOK)
+       return NOTOK;
+    if (pl -> pl_code != PL_CODE_NAME)
+       return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+
+    if ((i = pl_read_name (pl -> pl_name, pe_classlist, pe_maxclass)) == NOTOK)
+       return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+
+    *class = i;
+    return OK;
+}
+
+/* \f */
+
+static int pl_read_id (ps, pl, class, id)
+register PS    ps;
+register PL    pl;
+register PElementClass class;
+register PElementID *id;
+{
+    register int    i;
+    register char **list;
+
+    if (pl_read_lex (ps, pl) == NOTOK)
+       return NOTOK;
+    switch (pl -> pl_code) {
+       case PL_CODE_NAME: 
+           switch (class) {
+               case PE_CLASS_UNIV: 
+                   list = pe_univlist, i = pe_maxuniv;
+                   break;
+               case PE_CLASS_APPL: 
+                   list = pe_applist, i = pe_maxappl;
+                   break;
+               default: 
+                   list = NULL, i = 0;
+                   break;
+               case PE_CLASS_PRIV:
+                   list = pe_privlist, i = pe_maxpriv;
+                   break;
+           }
+           if ((i = pl_read_name (pl -> pl_name, list, i)) == NOTOK)
+               return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+           break;
+
+       case PL_CODE_NUM: 
+           i = pl -> pl_num;
+           break;
+
+       default: 
+           return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+    }
+
+    *id = i;
+    return OK;
+}
+
+/* \f */
+
+static int  pl_read_name (name, list, n)
+register char *name,
+            **list;
+register int   n;
+{
+    register int    i;
+    register char  *bp;
+
+    for (i = n; i > 0; i--)
+       if ((bp = *list++) && strcmp (bp, name) == 0)
+           return (n - i);
+
+    return NOTOK;
+}
+
+/* \f */
+
+static int  pl_read_cons (ps, pl, pe)
+register PS    ps;
+register PL    pl;
+register PE    *pe;
+{
+    register PE            p,
+                   q;
+
+    if ((p = pl2pe_aux (ps, pl)) == NULLPE)
+       return NOTOK;
+    *pe = p;
+
+    for (q = p;; q = q -> pe_next = p) {
+       if (pl_read_lex (ps, pl) == NOTOK)
+           return NOTOK;
+       switch (pl -> pl_code) {
+           case PL_CODE_LPAR: 
+               if ((p = pl2pe_aux (ps, pl)) == NULLPE)
+                   return NOTOK;
+               break;
+
+           default: 
+               return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+
+           case PL_CODE_RPAR: 
+               return OK;
+       }
+    }
+}
+
+/* \f */
+
+static int  pl_read_prim (ps, pl, pe)
+register PS    ps;
+register PL    pl;
+register PE    pe;
+{
+    register int    i,
+                    len,
+                    n;
+    register PElementData dp,
+                         ep;
+
+    if ((len = pl -> pl_num) == 0)
+       goto out;
+    if ((dp = PEDalloc (len)) == NULLPED)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+
+    pe -> pe_prim = dp, pe -> pe_len = len;
+
+    for (ep = dp + len; dp < ep;) {
+       i = min (ep - dp, sizeof (int));
+       if (pl_read_lex (ps, pl) == NOTOK)
+           return NOTOK;
+       if (pl -> pl_code != PL_CODE_NUM)
+           return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+       n = pl -> pl_num;
+       while (i-- > 0)
+           *dp++ = (n >> (i * 8)) & 0xff;
+    }
+
+out: ;
+    if (pl_read_lex (ps, pl) == NOTOK)
+       return NOTOK;
+    if (pl -> pl_code != PL_CODE_RPAR)
+       return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+
+    return OK;
+}
+
+/* \f */
+
+#ifdef XXX
+static int  pl_read_lex (ps, pl)
+register PS    ps;
+register PL    pl;
+{
+    int     i = pl_read_lex_aux (ps, pl);
+
+    (void) fprintf (stderr, "pl_read_lex returns ");
+    if (i == NOTOK) {
+       (void) fprintf (stderr, "NOTOK [%s]\n", ps_error (ps -> ps_errno));
+       return NOTOK;
+    }
+    switch (pl -> pl_code) {
+       case PL_CODE_LPAR: 
+           (void) fprintf (stderr, "LPAR");
+           break;
+       case PL_CODE_RPAR: 
+           (void) fprintf (stderr, "RPAR");
+           break;
+       case PL_CODE_NAME: 
+           (void) fprintf (stderr, "NAME \"%s\"", pl -> pl_name);
+           break;
+       case PL_CODE_NUM: 
+           (void) fprintf (stderr, "NUM 0x%x", pl -> pl_num);
+           break;
+       default: 
+           (void) fprintf (stderr, "code %d", pl -> pl_code);
+           break;
+    }
+    (void) fprintf (stderr, "\n");
+    if (pl -> pl_code == PL_CODE_RPAR)
+       sleep(1);
+
+    return i;
+}
+
+#define        pl_read_lex     pl_read_lex_aux
+#endif
+
+/* \f */
+
+static int  pl_read_lex (ps, pl)
+register PS    ps;
+register PL    pl;
+{
+    register int    base,
+                    n;
+    register char  *bp;
+    byte    c;
+
+    do {
+       if (pl_read (ps, &c) == NOTOK)
+           return NOTOK;
+    } while (isspace ((u_char) c));
+
+    switch (c) {
+       case '(': 
+           pl -> pl_code = PL_CODE_LPAR;
+           return OK;
+       case ')': 
+           pl -> pl_code = PL_CODE_RPAR;
+           return OK;
+
+       case ';':
+           do {
+               if (pl_read (ps, &c) == NOTOK)
+                   return NOTOK;
+           } while (c != '\n');
+           return pl_read_lex (ps, pl);
+
+       default: 
+           if (isalpha ((u_char) c)) {
+               pl -> pl_code = PL_CODE_NAME;
+               bp = pl -> pl_name;
+               while (isalnum ((u_char) c) || c == '-') {
+                   *bp++ = c;
+                   if (pl_read (ps, &c) == NOTOK)
+                       return NOTOK;
+               }
+               *bp = NULL;
+               ps -> ps_scratch = c;
+               return OK;
+           }
+
+           if (c == '"') {
+               pl -> pl_code = PL_CODE_NUM;
+               for (n = 0;;) {
+                   if (pl_read (ps, &c) == NOTOK)
+                       return NOTOK;
+                   if (c == '"') {
+                       pl -> pl_num = n;
+                       return OK;
+                   }
+                   n = (n << 8) | (c & 0xff);
+               }
+           }
+
+           if (!isdigit ((u_char) c))
+               return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+
+           pl -> pl_code = PL_CODE_NUM;
+           if (c == '0') {
+               if (pl_read (ps, &c) == NOTOK)
+                   return NOTOK;
+               if (c == 'x' || c == 'X') {
+                   base = 16;
+                   if (pl_read (ps, &c) == NOTOK)
+                       return NOTOK;
+               }
+               else {
+                   base = 8;
+                   if (c < '0' || c > '7') {
+                       pl -> pl_num = 0;
+                       ps -> ps_scratch = c;
+                       return OK;
+                   }
+               }
+           }
+           else
+               base = 10;
+
+           for (n = 0;;) {
+               switch (base) {
+                   case 10: 
+                       if (c < '0' || c > '9')
+                           return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+                       break;
+
+                   case 8: 
+                       if (c < '0' || c > '7')
+                           return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+                       break;
+
+                   case 16: 
+                       if (c >= '0' && c <= '9')
+                           break;
+                       if (c >= 'A' && c <= 'F')
+                           c += 'a' - 'A';
+                       else
+                           if (c < 'a' || c > 'f')
+                               return ps_seterr (ps, PS_ERR_XXX, NOTOK);
+                       c += '9' + 1 - 'a';
+                       break;
+               }
+               n = (n * base) + c - '0';
+               if (pl_read (ps, &c) == NOTOK)
+                   return NOTOK;
+               if (!isxdigit ((u_char) c)) {
+                   pl -> pl_num = n;
+                   ps -> ps_scratch = c;
+                   return OK;
+               }
+           }
+    }
+}
+
+/* \f */
+
+static int pl_read (ps, c)
+register PS    ps;
+register byte  *c;
+{
+    if (ps -> ps_scratch) {
+       *c = ps -> ps_scratch;
+       ps -> ps_scratch = 0;
+       return OK;
+    }
+
+    return ps_read (ps, c, 1);
+}
diff --git a/src/isode/psap/pl_tables.c b/src/isode/psap/pl_tables.c
new file mode 100644 (file)
index 0000000..99656c8
--- /dev/null
@@ -0,0 +1,91 @@
+/* pl_tables.c - tables for presentation lists */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:38  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:54  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:01  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f   DATA */
+
+char   *pe_classlist[] = {
+    "UNIV",
+    "APPL",
+    "CONT",
+    "PRIV"
+};
+
+int    pe_maxclass = sizeof pe_classlist / sizeof pe_classlist[0];
+
+
+char   *pe_univlist[] = {
+    "EOC",
+    "BOOL",
+    "INT",
+    "BITS",
+    "OCTS",
+    "NULL",
+    "OID",
+    "ODE",
+    "EXTN",
+    "REAL",
+    "ENUM",
+    "ENCR",
+    NULLCP,
+    NULLCP,
+    NULLCP,
+    NULLCP,
+    "SEQ",
+    "SET",
+    "NUMS",
+    "PRTS",
+    "T61S",
+    "VTXS",
+    "IA5S",
+    "UTCT",
+    "GENT",
+    "GFXS",
+    "VISS",
+    "GENS",
+    "CHRS",
+};
+
+int    pe_maxuniv = sizeof pe_univlist / sizeof pe_univlist[0];
+
+
+int    pe_maxappl = 0;
+char  **pe_applist = NULL;
+
+int    pe_maxpriv = 0;
+char  **pe_privlist = NULL;
diff --git a/src/isode/psap/prim2bit.c b/src/isode/psap/prim2bit.c
new file mode 100644 (file)
index 0000000..851943f
--- /dev/null
@@ -0,0 +1,72 @@
+/* prim2bit.c - presentation element to bit string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:40  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:56  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:02  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     prim2bit (pe)
+register PE    pe;
+{
+    int            i;
+    register PElementData bp;
+    register PElementLen len;
+    register PE            p;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM:      /* very paranoid... */
+           if ((bp = pe -> pe_prim) && (len = pe -> pe_len)) {
+               if ((i = *bp & 0xff) > 7)
+                   return pe_seterr (pe, PE_ERR_BITS, NULLPE);
+               pe -> pe_nbits = ((len - 1) * 8) - i;
+           }
+           else
+               pe -> pe_nbits = 0;
+           break;
+
+       case PE_FORM_CONS: 
+           pe -> pe_nbits = 0;
+           for (p = pe -> pe_cons; p; p = p -> pe_next) {
+               if (prim2bit (p) == NULLPE)
+                   return NULLPE;
+               pe -> pe_nbits += p -> pe_nbits;
+           }
+           break;
+    }
+
+    return pe;
+}
diff --git a/src/isode/psap/prim2flag.c b/src/isode/psap/prim2flag.c
new file mode 100644 (file)
index 0000000..9a531a6
--- /dev/null
@@ -0,0 +1,51 @@
+/* prim2flag.c - presentation element to boolean */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:42  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:58  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:02  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    prim2flag (pe)
+register PE    pe;
+{
+    if (pe -> pe_form != PE_FORM_PRIM
+           || pe -> pe_prim == NULLPED
+           || pe -> pe_len == 0)
+       return pe_seterr (pe, PE_ERR_PRIM, NOTOK);
+
+    return (*pe -> pe_prim != 0x00);
+}
diff --git a/src/isode/psap/prim2num.c b/src/isode/psap/prim2num.c
new file mode 100644 (file)
index 0000000..0990e58
--- /dev/null
@@ -0,0 +1,60 @@
+/* prim2num.c - presentation element to integer */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:43  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:37:59  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:03  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+integer        prim2num (pe)
+register PE    pe;
+{
+    register integer    i;
+    register PElementData dp,
+                         ep;
+
+    if (pe -> pe_form != PE_FORM_PRIM || pe -> pe_prim == NULLPED)
+       return pe_seterr (pe, PE_ERR_PRIM, NOTOK);
+    if (pe -> pe_len > sizeof (i))
+       return pe_seterr (pe, PE_ERR_OVER, NOTOK);
+
+    pe -> pe_errno = PE_ERR_NONE;/* in case integer is NOTOK-valued */
+    i = (*(dp = pe -> pe_prim) & 0x80) ? (-1) : 0;
+    for (ep = dp + pe -> pe_len; dp < ep;)
+       i = (i << 8) | (*dp++ & 0xff);
+
+    return i;
+}
diff --git a/src/isode/psap/prim2oid.c b/src/isode/psap/prim2oid.c
new file mode 100644 (file)
index 0000000..8e56b1c
--- /dev/null
@@ -0,0 +1,117 @@
+/* prim2oid.c - presentation element to object identifier */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:45  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:01  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:03  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+static int     once_only = 1;
+static OIDentifier oid;
+
+/* \f */
+
+OID    prim2oid (pe)
+register PE    pe;
+{
+    register unsigned int i,
+                        *ip;
+    register PElementData dp,
+                         ep;
+    register OID       o = &oid;
+
+    if (once_only) {
+       bzero ((char *) o, sizeof *o);
+       once_only = 0;
+    }
+
+    if (pe -> pe_form != PE_FORM_PRIM
+           || (dp = pe -> pe_prim) == NULLPED
+           || pe -> pe_len == 0)
+       return pe_seterr (pe, PE_ERR_PRIM, NULLOID);
+    ep = dp + pe -> pe_len;
+
+    if (o -> oid_elements) {
+       free ((char *) o -> oid_elements);
+       o -> oid_elements = NULL;
+    }
+
+    for (i = 1; dp < ep; i++) {        /* another whacko OSI encoding... */
+       if (*dp == 0x80)
+           return pe_seterr (pe, PE_ERR_OID, NULLOID);
+
+       while (*dp++ & 0x80)
+           if (dp > ep)
+               return pe_seterr (pe, PE_ERR_OID, NULLOID);
+    }
+
+    if ((ip = (unsigned int *) malloc ((i + 1) * sizeof *ip)) == NULL)
+       return pe_seterr (pe, PE_ERR_NMEM, NULLOID);
+    o -> oid_elements = ip, o -> oid_nelem = i;
+    
+    for (dp = pe -> pe_prim; dp < ep; ) {
+       i = 0;
+       do {
+           i <<= 7; 
+           i |= *dp & 0x7f;
+       } while (*dp++ & 0x80);
+
+       if (ip != o -> oid_elements)
+           *ip++ = i;
+       else
+           if (i < 40)
+               *ip++ = 0, *ip++ = i;
+           else
+               if (i < 80)
+                   *ip++ = 1, *ip++ = i - 40;
+               else
+                   *ip++ = 2, *ip++ = i - 80;
+    }
+
+    return o;
+}
+
+/* \f */
+
+#ifdef PEP_TEST
+free_oid ()
+{
+    if (!once_only && oid.oid_elements) {
+       free ((char *) oid.oid_elements);
+       oid.oid_elements = NULL;
+    }
+}
+#endif
diff --git a/src/isode/psap/prim2qb.c b/src/isode/psap/prim2qb.c
new file mode 100644 (file)
index 0000000..b1e7333
--- /dev/null
@@ -0,0 +1,105 @@
+/* prim2qb.c - presentation element to qbuf */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:48  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:02  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:04  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+struct qbuf *prim2qb (pe)
+register PE    pe;
+{
+    register struct qbuf *qb,
+                        *qp;
+    register PE            p;
+    register PElementClass class;
+    register PElementID id;
+
+    if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
+       return pe_seterr (pe, PE_ERR_NMEM, (struct qbuf *) NULL);
+    qb -> qb_forw = qb -> qb_back = qb;
+    qb -> qb_data = NULL, qb -> qb_len = 0;
+       
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM:
+           if ((qp = str2qb ((char *) pe -> pe_prim, (int) pe -> pe_len, 0))
+                   == NULL) {
+               pe -> pe_errno = PE_ERR_NMEM;
+               goto out;
+           }
+           qb -> qb_len = qp -> qb_len;
+           insque (qp, qb);
+           break;
+
+       case PE_FORM_CONS:
+           if ((p = pe -> pe_cons) == NULLPE)
+               break;
+           class = p -> pe_class, id = p -> pe_id;
+           for (p = pe -> pe_cons; p; p = p -> pe_next) {
+               register struct qbuf *qpp,
+                                    *qbp;
+
+               if ((p -> pe_class != class || p -> pe_id != id)
+                       && (p -> pe_class != PE_CLASS_UNIV
+                               || p -> pe_id != PE_PRIM_OCTS)) {
+                   pe -> pe_errno = PE_ERR_TYPE;
+                   goto out;
+               }
+               if ((qp = prim2qb (p)) == NULL) {
+                   pe -> pe_errno = p -> pe_errno;
+                   goto out;
+               }
+
+               for (qpp = qp -> qb_forw; qpp != qp; qpp = qbp) {
+                   qbp = qpp -> qb_forw;
+
+                   remque (qpp);
+                   insque (qpp, qb -> qb_back);
+
+                   qb -> qb_len += qpp -> qb_len;
+               }
+               free ((char *) qp);
+           }
+           break;
+    }
+
+    return qb;
+
+out: ;
+    qb_free (qb);
+
+    return NULL;
+}
diff --git a/src/isode/psap/prim2real.c b/src/isode/psap/prim2real.c
new file mode 100644 (file)
index 0000000..b30d92a
--- /dev/null
@@ -0,0 +1,151 @@
+/* prim2real.c - presentation element to real */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ * Contributed by Julian Onions, Nottingham University.
+ * July 1989 - this stuff is awful. If you're going to use it seriously then
+ * write a machine specific version rather than any attempt at portability.
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:50  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:04  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:04  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include "psap.h"
+
+/* \f */
+
+static double decode_binary (), decode_decimal ();
+       
+double prim2real (pe)
+register PE    pe;
+{
+       if (pe -> pe_form != PE_FORM_PRIM)
+               return pe_seterr (pe, PE_ERR_PRIM, NOTOK);
+       if (pe -> pe_len == 0)
+               return 0.0;
+       if (pe -> pe_prim == NULLPED)
+               return pe_seterr (pe, PE_ERR_PRIM, NOTOK);
+               
+       if (pe -> pe_len > sizeof (double) + 1)
+               return pe_seterr (pe, PE_ERR_OVER, NOTOK);
+
+       pe -> pe_errno = PE_ERR_NONE;   /* in case it's -1 */
+
+       if ((*(pe -> pe_prim) & 0x80) == 0x80)
+               return decode_binary (pe);
+
+       switch (*(pe -> pe_prim) & PE_REAL_FLAGS) {
+           case PE_REAL_DECENC:
+               return decode_decimal (pe);
+
+           case PE_REAL_SPECENC:
+               if (pe -> pe_len > 1)
+                       return pe_seterr (pe, PE_ERR_OVER, NOTOK);
+
+               switch (*(pe -> pe_prim)) {
+                   case PE_REAL_MINUSINF:
+                       return HUGE;
+                   case PE_REAL_PLUSINF:
+                       return -HUGE;
+                   default:
+                       return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK);
+               }
+       }
+       /* NOTREACHED */
+}
+
+/* \f */
+
+static double decode_binary (pe)
+PE     pe;
+{
+       int     sign, base, factor;
+       int     exponent, i;
+       double  mantissa, di;
+       PElementData dp, ep;
+
+       dp = pe -> pe_prim;
+       sign = (*dp & PE_REAL_B_S) ?  -1 : 1;
+       switch (*dp & PE_REAL_B_BASE) {
+           case PE_REAL_B_B2:
+               base = 2;
+               break;
+
+           case PE_REAL_B_B8:
+               base = 8;
+               break;
+
+           case PE_REAL_B_B16:
+               base = 16;
+               break;
+           default:
+               return pe_seterr(pe, PE_ERR_NOSUPP, NOTOK);
+       }
+
+       factor = ((int)(*dp & PE_REAL_B_F)) >> 2;
+
+       exponent = (dp[1] & 0x80) ? (-1) : 0;
+       switch (*dp++ & PE_REAL_B_EXP) {
+           case PE_REAL_B_EF3:
+               exponent = (exponent << 8) | (*dp++ & 0xff);
+               /* fall */
+           case PE_REAL_B_EF2:
+               exponent = (exponent << 8) | (*dp++ & 0xff);
+               /* fall */
+           case PE_REAL_B_EF1:
+               exponent = (exponent << 8) | (*dp++ & 0xff);
+               break;
+           case PE_REAL_B_EF4:
+               i = *dp++ & 0xff;
+               if (i > sizeof(int))
+                       return pe_seterr (pe, PE_ERR_OVER, NOTOK);
+               for (; i > 0; i--)
+                       exponent = (exponent << 8) | (*dp++ & 0xff);
+               break;
+       }
+       for (di = 0.0, ep = pe -> pe_prim + pe -> pe_len; dp < ep;) {
+               di *= 1 << 8;   ;
+               di += (int)(*dp++ & 0xff);
+       }
+       
+       mantissa = sign * di * (1 << factor);
+       return mantissa * pow ((double)base, (double)exponent);
+}
+
+/* \f */
+
+static double decode_decimal (pe)
+PE     pe;
+{
+       /* sorry - don't have the standard ! */
+       return pe_seterr (pe, PE_ERR_NOSUPP, NOTOK);
+}
+
diff --git a/src/isode/psap/prim2set.c b/src/isode/psap/prim2set.c
new file mode 100644 (file)
index 0000000..6640bc9
--- /dev/null
@@ -0,0 +1,57 @@
+/* prim2flag.c - presentation element to set */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:52  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:05  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:05  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     prim2set (pe)
+register PE    pe;
+{
+    register int    i;
+    register PE            p;
+
+    if (pe -> pe_form != PE_FORM_CONS)
+       return pe_seterr (pe, PE_ERR_CONS, NULLPE);
+
+    for (i = 0, p = pe -> pe_cons; p; p = p -> pe_next)
+       p -> pe_offset = i++;
+
+    pe -> pe_cardinal = i;
+
+    return pe;
+}
diff --git a/src/isode/psap/prim2str.c b/src/isode/psap/prim2str.c
new file mode 100644 (file)
index 0000000..9d3152f
--- /dev/null
@@ -0,0 +1,110 @@
+/* prim2str.c - presentation element to octet string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:07  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:05  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+/* Similar to pe_pullup.  Returns a newly allocated string, composed of
+   of any sub-elements in pe, whereas pe_pullup always reverts "pe" to
+   a primitive.  The string is null-terminated, though pe_len specifically
+   does NOT reflect this. */
+
+char   *prim2str (pe, len)
+register PE    pe;
+register int   *len;
+{
+    register int    i,
+                    k;
+    int     j;
+    register char  *dp,
+                   *ep,
+                   *fp;
+    register PElementClass class;
+    register PElementID id;
+    register PE            p;
+
+    *len = 0;
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if ((dp = malloc ((unsigned) ((i = pe -> pe_len) + 1))) == NULLCP)
+               return pe_seterr (pe, PE_ERR_NMEM, NULLCP);
+           bcopy ((char *) pe -> pe_prim, dp, i);
+           break;
+
+       case PE_FORM_CONS: 
+           if ((p = pe -> pe_cons) == NULLPE) {
+               if ((dp = malloc ((unsigned) ((i = 0) + 1))) == NULLCP)
+                   return pe_seterr (pe, PE_ERR_NMEM, NULLCP);
+               break;
+           }
+           dp = NULLCP, i = 0;
+           class = p -> pe_class, id = p -> pe_id;
+           for (p = pe -> pe_cons; p; p = p -> pe_next) {
+               if ((p -> pe_class != class || p -> pe_id != id)
+                       && (p -> pe_class != PE_CLASS_UNIV
+                               || p -> pe_id != PE_PRIM_OCTS)) {
+                   if (dp)
+                       free (dp);
+                   return pe_seterr (pe, PE_ERR_TYPE, NULLCP);
+               }
+
+               if ((ep = prim2str (p, &j)) == NULLCP) {
+                   if (dp)
+                       free (dp);
+                   return pe_seterr (pe, PE_ERR_NMEM, NULLCP);
+               }
+               if (dp) {
+                   if ((fp = realloc (dp, (unsigned) ((k = i + j) + 1)))
+                           == NULLCP) {
+                       free (dp);
+                       return pe_seterr (pe, PE_ERR_NMEM, NULLCP);
+                   }
+                   bcopy (ep, fp + i, j);
+                   dp = fp, i = k;
+               }
+               else
+                   dp = ep, i += j;
+           }
+           break;
+    }
+
+    if (dp)
+       dp[*len = i] = NULL;
+
+    return dp;
+}
diff --git a/src/isode/psap/prim2time.c b/src/isode/psap/prim2time.c
new file mode 100644 (file)
index 0000000..34daaf2
--- /dev/null
@@ -0,0 +1,263 @@
+/* prim2time.c - presentation element to time string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:56  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:09  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:06  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 <ctype.h>
+#include <stdio.h>
+#include "psap.h"
+
+/* \f   DATA */
+
+#define        YEAR(y)         ((y) >= 100 ? (y) : (y) + 1900)
+
+long   get_usec ();
+
+/* \f */
+
+UTC    prim2time (pe, generalized)
+register PE    pe;
+int    generalized;
+{
+    int     len;
+    register char  *cp;
+    register UTC    u;
+    UTC           (*aux) ();
+
+    aux = generalized ? str2gent : str2utct;
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if (pe -> pe_prim == NULLPED)
+               return pe_seterr (pe, PE_ERR_PRIM, NULLUTC);
+           u = (*aux) ((char *) pe -> pe_prim, (int) pe -> pe_len);
+           break;
+
+       case PE_FORM_CONS: 
+           if ((cp = prim2str (pe, &len)) == NULLCP)
+               return NULLUTC;
+           u = len ? (*aux) (cp, len) : NULLUTC;
+           free (cp);
+           break;
+    }
+
+    return (u ? u : pe_seterr (pe, generalized ? PE_ERR_GENT : PE_ERR_UTCT,
+                       NULLUTC));
+}
+
+/* \f */
+
+UTC    str2utct (cp, len)
+register char  *cp;
+register int   len;
+{
+    int     year,
+           hours,
+            mins;
+    register int    zone;
+    static UTCtime  ut;
+    register UTC    u = &ut;
+
+    bzero ((char *) u, sizeof *u);
+
+    if (sscanf (cp, "%2d%2d%2d%2d%2d", &year, &u -> ut_mon,
+               &u -> ut_mday, &u -> ut_hour, &u -> ut_min) != 5)
+       return NULLUTC;
+    cp += 10, len -= 10;
+    u -> ut_year = YEAR (year);
+
+    if (len > 0 && isdigit ((u_char) *cp)) {
+       if (sscanf (cp, "%2d", &u -> ut_sec) != 1)
+           return NULLUTC;
+       u -> ut_flags |= UT_SEC;
+       cp += 2, len -= 2;
+    }
+
+    if (len > 0) {
+       switch (*cp) {
+           case 'Z': 
+               cp++, len--;
+               break;
+
+           case '+': 
+           case '-': 
+               if (sscanf (cp + 1, "%2d%2d", &hours, &mins) != 2)
+                   return NULLUTC;
+               zone = hours * 60 + mins;
+               u -> ut_zone = *cp == '+' ? zone : -zone;
+               cp += 5, len -= 5;
+               break;
+
+           default: 
+               return NULLUTC;
+       }
+       u -> ut_flags |= UT_ZONE;
+    }
+    if (len != 0)
+       return NULLUTC;
+
+    return u;
+}
+
+/* \f */
+
+UTC    str2gent (cp, len)
+char   *cp;
+int    len;
+{
+    int     hours,
+            mins;
+    long    usec;
+    register int    zone;
+    static UTCtime    ut;
+    register UTC      u = &ut;
+
+    bzero ((char *) u, sizeof *u);
+
+    if (sscanf (cp, "%4d%2d%2d%2d", &u -> ut_year, &u -> ut_mon,
+               &u -> ut_mday, &u -> ut_hour) != 4)
+       return NULLUTC;
+    cp += 10, len -= 10;
+
+    if (len > 0)
+       switch (*cp) {
+           case '.':
+           case ',':
+               cp++, len--;
+               if ((usec = get_usec (&cp, &len)) < 0)
+                   return NULLUTC;
+               u -> ut_min = (u -> ut_sec = usec / 1000000) / 60;
+               u -> ut_sec %= 60;
+               u -> ut_usec = usec % 1000000;
+               u -> ut_flags |= UT_SEC | UT_USEC;
+               goto get_zone;
+
+           default:
+               if (isdigit ((u_char) *cp)) {
+                   if (sscanf (cp, "%2d", &u -> ut_min) != 1)
+                       return NULLUTC;
+                   cp += 2, len -= 2;
+               }
+               break;
+       }
+
+    if (len > 0)
+       switch (*cp) {
+           case '.':
+           case ',':
+               cp++, len--;
+               if ((usec = get_usec (&cp, &len)) < 0)
+                   return NULLUTC;
+               if ((u -> ut_sec = usec / 1000000) >= 60)
+                   return NULLUTC;
+               u -> ut_usec = usec % 1000000;
+               u -> ut_flags |= UT_SEC | UT_USEC;
+               goto get_zone;
+
+           default:
+               if (isdigit ((u_char) *cp)) {
+                   if (sscanf (cp, "%2d", &u -> ut_sec) != 1)
+                       return NULLUTC;
+                   u -> ut_flags |= UT_SEC;
+                   cp += 2, len -= 2;
+               }
+               break;
+       }
+           
+    if (len > 0)
+       switch (*cp) {
+           case '.':
+           case ',':
+               cp++, len--;
+               if ((usec = get_usec (&cp, &len)) < 0)
+                   return NULLUTC;
+               if ((u -> ut_usec = usec) >= 1000000)
+                   return NULLUTC;
+               u -> ut_flags |= UT_USEC;
+               goto get_zone;
+
+           default:
+               break;
+       }
+           
+get_zone: ;
+    if (len > 0) {
+       switch (*cp) {
+           case 'Z': 
+               cp++, len--;
+               break;
+
+           case '+': 
+           case '-': 
+               if (sscanf (cp + 1, "%2d%2d", &hours, &mins) != 2)
+                   return NULLUTC;
+               zone = hours * 60 + mins;
+               u -> ut_zone = *cp == '+' ? zone : -zone;
+               cp += 5, len -= 5;
+               break;
+
+           default: 
+               return NULLUTC;
+       }
+       u -> ut_flags |= UT_ZONE;
+    }
+    if (len != 0)
+       return NULLUTC;
+
+    return u;
+}
+
+/* \f */
+
+/* not perfect, but what is? */
+
+static long  get_usec (cp, len)
+char  **cp;
+int    *len;
+{
+    register int    j;
+    register long   i;
+    register char  *dp;
+
+    i = 0L;
+    for (dp = *cp, j = 0; isdigit ((u_char) *dp); dp++, j++)
+       if (j < 6)
+           i = i * 10L + (long) (*dp - '0');
+
+    *cp = dp, *len -= j;
+
+    while (j++ < 6)
+       i *= 10L;
+
+    return i;
+}
diff --git a/src/isode/psap/ps2pe.c b/src/isode/psap/ps2pe.c
new file mode 100644 (file)
index 0000000..e7ec9d1
--- /dev/null
@@ -0,0 +1,279 @@
+/* ps2pe.c - presentation stream to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:33:58  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:10  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:06  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+PE     ps2pe_aux (ps, top, all)
+register PS    ps;
+int    top,
+       all;
+{
+    register PElementLen len;
+    PElementClass   class;
+    PElementForm    form;
+    PElementID     id;
+    register PE            pe;
+
+    if (top && ps_prime (ps, 0) == NOTOK)
+       return NULLPE;
+    
+    if (ps_read_id (ps, top, &class, &form, &id) == NOTOK)
+       return NULLPE;
+    if ((pe = pe_alloc (class, form, id)) == NULLPE)
+       return ps_seterr (ps, PS_ERR_NMEM, NULLPE);
+    if (ps_read_len (ps, &pe -> pe_len) == NOTOK)
+       goto you_lose;
+
+    if (all == 0)
+       return pe;
+    len = pe -> pe_len;
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           if (len == PE_LEN_INDF) {
+               (void) ps_seterr (ps, PS_ERR_INDF, NULLPE);
+               goto you_lose;
+           }
+           if (len > 0) {
+               if (ps -> ps_inline) {  /* "ultra-efficiency"... */
+                   if (ps -> ps_base == NULLCP || ps -> ps_cnt < len) {
+                       (void) ps_seterr (ps, PS_ERR_EOF, NULLPE);
+                       goto you_lose;
+                   }
+                   pe -> pe_inline = 1;
+                   pe -> pe_prim = (PElementData) ps -> ps_ptr;
+                   ps -> ps_ptr += len, ps -> ps_cnt -= len;
+                   ps -> ps_byteno += len;
+               }
+               else {
+                   if ((pe -> pe_prim = PEDalloc (len)) == NULLPED) {
+                       (void) ps_seterr (ps, PS_ERR_NMEM, NULLPE);
+                       goto you_lose;
+                   }
+                   if (ps_read (ps, pe -> pe_prim, len) == NOTOK) {
+#ifdef DEBUG
+                       SLOG (psap_log, LLOG_DEBUG, NULLCP,
+                             ("error reading primitive, %d bytes: %s",
+                              len, ps_error (ps -> ps_errno)));
+#endif
+                       goto you_lose;
+                   }
+               }
+           }
+           break;
+
+       case PE_FORM_CONS: 
+           if (len != 0 && ps_read_cons (ps, &pe -> pe_cons, len) == NOTOK)
+               goto you_lose;
+           break;
+    }
+
+    if (top && ps_prime (ps, -1) == NOTOK)
+       goto you_lose;
+
+    return pe;
+
+you_lose: ;
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_DEBUG) {
+       LLOG (psap_log, LLOG_PDUS, ("PE read thus far"));
+       pe2text (psap_log, pe, 1, NOTOK);
+    }
+#endif
+
+    pe_free (pe);
+    return NULLPE;
+}
+
+/* \f */
+
+static int pe_id_overshift = PE_ID_MASK << (PE_ID_BITS - PE_ID_SHIFT);
+
+
+int  ps_read_id (ps, top, class, form, id)
+register PS    ps;
+int    top;
+register PElementClass *class;
+register PElementForm *form;
+register PElementID *id;
+{
+    byte    c,
+           d;
+    register PElementID j;
+
+    if (ps_read (ps, &c, 1) == NOTOK) {
+       if (top && ps -> ps_errno == PS_ERR_EOF)
+           ps -> ps_errno = PS_ERR_NONE;
+       else {
+#ifdef DEBUG
+       SLOG (psap_log, LLOG_DEBUG, NULLCP,
+             ("error reading initial octet: %s", ps_error (ps -> ps_errno)));
+#endif
+       }
+           
+       return NOTOK;
+    }
+
+    *class = ((int)(c & PE_CLASS_MASK)) >> PE_CLASS_SHIFT;
+    *form = ((int)(c & PE_FORM_MASK)) >> PE_FORM_SHIFT;
+    j = (c & PE_CODE_MASK);
+
+    if (j == PE_ID_XTND)
+       for (j = 0;; j <<= PE_ID_SHIFT) {
+           if (ps_read (ps, &d, 1) == NOTOK) {
+               if (ps -> ps_errno == PS_ERR_EOF)
+                   ps -> ps_errno = PS_ERR_EOFID;
+               return NOTOK;
+           }
+
+           j |= d & PE_ID_MASK;
+           if (!(d & PE_ID_MORE))
+               break;
+           if (j & pe_id_overshift)
+               return ps_seterr (ps, PS_ERR_OVERID, NOTOK);
+       }
+    *id = j;
+    DLOG (psap_log, LLOG_DEBUG, ("class=%d form=%d id=%d",*class, *form, *id));
+
+    return OK;
+}
+
+/* \f */
+
+int  ps_read_len (ps, len)
+register PS    ps;
+register PElementLen   *len;
+{
+    register int    i;
+    register PElementLen j;
+    byte    c;
+
+    if (ps_read (ps, &c, 1) == NOTOK) {
+#ifdef DEBUG
+       SLOG (psap_log, LLOG_DEBUG, NULLCP,
+             ("error reading initial length octet: %s",
+              ps_error (ps -> ps_errno)));
+#endif
+
+       return NOTOK;
+    }
+
+    if ((i = c) & PE_LEN_XTND) {
+       if ((i &= PE_LEN_MASK) > sizeof (PElementLen))
+           return ps_seterr (ps, PS_ERR_OVERLEN, NOTOK);
+
+       if (i) {
+           for (j = 0; i-- > 0;) {
+               if (ps_read (ps, &c, 1) == NOTOK) {
+                   if (ps -> ps_errno == PS_ERR_EOF)
+                       ps -> ps_errno = PS_ERR_EOFLEN;
+                   return NOTOK;
+               }
+
+               j = (j << 8) | (c & 0xff);
+           }
+           *len = j;
+       }
+       else
+           *len = PE_LEN_INDF;
+    }
+    else
+       *len = i;
+#ifdef DEBUG
+    SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", *len));
+#endif
+
+    return OK;
+}
+
+/* \f */
+
+int  ps_read_cons (ps, pe, len)
+register PS    ps;
+register PE    *pe;
+register PElementLen len;
+{
+    register int    cc;
+    register PE            p,
+                   q;
+
+    cc = ps -> ps_byteno + len;
+
+    if ((p = ps2pe_aux (ps, 0, 1)) == NULLPE) {
+no_cons: ;
+#ifdef DEBUG
+       if (len == PE_LEN_INDF)
+           LLOG (psap_log, LLOG_DEBUG,
+                 ("error building indefinite constructor, %s",
+                  ps_error (ps -> ps_errno)));
+       else
+           LLOG (psap_log, LLOG_DEBUG,
+                 ("error building constructor, stream at %d, wanted %d: %s",
+                  ps -> ps_byteno, cc, ps_error (ps -> ps_errno)));
+#endif
+
+       return NOTOK;
+    }
+    *pe = p;
+
+    if (len == PE_LEN_INDF) {
+       if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
+           pe_free (p);
+           *pe = NULLPE;
+           return OK;
+       }
+       for (q = p; p = ps2pe_aux (ps, 0, 1); q = q -> pe_next = p) {
+           if (p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
+               pe_free (p);
+               return OK;
+           }
+       }
+
+       goto no_cons;
+    }
+
+    for (q = p;; q = q -> pe_next = p) {
+       if (cc < ps -> ps_byteno)
+           return ps_seterr (ps, PS_ERR_LEN, NOTOK);
+       if (cc == ps -> ps_byteno)
+           return OK;
+       if ((p = ps2pe_aux (ps, 0, 1)) == NULLPE)
+           goto no_cons;
+    }
+}
diff --git a/src/isode/psap/ps_alloc.c b/src/isode/psap/ps_alloc.c
new file mode 100644 (file)
index 0000000..ee40342
--- /dev/null
@@ -0,0 +1,90 @@
+/* ps_alloc.c - allocate a presentation stream */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:00  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:12  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:07  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+/* A Presentatation Stream (or PStream) is the second generation of
+   "generic" I/O stream-based handling.  (For the first attempt,
+   take a look at the prototype implementation of the TTI Trusted Mail
+   Agent.)  The idea is to present a common, simple I/O paradigm (i.e.,
+   the UNIX v7 philosophy) to protocol-translation entities regardless of
+   the underlying medium (files, pipes, sockets, or strings).
+
+   New streams are created by a call to ps_alloc().  It allocates memory
+   and calls an open routine.  This routine fills in the dispatch vectors
+   for read/write and (optionally) close.  It can also fill in any other
+   part of the stream's structure it likes.
+
+   Once created, I/O is done using the macros ps_read/ps_write.  These
+   return either NOTOK or OK; depending on how things went. The read/write
+   routines are invoked as:
+
+       int     iofunc (ps, data, n, in_line)
+       PS      ps;
+       PElementData data;
+       PElementLen  n;
+       int     in_line;
+
+   They should read/write upto len bytes, starting at data, and return the
+   number of bytes processed, or NOTOK on error.  The routine ps_io() will
+   make successive calls to fill/flush the data.  If the read/write routine
+   returns NOTOK, it should set ps_errno as well.
+
+   Streams are removed by a call to ps_free ().  It calls the close
+   routine, if any, which should de-commission any parts of the stream's
+   structure that are in use.  ps_free() will then free the allocated
+   memory.
+ */
+
+/* \f */
+
+PS     ps_alloc (io)
+register IFP   io;
+{
+    register PS            ps;
+
+    if ((ps = (PS) calloc (1, sizeof *ps)) == NULLPS)
+       return NULLPS;
+
+    if ((*io) (ps) == NOTOK) {
+       ps_free (ps);
+       return NULLPS;
+    }
+
+    return ps;
+}
diff --git a/src/isode/psap/ps_error.c b/src/isode/psap/ps_error.c
new file mode 100644 (file)
index 0000000..7336fcc
--- /dev/null
@@ -0,0 +1,73 @@
+/* ps_error.c - presentation stream error to string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:03  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:13  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:08  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+static char *ps_errorlist[] = {
+    "Error 0",
+    "Overflow in ID",
+    "Overflow in length",
+    "Out of memory",
+    "End of file",
+    "End of file reading extended ID",
+    "End of file reading extended length",
+    "Length Mismatch",
+    "Truncated",
+    "Indefinite length in primitive form",
+    "I/O error",
+    "Extraneous octets",
+    "XXX"
+};
+
+static int ps_maxerror = sizeof ps_errorlist / sizeof ps_errorlist[0];
+
+/* \f */
+
+char   *ps_error (c)
+int    c;
+{
+    register char  *bp;
+    static char buffer[30];
+
+    if (c < ps_maxerror && (bp = ps_errorlist[c]))
+       return bp;
+
+    (void) sprintf (buffer, "Error %d", c);
+    return buffer;
+}
diff --git a/src/isode/psap/ps_flush.c b/src/isode/psap/ps_flush.c
new file mode 100644 (file)
index 0000000..028272b
--- /dev/null
@@ -0,0 +1,49 @@
+/* ps_flush.c - flush a presentation stream */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:05  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:15  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:08  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    ps_flush (ps)
+register PS    ps;
+{
+    if (ps -> ps_flushP)
+       return (*ps -> ps_flushP) (ps);
+
+    return OK;
+}
diff --git a/src/isode/psap/ps_free.c b/src/isode/psap/ps_free.c
new file mode 100644 (file)
index 0000000..ed79953
--- /dev/null
@@ -0,0 +1,49 @@
+/* ps_free.c - free a presentation stream */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:07  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:16  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:09  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+void   ps_free (ps)
+register PS    ps;
+{
+    if (ps -> ps_closeP)
+       (void) (*ps -> ps_closeP) (ps);
+
+    free ((char *) ps);
+}
diff --git a/src/isode/psap/ps_get_abs.c b/src/isode/psap/ps_get_abs.c
new file mode 100644 (file)
index 0000000..f0ef4f2
--- /dev/null
@@ -0,0 +1,120 @@
+/* ps_get_abs.c - get absolute length */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:10  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:18  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:09  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f   DATA */
+
+int    ps_len_strategy = PS_LEN_SPAG;
+static int  ps_get_id ();
+static int  ps_get_len ();
+
+/* \f */
+
+int    ps_get_abs (pe)
+register PE    pe;
+{
+    register    PElementLen len;
+    register    PE p;
+
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+           len = pe -> pe_len;
+           break;
+
+       case PE_FORM_CONS: 
+           len = 0;
+           for (p = pe -> pe_cons; p; p = p -> pe_next)
+               len += ps_get_abs (p);
+
+           switch (ps_len_strategy) {
+               case PS_LEN_SPAG: 
+               default: 
+                   if (len <= PE_LEN_SMAX) {
+                       pe -> pe_len = len;
+                       break;
+                   }           /* else fall */
+
+               case PS_LEN_INDF: 
+                   pe -> pe_len = PE_LEN_INDF;
+                   len += 2;   /* for EOC */
+                   break;
+
+               case PS_LEN_LONG: 
+                   pe -> pe_len = len;
+                   break;
+           }
+           break;
+
+       case PE_FORM_ICONS:
+           return pe -> pe_len;
+    }
+
+    return (ps_get_id (pe) + ps_get_len (pe) + len);
+}
+
+/* \f */
+
+static int  ps_get_id (pe)
+register PE    pe;
+{
+    register int    i;
+    register PElementID id;
+
+    if ((id = pe -> pe_id) < PE_ID_XTND)
+       return 1;
+
+    for (i = 1; id != 0; id >>= PE_ID_SHIFT)
+       i++;
+    return i;
+}
+
+/* \f */
+
+static int  ps_get_len (pe)
+register PE    pe;
+{
+    register int    i;
+    register PElementLen len;
+
+    if ((len = pe -> pe_len) == PE_LEN_INDF || len <= PE_LEN_SMAX)
+       return 1;
+
+    for (i = 1; len > 0; len >>= 8)
+       i++;
+    return i;
+}
diff --git a/src/isode/psap/ps_io.c b/src/isode/psap/ps_io.c
new file mode 100644 (file)
index 0000000..617f3eb
--- /dev/null
@@ -0,0 +1,69 @@
+/* ps_io.c - presentation stream I/O dispatch */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:12  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:19  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:10  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    ps_io (ps, io, data, n, in_line)
+register PS    ps;
+register IFP   io;
+register PElementData data;
+register PElementLen n;
+int    in_line;
+{
+    register int    cc;
+
+    if (io == NULLIFP)
+       return ps_seterr (ps, PS_ERR_EOF, NOTOK);
+
+    while (n > 0)
+       switch (cc = (*io) (ps, data, n, in_line)) {
+           case NOTOK: 
+               return NOTOK;
+
+           case OK: 
+               return ps_seterr (ps, PS_ERR_EOF, NOTOK);
+
+           default: 
+               data += cc, n -= cc;
+               ps -> ps_byteno += cc;
+               break;
+       }
+
+    return OK;
+}
diff --git a/src/isode/psap/ps_prime.c b/src/isode/psap/ps_prime.c
new file mode 100644 (file)
index 0000000..5c1f640
--- /dev/null
@@ -0,0 +1,50 @@
+/* ps_prime.c - prime a presentation stream */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:14  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:21  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:10  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    ps_prime (ps, waiting)
+register PS    ps;
+int    waiting;
+{
+    if (ps -> ps_primeP)
+       return (*ps -> ps_primeP) (ps, waiting);
+
+    return OK;
+}
diff --git a/src/isode/psap/psaptest.c b/src/isode/psap/psaptest.c
new file mode 100644 (file)
index 0000000..6700746
--- /dev/null
@@ -0,0 +1,225 @@
+/* psaptest.c - test out -lpsap */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:16  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:23  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:11  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+#include <sys/stat.h>
+
+/* \f */
+
+static enum {
+    ps2pl, ps2ps, pl2pl, pl2ps
+} mode;
+
+static ps_die ();
+
+/* \f */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int    argc;
+char  **argv,
+      **envp;
+{
+    char   *cp;
+    register PE pe;
+    register PS ps;
+
+    argc--, argv++;
+    if (argc != 1) {
+usage:         ;
+        (void) fprintf (stderr, "usage: psaptest [ps2pl | ps2ps | pl2pl | pl2ps]\n");
+       exit (1);
+    }
+
+    if (strcmp (*argv, "version") == 0) {
+       (void) printf ("%s\n", psapversion);
+       exit (0);
+    }
+
+    if ((cp = getenv ("PSAPTEST")) && *cp) {
+       psap_log -> ll_events = atoi (cp);
+       psap_log -> ll_stat |= LLOGTTY;
+    }
+
+    if (strcmp (*argv, "string") == 0) {
+       int     onceonly = 1;
+       register PE *pep;
+
+       if ((pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_CONS, PE_PRIM_OCTS))
+               == NULLPE) {
+no_pe: ;
+           (void) fprintf (stderr, "pe_alloc: you lose\n");
+           exit (1);
+       }
+       pep = &pe -> pe_cons;
+       for (;;) {
+           int     i;
+           register PE p;
+
+           if (onceonly) {
+               struct stat st;
+
+               if (fstat (fileno (stdin), &st) == NOTOK
+                       || (st.st_mode & S_IFMT) != S_IFREG
+                       || (i = st.st_size) <= 0)
+                   i = BUFSIZ;
+
+               onceonly = 0;
+           }
+           else
+               i = BUFSIZ;
+           
+           if ((p = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_OCTS))
+                       == NULL
+                   || (p -> pe_prim = PEDalloc (p -> pe_len = i)) == NULLPED)
+               goto no_pe;
+
+           switch (i = fread ((char *) p -> pe_prim, sizeof *p -> pe_prim,
+                              (int) p -> pe_len, stdin)) {
+               case NOTOK:
+                   perror ("fread");
+                   exit (1);
+
+               case OK:
+                   pe_free (p);
+                   mode = ps2ps;
+                   goto doit;
+
+               default:
+                   p -> pe_len = i;
+                   *pep = p, pep = &p -> pe_next;
+                   break;
+           }
+       }
+    }
+
+    if (strcmp (*argv, "binary") == 0) {
+       int     i;
+       char    buffer[BUFSIZ],
+               packet[BUFSIZ];
+
+       while (fgets (buffer, sizeof buffer, stdin)) {
+           if (*buffer == ' ')
+               (void) strncpy (packet, buffer + 1, i = strlen (buffer) - 2);
+           else
+               i = implode ((u_char *) packet, buffer, strlen (buffer) - 1);
+           (void) fwrite (packet, sizeof *packet, i, stdout);
+       }
+
+       exit (0);
+    }
+
+    if (strcmp (*argv, "ps2pl") == 0)
+       mode = ps2pl;
+    else
+       if (strcmp (*argv, "ps2ps") == 0)
+           mode = ps2ps;
+       else
+           if (strcmp (*argv, "pl2pl") == 0)
+               mode = pl2pl;
+           else
+               if (strcmp (*argv, "pl2ps") == 0)
+                   mode = pl2ps;
+               else
+                   goto usage;
+
+    for (;;) {
+       if ((ps = ps_alloc (std_open)) == NULLPS) {
+           (void) fprintf (stderr, "ps_alloc(stdin): you lose\n");
+           exit (1);
+       }
+       if (std_setup (ps, stdin) == NOTOK)
+           ps_die (ps, "std_setup(stdin)");
+
+       switch (mode) {
+           case ps2pl: 
+           case ps2ps: 
+               if ((pe = ps2pe (ps)) == NULLPE)
+                   if (ps -> ps_errno)
+                       ps_die (ps, "ps2pe");
+                   else
+                       exit (0);
+               break;
+
+           case pl2ps: 
+           case pl2pl: 
+               if ((pe = pl2pe (ps)) == NULLPE)
+                   if (ps -> ps_errno)
+                       ps_die (ps, "pl2pe");
+                   else
+                       exit (0);
+               break;
+       }
+
+       ps_free (ps);
+
+doit: ;
+       if ((ps = ps_alloc (std_open)) == NULLPS) {
+           (void) fprintf (stderr, "ps_alloc(stdout): you lose\n");
+           exit (1);
+       }
+       if (std_setup (ps, stdout) == NOTOK)
+           ps_die (ps, "std_setup(stdout)");
+
+       switch (mode) {
+           case ps2ps: 
+           case pl2ps: 
+               if (pe2ps (ps, pe) == NOTOK)
+                   ps_die (ps, "pe2ps");
+               break;
+
+           case pl2pl: 
+           case ps2pl: 
+               if (pe2pl (ps, pe) == NOTOK)
+                   ps_die (ps, "pe2pl");
+               break;
+       }
+
+       pe_free (pe);
+       ps_free (ps);
+    }
+}
+
+/* \f   ERRORS */
+
+static ps_die (ps, s)
+register PS     ps;
+register char   *s;
+{
+    (void) fprintf (stderr, "%s: %s\n", s, ps_error (ps -> ps_errno));
+    exit (1);
+}
diff --git a/src/isode/psap/qb2pe.c b/src/isode/psap/qb2pe.c
new file mode 100644 (file)
index 0000000..74da7c7
--- /dev/null
@@ -0,0 +1,162 @@
+/* qb2pe.c - create a variable-depth Inline CONStructor PElement */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:18  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:26  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:11  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+PE     qb2pe_aux ();
+
+/* \f */
+
+PE     qb2pe (qb, len, depth, result)
+register struct qbuf *qb;
+int    len,
+       depth;
+int    *result;
+{
+    char   *sp;
+    register struct qbuf *qp;
+    PE     pe;
+
+    *result = PS_ERR_NONE;
+    if (depth <= 0)
+       return NULLPE;
+
+    if ((qp = qb -> qb_forw) != qb && qp -> qb_forw == qb)
+       sp = qp -> qb_data;
+    else {
+       qp = NULL;
+       
+       if ((sp = qb2str (qb)) == NULL) {
+           *result = PS_ERR_NMEM;
+           return NULLPE;
+       }
+    }
+
+    if (pe = qb2pe_aux (sp, len, depth, result)) {
+       if (qp) {
+           pe -> pe_realbase = (char *) qp;
+
+           remque (qp);
+       }
+       else {
+           pe -> pe_realbase = sp;
+
+           QBFREE (qb);
+       }
+       pe -> pe_inline = 0;
+    }
+    else
+       if (qp == NULL)
+           free (sp);
+
+#ifdef DEBUG
+    if (pe && (psap_log -> ll_events & LLOG_PDUS))
+       pe2text (psap_log, pe, 1, len);
+#endif
+
+    return pe;
+}
+
+/* \f */
+
+static PE  qb2pe_aux (s, len, depth, result)
+register char  *s;
+register int   len;
+int    depth;
+int    *result;
+{
+    int            i;
+    register PElementData data;
+    register PE            pe,
+                   p,
+                   q;
+    PE     *r,
+           *rp;
+
+    depth--;
+
+    if ((pe = str2pe (s, len, &i, result)) == NULLPE)
+       return NULLPE;
+
+    if (pe -> pe_form == PE_FORM_ICONS) {
+       pe -> pe_form = PE_FORM_CONS;
+       pe -> pe_prim = NULLPED, pe -> pe_inline = 0;
+       pe -> pe_len -= pe -> pe_ilen;
+
+       p = NULLPE, r = &pe -> pe_cons;
+       for (s += pe -> pe_ilen, len -= pe -> pe_ilen;
+                len > 0;
+                s += i, len -= i) {
+           if ((p = str2pe (s, len, &i, result)) == NULLPE)
+               goto out;
+
+           if (p -> pe_form == PE_FORM_ICONS) {
+               if (depth > 0) {
+                   if ((q = qb2pe_aux ((char *) p -> pe_prim, i, depth,
+                                       result)) == NULLPE)
+                       goto out;
+                   pe_free (p);
+                   p = q;
+               }
+               else {
+                   if ((data = PEDalloc (i)) == NULL) {
+                       *result = PS_ERR_NMEM;
+                       goto out;
+                   }
+                   PEDcpy (p -> pe_prim, data, i);
+                   p -> pe_prim = data, p -> pe_inline = 0;
+               }
+           }
+
+           *r = p, rp = r, r = &p -> pe_next;
+       }
+
+       if (p && p -> pe_class == PE_CLASS_UNIV && p -> pe_id == PE_UNIV_EOC) {
+           pe_free (p);
+           *rp = NULLPE;
+       }
+    }
+    
+    return pe;
+
+out: ;
+    pe_free (pe);
+    return NULLPE;
+}
diff --git a/src/isode/psap/qb2prim.c b/src/isode/psap/qb2prim.c
new file mode 100644 (file)
index 0000000..bb0f4ae
--- /dev/null
@@ -0,0 +1,106 @@
+/* qb2prim.c - octet string to primitive */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:20  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:27  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:12  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* form: PRIMitive or CONStructor --
+
+       qb2prim  -      octet string (via qbufs) to presentation element
+
+ */
+
+/* \f */
+
+PE     qb2prim_aux (qb, class, id, in_line)
+register struct qbuf *qb;
+PElementClass  class;
+PElementID     id;
+int    in_line;
+{
+    register PE            pe,
+                   p;
+    register struct qbuf *qp;
+
+    if (qb == NULL)
+       return NULLPE;
+    
+    if ((qp = qb -> qb_forw) == qb || qp -> qb_forw == qb) {
+       if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+           return NULLPE;
+
+       if (in_line) {
+           if (pe -> pe_len = qp -> qb_len)
+               pe -> pe_prim = (PElementData) qp -> qb_data;
+           pe -> pe_inline = 1;
+       }
+       else
+           if (pe -> pe_len = qp -> qb_len) {
+               if ((pe -> pe_prim = PEDalloc (pe -> pe_len)) == NULLPED)
+                   goto no_mem;
+               PEDcpy (qp -> qb_data, pe -> pe_prim, pe -> pe_len);
+           }
+    }
+    else {
+       if ((pe = pe_alloc (class, PE_FORM_CONS, id)) == NULLPE)
+           return NULLPE;
+
+       do {
+           if (seq_add (pe, p = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
+                                          PE_PRIM_OCTS), -1) == NOTOK) {
+no_mem: ;
+               pe_free (pe);
+               return NULLPE;
+           }
+
+           p -> pe_len = qp -> qb_len;
+           if (in_line) {
+               p -> pe_prim = (PElementData) qp -> qb_data;
+               p -> pe_inline = 1;
+           }
+           else {
+               if ((p -> pe_prim = PEDalloc (p -> pe_len)) == NULLPED)
+                   goto no_mem;
+               PEDcpy (qp -> qb_data, p -> pe_prim, p -> pe_len);
+           }
+
+           qp = qp -> qb_forw;
+       }
+       while (qp != qb);
+    }
+
+    return pe;
+}
diff --git a/src/isode/psap/qb2str.c b/src/isode/psap/qb2str.c
new file mode 100644 (file)
index 0000000..ed2e206
--- /dev/null
@@ -0,0 +1,73 @@
+/* qb2str.c - qbuf to string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:22  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:29  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:12  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+char   *qb2str (q)
+register struct qbuf *q;
+{
+    register int    len;
+    register char  *b,
+                   *d;
+    register struct qbuf   *p;
+
+    p = q -> qb_forw, len = 0;
+    do {
+       len += p -> qb_len;
+
+       p = p -> qb_forw;
+    }
+    while (p != q);
+    q -> qb_len = len;
+
+    if ((b = d = malloc ((unsigned) (len + 1))) == NULL)
+       return NULLCP;
+
+    p = q -> qb_forw;
+    do {
+       bcopy (p -> qb_data, d, p -> qb_len);
+       d += p -> qb_len;
+
+       p = p -> qb_forw;
+    }
+    while (p != q);
+    *d = NULL;
+
+    return b;
+}
diff --git a/src/isode/psap/qb_free.c b/src/isode/psap/qb_free.c
new file mode 100644 (file)
index 0000000..af0edcc
--- /dev/null
@@ -0,0 +1,48 @@
+/* qb_free.c - free a list of qbufs */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:24  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:31  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:13  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    qb_free (qb)
+register struct qbuf *qb;
+{
+    QBFREE (qb);
+
+    free ((char *) qb);
+}
diff --git a/src/isode/psap/qb_pullup.c b/src/isode/psap/qb_pullup.c
new file mode 100644 (file)
index 0000000..bc29995
--- /dev/null
@@ -0,0 +1,80 @@
+/* qb_pullup.c - "pullup" a list of qbufs */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:32  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:13  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    qb_pullup (qb)
+register struct qbuf *qb;
+{
+    register int    len;
+    register char  *d;
+    register struct qbuf  *p,
+                         *qp,
+                         *qpp;
+
+    len = 0;
+#ifdef notdef          /* want null-termination... */
+    if ((p = qb -> qb_forw) -> qb_forw == qb)
+       return OK;
+#endif
+    for (p = qb -> qb_forw; p != qb; p = p -> qb_forw)
+       len += p -> qb_len;
+
+    if ((p = (struct qbuf *) malloc ((unsigned) (sizeof *p + len + 1)))
+           == NULL)
+       return NOTOK;
+    d = p -> qb_data = p -> qb_base;
+    p -> qb_len = len;
+
+    for (qp = qb -> qb_forw; qp != qb; qp = qpp) {
+       qpp = qp -> qb_forw;
+
+       remque (qp);
+
+       bcopy (qp -> qb_data, d, qp -> qb_len);
+       d += qp -> qb_len;
+
+       free ((char *) qp);
+    }
+    *d = NULL;
+
+    insque (p, qb);
+
+    return OK;
+}
diff --git a/src/isode/psap/qbuf2pe.c b/src/isode/psap/qbuf2pe.c
new file mode 100644 (file)
index 0000000..570f292
--- /dev/null
@@ -0,0 +1,88 @@
+/* qbuf2pe.c - read a PE from a SSDU */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:28  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:34  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:14  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#undef qbuf2pe
+#include "tailor.h"
+
+/* \f */
+
+#ifndef        DEBUG
+/* ARGSUSED */
+#endif
+
+PE     qbuf2pe (qb, len, result)
+register struct qbuf *qb;
+int    len;
+int    *result;
+{
+#ifdef notdef
+    register struct qbuf *qp;
+#endif
+    register PE            pe;
+    register PS            ps;
+
+#ifdef notdef          /* "inline" nonsense too difficult to handle */
+    if ((qp = qb -> qb_forw) != qb && qp -> qb_forw == qb) {
+       remque (qp);
+
+       return ssdu2pe (qp -> qb_data, qp -> qb_len, (char *) qp, result);
+    }
+#endif
+
+    if ((ps = ps_alloc (qbuf_open)) == NULLPS) {
+       *result = PS_ERR_NMEM;
+       return NULLPE;
+    }
+    if (qbuf_setup (ps, qb) == NOTOK || (pe = ps2pe (ps)) == NULLPE) {
+       if (ps -> ps_errno == PS_ERR_NONE)
+           ps -> ps_errno = PS_ERR_EOF;
+       *result = ps -> ps_errno;
+       ps_free (ps);
+       return NULLPE;
+    }
+
+    *result = PS_ERR_NONE;
+    ps_free (ps);
+
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_PDUS)
+       pe2text (psap_log, pe, 1, len);
+#endif
+
+    return pe;
+}
diff --git a/src/isode/psap/qbuf2pe_f.c b/src/isode/psap/qbuf2pe_f.c
new file mode 100644 (file)
index 0000000..2cfaec7
--- /dev/null
@@ -0,0 +1,345 @@
+/* qbuf2pe.c - build PE(s) from an SSDU assumed to be in qbuf(s) */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:30  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:35  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:14  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+static int  qb_read_cons ();
+static qbuf2data();
+
+/*
+ * The following macro takes one byte from a qbuf, stuffs it in c,
+ * and adjusts the qbuf.
+ */
+
+#define qbuf2char(c)   { \
+                               qp = Qb; \
+                               if (qp->qb_len > 0 && qp != Hqb) { \
+                                       (c) = *qp->qb_data++; \
+                                       Byteno++; \
+                                       if(--qp->qb_len == 0) { \
+                                               if(!(Qb = qp->qb_forw)) \
+                                                       abort(); \
+                                       } \
+                               } \
+                               else { \
+                                       SLOG (psap_log, LLOG_EXCEPTIONS, \
+                                         NULLCP, \
+                                         ("bad qbuf length=%d", \
+                                         ((qp == Hqb) ? 0: qp->qb_len))); \
+                                       *result = PS_ERR_EOF; \
+                                       if (pe) pe_free(pe); \
+                                       return(NULLPE); \
+                               } \
+                       }
+
+int            Byteno;
+int            Qbrefs;
+struct qbuf    *Hqb;
+struct qbuf    *Fqb;
+struct qbuf    *Qb;
+
+static int pe_id_overshift = PE_ID_MASK << (PE_ID_BITS - PE_ID_SHIFT);
+
+/* \f */
+
+PE
+qbuf2pe_f (result)
+int    *result;
+{
+       register PE     pe;
+       register struct qbuf *qp;
+       byte c, d;
+       register PElementClass class;
+       register PElementForm form;
+       register PElementID id;
+       register PElementLen   len;
+       register int    i;
+       register PElementLen j;
+
+       pe = NULLPE;
+
+       /*
+        * Just take the qbuf directly and build PEs.
+        * First, decode the id.
+        */
+
+       qbuf2char(c);
+
+       class = ((int)(c & PE_CLASS_MASK)) >> PE_CLASS_SHIFT;
+       form = ((int)(c & PE_FORM_MASK)) >> PE_FORM_SHIFT;
+       j = (c & PE_CODE_MASK);
+
+       if (j == PE_ID_XTND)
+               for (j = 0;; j <<= PE_ID_SHIFT) {
+                       qbuf2char(d);
+                       j |= d & PE_ID_MASK;
+                       if (!(d & PE_ID_MORE))
+                               break;
+                       if (j & pe_id_overshift) {
+#ifdef DEBUG
+                               DLOG (psap_log, LLOG_DEBUG,
+                                     ("j is %x d is %x %x %x %x\n",
+                                      j, d, *(Qb->qb_data-1),
+                                      *(Qb->qb_data-2),
+                                      *(Qb->qb_data-3)));
+#endif
+                               *result = PS_ERR_OVERID;
+                               return (NULLPE);
+                       }
+               }
+
+       id = j;
+
+       DLOG (psap_log, LLOG_DEBUG,
+               ("class=%d form=%d id=%d", class, form, id));
+
+       if ((pe = pe_alloc (class, form, id)) == NULLPE) {
+               *result = PS_ERR_NMEM;
+               return (NULLPE);
+       }
+
+       qbuf2char(c);
+
+       if ((i = c) & PE_LEN_XTND) {
+               if ((i &= PE_LEN_MASK) > sizeof (PElementLen)) {
+#ifdef DEBUG
+                       DLOG (psap_log, LLOG_DEBUG,
+                             ("c (%x) i (%x) %d is %x %x %x %x\n",
+                              c, i, sizeof(PElementLen),
+                              *(Qb->qb_data-1),
+                              *(Qb->qb_data-2),
+                              *(Qb->qb_data-3),
+                              *(Qb->qb_data-4)));
+                       qbprintf();
+#endif
+                       *result = PS_ERR_OVERLEN;
+                       return (NULLPE);
+               }
+
+               if (i) {
+                       for (j = 0; i-- > 0;) {
+                               qbuf2char(c);
+                               j = (j << 8) | (c & 0xff);
+                       }
+                       len = j;
+               }
+               else
+                       len = PE_LEN_INDF;
+       }
+       else
+               len = i;
+
+       SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", len));
+       pe -> pe_len = len;
+
+       /* Now get the value.  */
+
+       switch (pe -> pe_form) {
+       case PE_FORM_PRIM: 
+               if (len == PE_LEN_INDF) {
+                       *result = PS_ERR_INDF;
+                       goto you_lose;
+               }
+               if (len > 0) {
+                       qp = Qb;
+                       if (qp->qb_len >= len) {
+                               pe->pe_prim = (PElementData) qp->qb_data;
+                               pe->pe_inline = 1;
+                               Qbrefs++;
+                               Byteno += len;
+                               if (qp->qb_len == len) {
+                                       if(!(Qb = qp->qb_forw))
+                                               abort();
+                               }
+                               else {
+                                       qp->qb_len -= len;
+                                       qp->qb_data += len;
+                               }
+                       }
+                       else {
+                               if ((pe->pe_prim = PEDalloc (len)) == NULLPED) {
+                                       *result = PS_ERR_NMEM;
+                                       goto you_lose;
+                               }
+                               if (qbuf2data(pe->pe_prim, len) != len) {
+                                       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+                                                   ("bad qbuf lenght=%d",len));
+                                       *result = PS_ERR_EOF;
+                                       goto you_lose;
+                               }
+                       }
+               }
+               break;
+
+       case PE_FORM_CONS: 
+               if ((len == PE_LEN_INDF || len > 0) && 
+                       qb_read_cons (&pe -> pe_cons, len, result) == NOTOK)
+                               goto you_lose;
+               break;
+       }
+
+       return pe;
+
+you_lose: ;
+       if (psap_log -> ll_events & LLOG_PDUS) {
+           LLOG (psap_log, LLOG_PDUS, ("PE read thus far"));
+           pe2text (psap_log, pe, 1, *result);
+       }
+       
+       pe_free (pe);
+       return NULLPE;
+}
+
+/* \f */
+
+static int  qb_read_cons (pe, len, cresult)
+register PE    *pe;
+register PElementLen len;
+register int *cresult;
+{
+       register int    cc;
+       register PE    p, q;
+       int result;
+
+       *pe = NULLPE;
+       cc = Byteno + len;
+
+       if ((p = qbuf2pe_f (&result)) == NULLPE) {
+no_cons: ;
+#ifdef DEBUG
+               if (len == PE_LEN_INDF)
+                       LLOG (psap_log, LLOG_DEBUG,
+                         ("error building indefinite cons, %s",
+                                  ps_error (result)));
+               else
+                       LLOG (psap_log, LLOG_DEBUG,
+                         ("error building cons, stream at %d, wanted %d: %s",
+                                  Byteno, cc, ps_error (result)));
+#endif
+
+               *cresult = result;
+               return NOTOK;
+       }
+       *pe = p;
+
+       if (len == PE_LEN_INDF) {
+               if (p->pe_class == PE_CLASS_UNIV && p->pe_id == PE_UNIV_EOC) {
+                       pe_free (p);
+                       *pe = NULLPE;
+                       return OK;
+               }
+
+               for(q = p; p = qbuf2pe_f(&result); q = q->pe_next = p) {
+                       if (p->pe_class == PE_CLASS_UNIV &&
+                                               p->pe_id == PE_UNIV_EOC) {
+                               pe_free (p);
+                               return OK;
+                       }
+               }
+               goto no_cons;
+       }
+
+       for (q = p;; q = q -> pe_next = p) {
+               if (cc < Byteno) {
+#ifdef DEBUG
+                       DLOG (psap_log, LLOG_DEBUG,
+                             ("cc %d Byteno %d last length was %d\n",
+                              cc, Byteno));
+                       qbprintf();
+#endif
+                       *cresult = PS_ERR_LEN;
+                       return (NOTOK);
+               }
+               if (cc == Byteno) {
+                       return OK;
+               }
+               if ((p = qbuf2pe_f (&result)) == NULLPE)
+                       goto no_cons;
+       }
+}
+
+/* \f */
+
+static qbuf2data(data, len)
+PElementData data;
+PElementLen len;
+{
+       register struct qbuf *qp;
+       register int i, cc;
+
+       for (qp = Qb, cc = 0; len > 0; data += i, cc += i, len -= i) {
+               if (qp == Hqb)
+                       goto leave;
+
+               i = min (qp -> qb_len, len);
+               bcopy (qp -> qb_data, (char *) data, i);
+
+               qp -> qb_len -= i;
+               if (qp -> qb_len <= 0) {
+                       if(!(Qb = (qp = qp->qb_forw)))
+                               abort();
+               }
+               else
+                       qp->qb_data += i;
+       }
+
+leave:
+       Byteno += cc;
+       return cc;
+}
+
+/* \f */
+
+#ifdef DEBUG
+qbprintf()
+{
+       int len;
+       struct qbuf *qb;
+       char *cp;
+
+       for(qb = Fqb, cp = qb->qb_data;qb != Hqb;qb = qb->qb_forw) {
+               for(len = 0;len < qb->qb_len;cp++, len++) {
+                   (void) ll_printf (psap_log, "%x ", *cp);
+                   if((len % 15) == 0) (void) ll_printf(psap_log, "\n");
+               }
+       }
+       (void) ll_sync (psap_log);
+}
+#endif
diff --git a/src/isode/psap/qbuf2ps.c b/src/isode/psap/qbuf2ps.c
new file mode 100644 (file)
index 0000000..7581c64
--- /dev/null
@@ -0,0 +1,98 @@
+/* qbuf2ps.c - qbuf-backed abstractions for PStreams */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:32  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:37  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:15  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  qbuf_read (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    register int cc,
+                i;
+    register struct qbuf *qb,
+                        *qp;
+
+    if ((qb = (struct qbuf *) ps -> ps_addr) == NULL)
+       return 0;
+
+    for (qp = NULL, cc = 0; n > 0; data += i, cc += i, n -= i) {
+       if (qp == NULL && (qp = qb -> qb_forw) == qb)
+           return cc;
+
+       i = min (qp -> qb_len, n);
+       bcopy (qp -> qb_data, (char *) data, i);
+
+       qp -> qb_data += i, qp -> qb_len -= i;
+       if (qp -> qb_len <= 0) {
+           remque (qp);
+
+           free ((char *) qp);
+           qp = NULL;
+       }
+    }
+
+    return cc;
+}
+
+
+static int  qbuf_close (ps)
+register PS    ps;
+{
+    register struct qbuf   *qb;
+
+    if ((qb = (struct qbuf *) ps -> ps_addr) == NULL)
+       return;
+
+    QBFREE (qb);
+}
+
+/* \f */
+
+int    qbuf_open (ps)
+register PS    ps;
+{
+    ps -> ps_readP = qbuf_read;
+    ps -> ps_closeP = qbuf_close;
+
+    return OK;
+}
diff --git a/src/isode/psap/real2prim.c b/src/isode/psap/real2prim.c
new file mode 100644 (file)
index 0000000..a05fbf7
--- /dev/null
@@ -0,0 +1,121 @@
+/* real2prim.c - real to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ * Contributed by Julian Onions, Nottingham University.
+ * July 1989 - this is awful stuff!
+ *
+ * $
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials are subject to the restrictions of a license agreement.
+ *    Consult the Preface in the User's Manual for the full terms of
+ *    this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include "psap.h"
+
+/* \f */
+
+PE     real2prim (d, class, id)
+register double d;
+PElementClass  class;
+PElementID     id;
+{
+       register PE pe;
+       double  mant, nm;
+       int     exponent;
+       int     expsign;
+       int     parts[sizeof (double)];
+       int     sign, i, maxi, mask;
+       int     n, explen;
+       PElementData    dp;
+
+       if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+               return NULLPE;
+
+       if (d == 0.0)
+               return pe;
+
+       mant = frexp (d, &exponent);
+
+       if (mant < 0.0) {
+               sign = -1;
+               mant = -mant;
+       }
+       else    sign = 1;
+
+       nm = mant;
+       for (i = 0; i < sizeof (double) ; i++) {
+               int intnm;
+               nm *= (1<<8);
+               intnm = ((int)nm) & 0xff;
+               nm -= intnm;
+               if (intnm)
+                       maxi = i + 1;
+               parts[i] = intnm;
+       }
+
+       exponent -= 8 * maxi;
+
+       expsign = exponent >= 0 ? exponent : exponent ^ (-1);
+       mask = 0x1ff << (((n = sizeof exponent) - 1) * 8 - 1);
+       while (n > 1 && (expsign & mask) == 0)
+               mask >>= 8, n--;
+
+       explen = n;
+       if (n > 3)
+               n ++;
+
+       if ((pe -> pe_prim = PEDalloc (n + maxi + 1)) == NULLPED) {
+               pe_free (pe);
+               return NULLPE;
+       }
+
+       dp = pe -> pe_prim + (pe -> pe_len = n + maxi + 1);
+
+       for (; maxi > 0; maxi --)
+               *--dp = parts[maxi - 1];
+       for (n = explen; n-- > 0; exponent >>= 8)
+               *--dp = exponent & 0xff;
+       if (explen > 3)
+               *--dp = explen & 0xff;
+
+       switch (explen) {
+           case 1:
+               explen = PE_REAL_B_EF1;
+               break;
+           case 2:
+               explen = PE_REAL_B_EF2;
+               break;
+           case 3:
+               explen = PE_REAL_B_EF3;
+               break;
+           default:
+               explen = PE_REAL_B_EF3;
+               break;
+       }
+       *--dp = PE_REAL_BINENC
+                   | PE_REAL_B_B2
+                   | (sign == -1 ? PE_REAL_B_S : 0)
+                   | explen;
+       return pe;
+}
+
+                       
+
+       
diff --git a/src/isode/psap/seq_add.c b/src/isode/psap/seq_add.c
new file mode 100644 (file)
index 0000000..ca5f027
--- /dev/null
@@ -0,0 +1,72 @@
+/* seq_add.c - add an element to a sequence */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:36  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:40  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:16  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    seq_add (pe, r, i)
+register PE    pe,
+               r;
+register int   i;
+{
+    register PE           *p,
+                   q;
+
+    if (r == NULLPE)
+       return pe_seterr (pe, PE_ERR_NMEM, NOTOK);
+
+    if (i < 0)
+       i = pe -> pe_cardinal;
+    for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next)
+       if (q -> pe_offset == i) {
+           r -> pe_next = q -> pe_next;
+           pe_free (q);
+           break;
+       }
+       else
+           if (q -> pe_offset > i) {
+               r -> pe_next = q;
+               break;
+           }
+
+    *p = r;
+    if ((r -> pe_offset = i) >= pe -> pe_cardinal)
+       pe -> pe_cardinal = i + 1;
+
+    return OK;
+}
diff --git a/src/isode/psap/seq_addon.c b/src/isode/psap/seq_addon.c
new file mode 100644 (file)
index 0000000..3b5db64
--- /dev/null
@@ -0,0 +1,54 @@
+/* seq_addon.c - add a member to the end of a sequence (efficiency hack) */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:38  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:42  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:16  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    seq_addon (pe, last, new)
+PE     pe,
+        last,
+        new;
+{
+    if (pe == NULLPE)
+       return NOTOK;
+    if (last == NULLPE)
+       return seq_add (pe, new, -1);
+    new -> pe_offset = pe -> pe_cardinal++;
+    last -> pe_next = new;
+    return OK;
+}
diff --git a/src/isode/psap/seq_del.c b/src/isode/psap/seq_del.c
new file mode 100644 (file)
index 0000000..019e47c
--- /dev/null
@@ -0,0 +1,64 @@
+/* seq_del.c - delete a member from a sequence */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:40  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:43  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:17  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    seq_del (pe, i)
+register PE    pe;
+register int   i;
+{
+    int            offset;
+    register PE           *p,
+                   q;
+
+    for (p = &pe -> pe_cons, offset = 0;
+           q = *p;
+           p = &q -> pe_next, offset = q -> pe_offset)
+       if (q -> pe_offset == i) {
+           if (((*p) = q -> pe_next) == NULLPE)
+               pe -> pe_cardinal = offset + 1;
+           pe_free (q);
+           return OK;
+       }
+       else
+           if (q -> pe_offset > i)
+               break;
+       
+    return pe_seterr (pe, PE_ERR_MBER, NOTOK);
+}
diff --git a/src/isode/psap/seq_find.c b/src/isode/psap/seq_find.c
new file mode 100644 (file)
index 0000000..c526b4b
--- /dev/null
@@ -0,0 +1,56 @@
+/* seq_find.c - find an element in a sequence */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:41  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:45  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:17  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     seq_find (pe, i)
+register PE    pe;
+register int   i;
+{
+    register PE            p;
+
+    if (i >= pe -> pe_cardinal)
+       return pe_seterr (pe, PE_ERR_MBER, NULLPE);
+
+    for (p = pe -> pe_cons; p; p = p -> pe_next)
+       if (p -> pe_offset == i)
+           break;
+
+    return p;
+}
diff --git a/src/isode/psap/set_add.c b/src/isode/psap/set_add.c
new file mode 100644 (file)
index 0000000..fafb12b
--- /dev/null
@@ -0,0 +1,63 @@
+/* set_add.c - add member to set */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:43  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:46  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:18  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    set_add (pe, r)
+register PE    pe,
+               r;
+{
+    register int     pe_id;
+    register PE            *p,
+                   q;
+
+    if (r == NULLPE)
+       return pe_seterr (pe, PE_ERR_NMEM, NOTOK);
+
+    pe_id = PE_ID (r -> pe_class, r -> pe_id);
+    for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next)
+       if (PE_ID (q -> pe_class, q -> pe_id) == pe_id) {
+           r -> pe_next = q -> pe_next;
+           pe_free (q);
+           break;
+       }
+
+    *p = r;
+    return OK;
+}
diff --git a/src/isode/psap/set_addon.c b/src/isode/psap/set_addon.c
new file mode 100644 (file)
index 0000000..dae5805
--- /dev/null
@@ -0,0 +1,55 @@
+/* set_addon.c - add member to end of a set */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:45  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:48  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:18  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    set_addon (pe, last, new)
+PE     pe,
+        last,
+        new;
+{
+    if (pe == NULLPE)
+       return NOTOK;
+    if (last == NULLPE)
+       return set_add (pe, new);
+    new -> pe_offset = pe -> pe_cardinal++;
+    last -> pe_next = new;
+
+    return OK;
+}
diff --git a/src/isode/psap/set_del.c b/src/isode/psap/set_del.c
new file mode 100644 (file)
index 0000000..b4da982
--- /dev/null
@@ -0,0 +1,60 @@
+/* set_del.c - remove member from set */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:47  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:49  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:19  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+int    set_del (pe, class, id)
+register PE    pe;
+register PElementClass class;
+register PElementID id;
+{
+    register int    pe_id;
+    register PE           *p,
+                   q;
+
+    pe_id = PE_ID (class, id);
+    for (p = &pe -> pe_cons; q = *p; p = &q -> pe_next)
+       if (PE_ID (q -> pe_class, q -> pe_id) == pe_id) {
+           (*p) = q -> pe_next;
+           pe_free (q);
+           return OK;
+       }
+
+    return pe_seterr (pe, PE_ERR_MBER, NOTOK);
+}
diff --git a/src/isode/psap/set_find.c b/src/isode/psap/set_find.c
new file mode 100644 (file)
index 0000000..d6d87b0
--- /dev/null
@@ -0,0 +1,56 @@
+/* set_find.c - find member of a set */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:49  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:51  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:19  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     set_find (pe, class, id)
+register PE    pe;
+register PElementClass class;
+register PElementID id;
+{
+    register int    pe_id;
+    register PE            p;
+
+    pe_id = PE_ID (class, id);
+    for (p = pe -> pe_cons; p; p = p -> pe_next)
+       if (PE_ID (p -> pe_class, p -> pe_id) == pe_id)
+           break;
+
+    return p;
+}
diff --git a/src/isode/psap/sprintoid.c b/src/isode/psap/sprintoid.c
new file mode 100644 (file)
index 0000000..fb85a61
--- /dev/null
@@ -0,0 +1,64 @@
+/* sprintoid.c - object identifier to string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:51  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:53  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:21  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+char   *sprintoid (oid)
+register OID oid;
+{
+    register int    i;
+    register unsigned int  *ip;
+    register char  *bp,
+                  *cp;
+    static char buffer[BUFSIZ];
+
+    if (oid == NULLOID || oid -> oid_nelem < 1)
+       return "";
+
+    bp = buffer;
+
+    for (ip = oid -> oid_elements, i = oid -> oid_nelem, cp = "";
+           i-- > 0;
+           ip++, cp = ".") {
+       (void) sprintf (bp, "%s%u", cp, *ip);
+       bp += strlen (bp);
+    }
+
+    return buffer;
+}
diff --git a/src/isode/psap/sprintref.c b/src/isode/psap/sprintref.c
new file mode 100644 (file)
index 0000000..da4aa7a
--- /dev/null
@@ -0,0 +1,99 @@
+/* sprintref.c - manage encoded session addresses */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:54  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:54  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:22  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "ssap.h"
+
+/* \f */
+
+char   *sprintref (sr)
+struct SSAPref *sr;
+{
+    register char  *cp;
+    static char buffer[BUFSIZ];
+
+    cp = buffer;
+    *cp++ = '<';
+
+    if (sr -> sr_ulen) {
+       if (sr -> sr_ulen > 1 && *(sr -> sr_udata + 1) + 2 == sr -> sr_ulen)
+           (void) sprintf (cp, "%*.*s", sr -> sr_ulen - 2, sr -> sr_ulen - 2,
+                   sr -> sr_udata + 2);
+       else
+           (void) sprintf (cp, "%*.*s", sr -> sr_ulen, sr -> sr_ulen,
+                   sr -> sr_udata);
+       cp += strlen (cp);
+    }
+    *cp++ = ',';
+
+    if (sr -> sr_clen) {
+       if (sr -> sr_clen > 1 && *(sr -> sr_cdata + 1) + 2 == sr -> sr_clen)
+           (void) sprintf (cp, "%*.*s", sr -> sr_clen - 2, sr -> sr_clen - 2,
+                   sr -> sr_cdata + 2);
+       else
+           (void) sprintf (cp, "%*.*s", sr -> sr_clen, sr -> sr_clen,
+                   sr -> sr_cdata);
+       cp += strlen (cp);
+    }
+    *cp++ = ',';
+
+    if (sr -> sr_alen) {
+       if (sr -> sr_alen > 1 && *(sr -> sr_adata + 1) + 2 == sr -> sr_alen)
+           (void) sprintf (cp, "%*.*s", sr -> sr_alen - 2, sr -> sr_alen - 2,
+                   sr -> sr_adata + 2);
+       else
+           (void) sprintf (cp, "%*.*s", sr -> sr_alen, sr -> sr_alen,
+                   sr -> sr_adata);
+       cp += strlen (cp);
+    }
+    *cp++ = ',';
+
+    if (sr -> sr_vlen) {
+       if (sr -> sr_vlen > 1 && *(sr -> sr_vdata + 1) + 2 == sr -> sr_vlen)
+           (void) sprintf (cp, "%*.*s", sr -> sr_vlen - 2, sr -> sr_vlen - 2,
+                   sr -> sr_vdata + 2);
+       else
+           (void) sprintf (cp, "%*.*s", sr -> sr_vlen, sr -> sr_vlen,
+                   sr -> sr_vdata);
+       cp += strlen (cp);
+    }
+    *cp++ = '>';
+
+    *cp = NULL;
+
+    return buffer;
+}
diff --git a/src/isode/psap/ssdu2pe.c b/src/isode/psap/ssdu2pe.c
new file mode 100644 (file)
index 0000000..c6ea405
--- /dev/null
@@ -0,0 +1,81 @@
+/* ssdu2pe.c - read a PE from SSDU */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:56  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:56  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:22  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+PE     ssdu2pe (base, len, realbase, result)
+char   *base,
+       *realbase;
+int    len;
+int    *result;
+{
+    register PE pe;
+    register PS ps;
+
+    if ((ps = ps_alloc (str_open)) == NULLPS) {
+       *result = PS_ERR_NMEM;
+       return NULLPE;
+    }
+    if (str_setup (ps, base, len, 1) == OK) {
+       if (!realbase)
+           ps -> ps_inline = 0;
+       if (pe = ps2pe (ps)) {
+           if (realbase)
+               pe -> pe_realbase = realbase;
+
+           ps -> ps_errno = PS_ERR_NONE;
+       }
+       else
+           if (ps -> ps_errno == PS_ERR_NONE)
+               ps -> ps_errno = PS_ERR_EOF;
+    }
+
+    *result = ps -> ps_errno;    
+
+    ps -> ps_inline = 1;
+    ps_free (ps);
+
+#ifdef DEBUG
+    if (pe && (psap_log -> ll_events & LLOG_PDUS))
+       pe2text (psap_log, pe, 1, len);
+#endif
+
+    return pe;
+}
diff --git a/src/isode/psap/std2ps.c b/src/isode/psap/std2ps.c
new file mode 100644 (file)
index 0000000..6ccaa52
--- /dev/null
@@ -0,0 +1,98 @@
+/* std2ps.c - stdio-backed abstraction for PStreams */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:34:58  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:57  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:23  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+/* ARGSUSED */
+
+static int  std_read (ps, data, n, in_line)
+PS     ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    int            i;
+
+    if ((i = fread ((char *) data, sizeof *data, (int) n,
+                   (FILE *) ps -> ps_addr)) == NOTOK)
+       ps -> ps_errno = PS_ERR_IO;
+
+    return i;
+}
+
+
+/* ARGSUSED */
+
+static int  std_write (ps, data, n, in_line)
+PS     ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    int            i;
+
+
+    if ((i = fwrite ((char *) data, sizeof *data, (int) n,
+                    (FILE *) ps -> ps_addr)) == NOTOK)
+       ps -> ps_errno = PS_ERR_IO;
+
+    return i;
+}
+
+
+int  std_flush (ps)
+PS     ps;
+{
+    if (fflush ((FILE *) ps -> ps_addr) != EOF)
+       return OK;
+
+    return ps_seterr (ps, PS_ERR_IO, NOTOK);
+}
+
+/* \f */
+
+int    std_open (ps)
+register PS    ps;
+{
+    ps -> ps_readP = std_read;
+    ps -> ps_writeP = std_write;
+    ps -> ps_flushP = std_flush;
+
+    return OK;
+}
diff --git a/src/isode/psap/str2oid.c b/src/isode/psap/str2oid.c
new file mode 100644 (file)
index 0000000..1e4f1c1
--- /dev/null
@@ -0,0 +1,57 @@
+/* str2oid.c - string to object identifier */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:00  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:38:59  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:23  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+OID    str2oid (s)
+char    *s;
+{
+    int            i;
+    static struct OIDentifier   oids;
+    static unsigned int elements[NELEM + 1];
+
+    if ((i = str2elem (s, elements)) < 1
+           || elements[0] > 2
+           || (i > 1 && elements[0] < 2 && elements[1] > 39))
+       return NULLOID;
+
+    oids.oid_elements = elements, oids.oid_nelem = i;
+
+    return (&oids);
+}
diff --git a/src/isode/psap/str2pe.c b/src/isode/psap/str2pe.c
new file mode 100644 (file)
index 0000000..6dd6717
--- /dev/null
@@ -0,0 +1,212 @@
+/* str2pe.c - create an Inline CONStructor PElement */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:02  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:00  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:24  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+/* \f */
+
+PElementLen    str_get_len ();
+static int  str_get_start ();
+
+/* \f */
+
+#define        seterr(e,v)             (*result = (e), (v))
+
+
+PE     str2pe (s, len, advance, result)
+char   *s;
+int    len,
+       *advance,
+       *result;
+{
+#ifdef DEBUG
+    int            n = len;
+#endif
+    char   *sp;
+    PElementClass   class;
+    PElementForm    form;
+    PElementID    id;
+    PElementLen plen;
+    register PE            pe;
+
+    *result = PS_ERR_NONE;
+
+    sp = s;
+    if (str_get_start (&sp, &len, &class, &form, &id, &plen, result) == NOTOK)
+       return NULLPE;
+
+    if (form == PE_FORM_CONS)
+       form = PE_FORM_ICONS;
+
+    if (plen == PE_LEN_INDF
+           && (plen = str_get_len (sp, len, result)) == PE_LEN_INDF)
+       return NULLPE;
+
+    if ((pe = pe_alloc (class, form, id)) == NULLPE)
+       return seterr (PS_ERR_NMEM, NULLPE);
+
+    pe -> pe_ilen = sp - s;
+    if (form == PE_FORM_ICONS) {
+       pe -> pe_len = pe -> pe_ilen + plen;
+       pe -> pe_prim = (PElementData) s;
+    }
+    else
+       if (pe -> pe_len = plen)
+           pe -> pe_prim = (PElementData) sp;
+
+    pe -> pe_inline = 1;
+
+    if (advance)
+       *advance = pe -> pe_ilen + plen;
+
+#ifdef DEBUG
+    if (psap_log -> ll_events & LLOG_PDUS)
+       pe2text (psap_log, pe, 1, n);
+#endif
+
+    return pe;
+}
+
+/* \f */
+
+static int  str_get_start (sp, n, class, form, id, plen, result)
+char  **sp;
+int    *n,
+       *result;
+PElementClass *class;
+PElementForm *form;
+PElementID *id;
+PElementLen *plen;
+{
+    register int i,
+                len;
+    register char *s;
+    byte    c,
+           d;
+    register PElementID    jd;
+    register PElementLen qlen;
+
+    s = *sp, len = *n;
+    if (len-- <= 0)
+       return seterr (PS_ERR_EOF, NOTOK);
+    c = *s++;
+
+    *class = ((int)(c & PE_CLASS_MASK)) >> PE_CLASS_SHIFT;
+    *form = ((int)(c & PE_FORM_MASK)) >> PE_FORM_SHIFT;
+    if ((jd = (c & PE_CODE_MASK)) == PE_ID_XTND)
+       for (jd = 0;; jd <<= PE_ID_SHIFT) {
+           if (len-- <= 0)
+               return seterr (PS_ERR_EOFID, NOTOK);
+           d = *s++;
+
+           jd |= d & PE_ID_MASK;
+           if (!(d & PE_ID_MORE))
+               break;
+           if (jd & (PE_ID_MASK << (PE_ID_SHIFT - 1)))
+               return seterr (PS_ERR_OVERID, NOTOK);
+       }
+    *id = jd;
+#ifdef DEBUG
+    SLOG (psap_log, LLOG_DEBUG, NULLCP,
+         ("class=%d form=%d id=%d", *class, *form, *id));
+#endif
+
+    if (len-- <= 0)
+       return seterr (PS_ERR_EOFLEN, NOTOK);
+    c = *s++;
+
+    if ((i = c) & PE_LEN_XTND) {
+       if ((i &= PE_LEN_MASK) > sizeof (PElementLen))
+           return seterr (PS_ERR_OVERLEN, NOTOK);
+
+       if (i) {
+           for (qlen = 0; i-- > 0;) {
+               if (len-- <= 0)
+                   return seterr (PS_ERR_EOFLEN, NOTOK);
+               c = *s++;
+
+               qlen = (qlen << 8) | (c & 0xff);
+           }
+
+           *plen = qlen;
+       }
+       else
+           if (*form == PE_FORM_PRIM)
+               return seterr (PS_ERR_INDF, NOTOK);
+           else
+               *plen = PE_LEN_INDF;
+    }
+    else
+       *plen = i;
+#ifdef DEBUG
+    SLOG (psap_log, LLOG_DEBUG, NULLCP, ("len=%d", *plen));
+#endif
+
+    *sp = s, *n = len;
+
+    return OK;
+}
+
+/* \f */
+
+static PElementLen  str_get_len (s, len, result)
+char   *s;
+int    len,
+       *result;
+{
+    char   *sp;
+    PElementClass class;
+    PElementForm form;
+    PElementID id;
+    PElementLen plen;
+
+    for (sp = s;;) {
+       if (str_get_start (&sp, &len, &class, &form, &id, &plen, result)
+               == NOTOK)
+           return PE_LEN_INDF;
+
+       if (class == PE_CLASS_UNIV && id == PE_UNIV_EOC)
+           return ((PElementLen) (sp - s));
+
+       if (plen == PE_LEN_INDF
+               && (plen = str_get_len (sp, len, result)) == PE_LEN_INDF)
+           return PE_LEN_INDF;
+
+       sp += plen, len -= plen;
+    }
+}
diff --git a/src/isode/psap/str2prim.c b/src/isode/psap/str2prim.c
new file mode 100644 (file)
index 0000000..54a782d
--- /dev/null
@@ -0,0 +1,62 @@
+/* str2prim.c - octet string to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:04  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:02  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:24  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     str2prim (s, len, class, id)
+register char *s;
+register int len;
+PElementClass  class;
+PElementID     id;
+{
+    register PE            pe;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    if (len && (pe -> pe_prim = PEDalloc (pe -> pe_len = len)) == NULLPED) {
+       pe_free (pe);
+       return NULLPE;
+    }
+
+    if (s)
+       PEDcpy (s, pe -> pe_prim, len);
+
+    return pe;
+}
diff --git a/src/isode/psap/str2ps.c b/src/isode/psap/str2ps.c
new file mode 100644 (file)
index 0000000..9218e30
--- /dev/null
@@ -0,0 +1,153 @@
+/* str2ps.c - string-backed abstraction for PStreams */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:06  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:03  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:25  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+/* ARGSUSED */
+
+static int str_read (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    register int    cc;
+
+    if (ps -> ps_base == NULLCP || (cc = ps -> ps_cnt) <= 0)
+       return 0;
+    if (cc > n)
+       cc = n;
+
+    bcopy (ps -> ps_ptr, (char *) data, cc);
+    ps -> ps_ptr += cc, ps -> ps_cnt -= cc;
+
+    return cc;
+}
+
+
+/* ARGSUSED */
+
+static int str_write (ps, data, n, in_line)
+register PS    ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    register int    cc;
+    register char  *cp;
+
+    if (ps -> ps_base == NULLCP) {
+       if ((cp = malloc ((unsigned) (cc = n + BUFSIZ))) == NULLCP)
+           return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+       ps -> ps_base = ps -> ps_ptr = cp;
+       ps -> ps_bufsiz = ps -> ps_cnt = cc;
+    }
+    else
+       if (ps -> ps_cnt < n) {
+           register int    curlen = ps -> ps_ptr - ps -> ps_base;
+
+           if (ps -> ps_inline) {
+               n = ps -> ps_cnt;
+               goto partial;
+           }
+
+           if ((cp = realloc (ps -> ps_base,
+                                     (unsigned) (ps -> ps_bufsiz
+                                                 + (cc = n + BUFSIZ))))
+                   == NULLCP)
+               return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+           ps -> ps_ptr = (ps -> ps_base = cp) + curlen;
+           ps -> ps_bufsiz += cc, ps -> ps_cnt += cc;
+       }
+partial: ;
+
+    bcopy ((char *) data, ps -> ps_ptr, n);
+    ps -> ps_ptr += n, ps -> ps_cnt -= n;
+
+    return n;
+}
+
+
+static int str_close (ps)
+register PS    ps;
+{
+    if (ps -> ps_base && !ps -> ps_inline)
+       free (ps -> ps_base);
+
+    return OK;
+}
+
+/* \f */
+
+int    str_open (ps)
+register PS    ps;
+{
+    ps -> ps_readP = str_read;
+    ps -> ps_writeP = str_write;
+    ps -> ps_closeP = str_close;
+
+    return OK;
+}
+
+
+int    str_setup (ps, cp, cc, in_line)
+register PS    ps;
+register char  *cp;
+register int   cc;
+int    in_line;
+{
+    register char  *dp;
+
+    if (in_line) {
+       ps -> ps_inline = 1;
+       ps -> ps_base = ps -> ps_ptr = cp;
+       ps -> ps_bufsiz = ps -> ps_cnt = cc;
+    }
+    else
+       if (cc > 0) {
+           if ((dp = malloc ((unsigned) (cc))) == NULLCP)
+               return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+           ps -> ps_base = ps -> ps_ptr = dp;
+           if (cp != NULLCP)
+               bcopy (cp, dp, cc);
+           ps -> ps_bufsiz = ps -> ps_cnt = cc;
+       }
+
+    return OK;
+}
diff --git a/src/isode/psap/str2qb.c b/src/isode/psap/str2qb.c
new file mode 100644 (file)
index 0000000..51b1dd6
--- /dev/null
@@ -0,0 +1,72 @@
+/* str2qb.c - string to qbuf */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:09  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:05  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:25  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+struct qbuf *str2qb (s, len, head)
+char   *s;
+int    len,
+       head;
+{
+    register struct qbuf *qb,
+                        *pb;
+
+    if ((pb = (struct qbuf *) malloc ((unsigned) (sizeof *pb + len))) == NULL)
+       return NULL;
+
+    if (head) {
+       if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) {
+           free ((char *) pb);
+           return NULL;
+       }
+       qb -> qb_forw = qb -> qb_back = qb;
+       qb -> qb_data = NULL, qb -> qb_len = len;
+       insque (pb, qb);
+    }
+    else {
+       pb -> qb_forw = pb -> qb_back = pb;
+       qb = pb;
+    }
+
+    pb -> qb_data = pb -> qb_base;
+    if ((pb -> qb_len = len) > 0 && s)
+       bcopy (s, pb -> qb_data, len);
+
+    return qb;
+}
diff --git a/src/isode/psap/strb2bitstr.c b/src/isode/psap/strb2bitstr.c
new file mode 100644 (file)
index 0000000..c8d19ee
--- /dev/null
@@ -0,0 +1,74 @@
+/* strb2bitstr.c - string of bits to bit string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:11  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:07  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:26  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     strb2bitstr (cp, len, class, id)
+register char  *cp;
+register int     len;
+PElementClass class;
+PElementID id;
+{
+    register int    i,
+                   j,
+                    bit,
+                   mask;
+    register PE            p;
+
+    if ((p = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    p = prim2bit (p);
+    if (len > 0 && bit_off (p, len - 1) == NOTOK) {
+no_mem: ;
+        pe_free (p);
+        return NULLPE;
+    }
+
+    for (bit = (*cp & 0xff), i = 0, mask = 1 << (j = 7); i < len; i++) {
+       if ((bit & mask) && bit_on (p, i) == NOTOK)
+           goto no_mem;
+       if (j-- == 0)
+           bit = *++cp & 0xff, mask = 1 << (j = 7);
+       else
+           mask >>= 1;
+    }
+
+    return p;
+}
diff --git a/src/isode/psap/strb2int.c b/src/isode/psap/strb2int.c
new file mode 100644 (file)
index 0000000..18ce3f7
--- /dev/null
@@ -0,0 +1,62 @@
+/* converts a bit string - output of bitstr2strb() - to an integer */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:13  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:08  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:26  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+int    strb2int (cp, len)
+register char   *cp;
+register int   len;
+{
+    register int    i,
+                   j,
+                   bit,
+                   mask,
+                   n;
+
+    n = 0;
+    for (bit = (*cp & 0xff), i = 0, mask = 1 << (j = 7); i < len; i++) {
+       if (bit & mask)
+           n |= 1 << i;
+       if (j-- == 0)
+           bit = *++cp & 0xff, mask = 1 << (j = 7);
+       else
+           mask >>= 1;
+    }
+
+    return n;
+}
diff --git a/src/isode/psap/test/test1.pl b/src/isode/psap/test/test1.pl
new file mode 100644 (file)
index 0000000..b911587
--- /dev/null
@@ -0,0 +1,130 @@
+( UNIV BOOL 0x1
+    0xff
+)
+( UNIV INT 0x5
+    0x01000000
+    0x00
+)
+( UNIV INT 0x1
+    0x01
+)
+( UNIV BITS 0x7
+    0x040a3b5f
+    0x291cd0
+)
+( UNIV BITS
+    ( UNIV BITS 0x3
+        0x000a3b
+    )
+    ( UNIV BITS 0x5
+        0x045f291c
+        0xd0
+    )
+)
+( UNIV OCTS 0x9
+    "Hi T"
+    "here"
+    "."
+)
+( UNIV OCTS
+    ( UNIV OCTS 0x4
+        "Hi T"
+    )
+    ( UNIV OCTS 0x5
+        "here"
+        "."
+    )
+)
+( UNIV NULL 0x0 )
+( UNIV SEQ
+    ( UNIV IA5S 0x5
+        "Smit"
+        "h"
+    )
+    ( UNIV NULL 0x0 )
+)
+( UNIV SEQ
+    ( UNIV IA5S 0x5
+        "Smit"
+        "h"
+    )
+    ( UNIV IA5S 0x5
+        "Jone"
+        "s"
+    )
+)
+( UNIV SEQ
+    ( UNIV IA5S 0x5
+        "Smit"
+        "h"
+    )
+    ( UNIV BOOL 0x1
+        0xff
+    )
+)
+( UNIV SET
+    ( CONT 0x0
+        ( UNIV IA5S 0x5
+            "Smit"
+            "h"
+        )
+    )
+)
+( APPL 0x3
+    ( UNIV IA5S 0x5
+        "Jone"
+        "s"
+    )
+)
+( APPL 0x3 0x5
+    0x4a6f6e65
+    0x73
+)
+( CONT 0x0
+    ( UNIV IA5S 0x5
+        "Smit"
+        "h"
+    )
+)
+( UNIV IA5S 0x5
+    "Smit"
+    "h"
+)
+( UNIV IA5S 0x9
+    "Hi T"
+    "here"
+    "."
+)
+( UNIV NUMS 0x3
+    "234"
+)
+( UNIV PRTS 0xe
+    "Unit"
+    "ed K"
+    "ingd"
+    "om"
+)
+( UNIV T61S 0x7
+    "Espa"
+    0xc46e61
+)
+( UNIV VTXS 0x6
+    0x1b4d4849
+    0x4748
+)
+( UNIV GENT 0xa
+    "8201"
+    "0207"
+    "00"
+)
+( UNIV UTCT 0xb
+    "8201"
+    "0212"
+    "00Z"
+)
+( UNIV UTCT 0xf
+    "8201"
+    "0207"
+    "00-0"
+    "500"
+)
diff --git a/src/isode/psap/test/test2.pl b/src/isode/psap/test/test2.pl
new file mode 100644 (file)
index 0000000..3cb7415
--- /dev/null
@@ -0,0 +1,375 @@
+( UNIV BOOL 0x1
+    0xff
+)
+( UNIV BOOL 0x1
+    0x00
+)
+( UNIV INT 0x2
+    0x7fff
+)
+( UNIV INT 0x2
+    0x8000
+)
+( UNIV INT 0x3
+    0x008000
+)
+( UNIV INT 0x3
+    0xff7fff
+)
+( UNIV BITS 0x1
+    0x00
+)
+( UNIV BITS 0x2
+    0x0780
+)
+( UNIV BITS 0x2
+    0x06c0
+)
+( UNIV BITS 0x2
+    0x05e0
+)
+( UNIV BITS 0x2
+    0x04f0
+)
+( UNIV BITS 0x2
+    0x03f8
+)
+( UNIV BITS 0x2
+    0x02fc
+)
+( UNIV BITS 0x2
+    0x01fe
+)
+( UNIV BITS 0x2
+    0x00ff
+)
+( UNIV BITS 0x2
+    0x04f0
+)
+( UNIV BITS 0x2
+    0x00ff
+)
+( UNIV OCTS 0x1
+    0x80
+)
+( UNIV OCTS 0x1
+    0xf0
+)
+( UNIV OCTS 0x1
+    0xff
+)
+( UNIV NULL 0x0 )
+( UNIV SEQ
+    ( UNIV BOOL 0x1
+        0xff
+    )
+    ( UNIV INT 0x1
+        0x01
+    )
+    ( UNIV BITS 0x2
+        0x0680
+    )
+    ( UNIV OCTS 0x1
+        0x03
+    )
+)
+( UNIV SEQ
+    ( UNIV BOOL 0x1
+        0xff
+    )
+    ( UNIV INT 0x1
+        0x01
+    )
+)
+( UNIV SEQ )
+( UNIV SEQ
+    ( UNIV BOOL 0x1
+        0x00
+    )
+    ( UNIV INT 0x1
+        0x04
+    )
+)
+( UNIV SEQ )
+( UNIV SEQ
+    ( UNIV BOOL 0x1
+        0xff
+    )
+    ( UNIV INT 0x1
+        0x01
+    )
+    ( UNIV BITS 0x2
+        0x0680
+    )
+    ( UNIV OCTS 0x1
+        0x03
+    )
+    ( UNIV SEQ
+        ( UNIV BOOL 0x1
+            0x00
+        )
+        ( UNIV INT 0x1
+            0x04
+        )
+        ( UNIV BITS 0x2
+            0x05a0
+        )
+        ( UNIV OCTS 0x1
+            0x06
+        )
+    )
+)
+( UNIV SEQ
+    ( UNIV INT 0x1
+        0x01
+    )
+    ( UNIV INT 0x1
+        0x02
+    )
+    ( UNIV INT 0x1
+        0x03
+    )
+    ( UNIV INT 0x1
+        0x04
+    )
+    ( UNIV INT 0x1
+        0x05
+    )
+)
+( UNIV SEQ )
+( UNIV SET
+    ( CONT 0x0
+        ( UNIV INT 0x1
+            0x0a
+        )
+    )
+    ( CONT 0x1
+        ( UNIV INT 0x1
+            0x64
+        )
+    )
+    ( CONT 0x2
+        ( UNIV INT 0x2
+            0x03e8
+        )
+    )
+)
+( UNIV SET
+    ( CONT 0x0 0x1
+        0x0a
+    )
+    ( CONT 0x1 0x1
+        0x64
+    )
+    ( CONT 0x2 0x2
+        0x03e8
+    )
+)
+( UNIV SET
+    ( CONT 0x1f 0x1
+        0x0a
+    )
+    ( CONT 0x20 0x1
+        0x64
+    )
+    ( CONT 0x21 0x2
+        0x03e8
+    )
+)
+( UNIV SET
+    ( CONT 0x80 0x1
+        0x0a
+    )
+    ( CONT 0x81 0x1
+        0x64
+    )
+    ( CONT 0x82 0x2
+        0x03e8
+    )
+)
+( UNIV SET
+    ( UNIV INT 0x1
+        0x01
+    )
+    ( UNIV INT 0x1
+        0x02
+    )
+    ( UNIV INT 0x1
+        0x03
+    )
+    ( UNIV INT 0x1
+        0x04
+    )
+    ( UNIV INT 0x1
+        0x05
+    )
+    ( UNIV INT 0x1
+        0x06
+    )
+    ( UNIV INT 0x1
+        0x07
+    )
+    ( UNIV INT 0x1
+        0x08
+    )
+    ( UNIV INT 0x1
+        0x09
+    )
+    ( UNIV INT 0x1
+        0x0a
+    )
+    ( UNIV INT 0x1
+        0x0b
+    )
+    ( UNIV INT 0x1
+        0x0c
+    )
+    ( UNIV INT 0x1
+        0x0d
+    )
+    ( UNIV INT 0x1
+        0x0e
+    )
+    ( UNIV INT 0x1
+        0x0f
+    )
+    ( UNIV INT 0x1
+        0x10
+    )
+    ( UNIV INT 0x1
+        0x11
+    )
+    ( UNIV INT 0x1
+        0x12
+    )
+    ( UNIV INT 0x1
+        0x13
+    )
+    ( UNIV INT 0x1
+        0x14
+    )
+    ( UNIV INT 0x1
+        0x15
+    )
+    ( UNIV INT 0x1
+        0x16
+    )
+    ( UNIV INT 0x1
+        0x17
+    )
+    ( UNIV INT 0x1
+        0x18
+    )
+    ( UNIV INT 0x1
+        0x19
+    )
+    ( UNIV INT 0x1
+        0x1a
+    )
+    ( UNIV INT 0x1
+        0x1b
+    )
+    ( UNIV INT 0x1
+        0x1c
+    )
+    ( UNIV INT 0x1
+        0x1d
+    )
+    ( UNIV INT 0x1
+        0x1e
+    )
+    ( UNIV INT 0x1
+        0x1f
+    )
+    ( UNIV INT 0x1
+        0x20
+    )
+    ( UNIV INT 0x1
+        0x21
+    )
+    ( UNIV INT 0x1
+        0x22
+    )
+    ( UNIV INT 0x1
+        0x23
+    )
+    ( UNIV INT 0x1
+        0x24
+    )
+    ( UNIV INT 0x1
+        0x25
+    )
+    ( UNIV INT 0x1
+        0x26
+    )
+    ( UNIV INT 0x1
+        0x27
+    )
+    ( UNIV INT 0x1
+        0x28
+    )
+    ( UNIV INT 0x1
+        0x29
+    )
+    ( UNIV INT 0x1
+        0x2a
+    )
+    ( UNIV INT 0x1
+        0x2b
+    )
+    ( UNIV INT 0x1
+        0x2c
+    )
+    ( UNIV INT 0x1
+        0x2d
+    )
+    ( UNIV INT 0x1
+        0x2e
+    )
+    ( UNIV INT 0x1
+        0x2f
+    )
+    ( UNIV INT 0x1
+        0x30
+    )
+    ( UNIV INT 0x1
+        0x31
+    )
+    ( UNIV INT 0x1
+        0x32
+    )
+)
+( UNIV NUMS 0xb
+    "0123"
+    "4567"
+    "89 "
+)
+( UNIV PRTS 0x4a
+    "ABCD"
+    "EFGH"
+    "IJKL"
+    "MNOP"
+    "QRST"
+    "UVWX"
+    "YZab"
+    "cdef"
+    "ghij"
+    "klmn"
+    "opqr"
+    "stuv"
+    "wxyz"
+    "0123"
+    "4567"
+    "89 '"
+    "()+,"
+    "-./:"
+    "=?"
+)
+( UNIV OID 0x5
+    0x28c27b04
+    0x01
+)
+( UNIV OID 0x5
+    0x28c27b04
+    0x02
+)
diff --git a/src/isode/psap/time2prim.c b/src/isode/psap/time2prim.c
new file mode 100644 (file)
index 0000000..0657b5d
--- /dev/null
@@ -0,0 +1,65 @@
+/* time2prim.c - time string to presentation element */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:15  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:10  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:27  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+/* \f */
+
+PE     time2prim (u, generalized, class, id)
+register UTC   u;
+int    generalized;
+PElementClass  class;
+PElementID     id;
+{
+    register int    len;
+    register char  *bp;
+    register PE            pe;
+
+    if ((bp = time2str (u, generalized)) == NULLCP)
+       return NULLPE;
+
+    if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+       return NULLPE;
+
+    if ((pe -> pe_prim = PEDalloc (len = strlen (bp))) == NULLPED) {
+       pe_free (pe);
+       return NULLPE;
+    }
+    PEDcpy (bp, pe -> pe_prim, pe -> pe_len = len);
+
+    return pe;
+}
diff --git a/src/isode/psap/time2str.c b/src/isode/psap/time2str.c
new file mode 100644 (file)
index 0000000..5717af2
--- /dev/null
@@ -0,0 +1,97 @@
+/* time2str.c - time string to string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:17  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:11  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:27  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+
+
+#define        YEAR(y)         ((y) >= 100 ? (y) : (y) + 1900)
+#define        UNYEAR(y)       ((y) < 1900 || (y) > 1999 ? (y) : (y) - 1900)
+
+/* \f */
+
+char   *time2str (u, generalized)
+register UTC   u;
+int    generalized;
+{
+    register int    hours,
+                    mins,
+                    zone;
+    register char  *bp;
+    static char buffer[BUFSIZ];
+
+    if (u == NULLUTC)
+       return NULLCP;
+
+    bp = buffer;
+
+    if (generalized)
+       (void) sprintf (bp, "%04d", YEAR (u -> ut_year));
+    else
+       (void) sprintf (bp, "%02d", UNYEAR (u -> ut_year));
+    bp += strlen (bp);
+
+    (void) sprintf (bp, "%02d%02d%02d%02d", u -> ut_mon, u -> ut_mday,
+               u -> ut_hour, u -> ut_min);
+    bp += strlen (bp);
+
+    if (u -> ut_flags & UT_SEC
+           || (generalized && (u -> ut_flags & UT_USEC))) {
+       (void) sprintf (bp, "%02d", u -> ut_sec);
+       bp += strlen (bp);
+    }
+    if (generalized && (u -> ut_flags & UT_USEC)) {
+       (void) sprintf (bp, ".%06d", u -> ut_usec);
+       bp += strlen (bp);
+    }
+
+    if (u -> ut_flags & UT_ZONE)
+       if ((zone = u -> ut_zone) == 0)
+           *bp++ = 'Z';
+       else {
+           if (zone < 0)
+               mins = (-zone) % 60, hours = (-zone) / 60;
+           else
+               mins = zone % 60, hours = zone / 60;
+           (void) sprintf (bp, "%c%02d%02d", zone < 0 ? '-' : '+',
+                   hours, mins);
+           bp += strlen (bp);
+       }
+
+    *bp = NULL;
+
+    return buffer;
+}
diff --git a/src/isode/psap/tm2ut.c b/src/isode/psap/tm2ut.c
new file mode 100644 (file)
index 0000000..05b6139
--- /dev/null
@@ -0,0 +1,63 @@
+/* tm2ut.c - tm to time string */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:19  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:13  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:28  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#ifdef OSX
+#include <sys/time.h>
+#endif
+
+
+#define        YEAR(y)         ((y) >= 100 ? (y) : (y) + 1900)
+
+/* \f */
+
+void   tm2ut (tm, ut)
+register struct tm *tm;
+register UTC   ut;
+{
+    bzero ((char *) ut, sizeof *ut);
+
+    ut -> ut_year = YEAR (tm -> tm_year);
+    ut -> ut_mon = tm -> tm_mon + 1;
+    ut -> ut_mday = tm -> tm_mday;
+    ut -> ut_hour = tm -> tm_hour;
+    ut -> ut_min = tm -> tm_min;
+    ut -> ut_sec = tm -> tm_sec;
+    ut -> ut_zone = 0;
+    
+    ut -> ut_flags = UT_ZONE | UT_SEC;
+}
diff --git a/src/isode/psap/ts2ps.c b/src/isode/psap/ts2ps.c
new file mode 100644 (file)
index 0000000..70a7b39
--- /dev/null
@@ -0,0 +1,106 @@
+/* ts2ps.c - TSDU-backed abstraction for PStreams
+               (really just a refinement of datagram-backed PStreams) */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:22  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:14  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:28  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tsap.h"
+#include "tailor.h"
+
+/* \f */
+
+int    ts_read (fd, q)
+int    fd;
+struct qbuf **q;
+{
+    register struct qbuf *qb;
+    struct TSAPdata  txs;
+    register struct TSAPdata *tx = &txs;
+    struct TSAPdisconnect  tds;
+    register struct TSAPdisconnect *td = &tds;
+
+    if (TReadRequest (fd, tx, NOTOK, td) == NOTOK) {
+       if (td -> td_reason == DR_NORMAL) {
+           *q = NULL;
+           return OK;
+       }
+
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+             (td -> td_cc > 0 ? "ts_read: [%s] %*.*s" : "ts_read: [%s]",
+              TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
+               td -> td_data));
+
+       return NOTOK;
+    }
+
+    qb = &tx -> tx_qbuf;
+    if (qb -> qb_forw -> qb_forw != qb && qb_pullup (qb) == NOTOK) {
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("ts_read: qb_pullup fails"));
+       TXFREE (tx);
+
+       return NOTOK;
+    }
+
+    remque (qb = tx -> tx_qbuf.qb_forw);
+    qb -> qb_forw = qb -> qb_back = qb;
+
+    *q = qb;
+
+    TXFREE (tx);
+
+    return qb -> qb_len;
+}
+
+
+int    ts_write (fd, qb)
+int    fd;
+register struct qbuf *qb;
+{
+    struct TSAPdisconnect  tds;
+    register struct TSAPdisconnect *td = &tds;
+    
+    if (TDataRequest (fd, qb -> qb_data, qb -> qb_len, td) == NOTOK) {
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+             (td -> td_cc > 0 ? "ts_write: [%s] %*.*s" : "ts_write: [%s]",
+              TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
+               td -> td_data));
+
+       return NOTOK;
+    }
+
+    return qb -> qb_len;
+}
diff --git a/src/isode/psap/ut2tm.c b/src/isode/psap/ut2tm.c
new file mode 100644 (file)
index 0000000..3bbbc81
--- /dev/null
@@ -0,0 +1,130 @@
+/* ut2tm.c - time string to tm */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:24  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:16  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:29  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#ifdef OSX
+#include <sys/time.h>
+#endif
+
+
+#define        UNYEAR(y)       ((y) < 1900 || (y) > 1999 ? (y) : (y) - 1900)
+
+extern int dmsize[];
+static  int makewkday ();
+
+/* \f */
+
+struct tm *ut2tm (ut)
+register UTC   ut;
+{
+    static struct tm   tms;
+    register struct tm *tm = &tms;
+
+    bzero ((char *) tm, sizeof *tm);
+
+    tm -> tm_sec = ut -> ut_sec;
+    tm -> tm_min = ut -> ut_min;
+    tm -> tm_hour = ut -> ut_hour;
+    tm -> tm_mday = ut -> ut_mday;
+    tm -> tm_mon = ut -> ut_mon - 1;
+    tm -> tm_year = UNYEAR (ut -> ut_year);
+    tm -> tm_wday = makewkday (ut);
+    tm -> tm_yday = tm -> tm_isdst = 0;
+
+    tm -> tm_hour -= ut -> ut_zone / 60, tm -> tm_min -= ut -> ut_zone % 60;
+    if (tm -> tm_min < 0)
+       tm -> tm_hour--, tm -> tm_min += 60;
+    else
+       if (tm -> tm_min > 59)
+           tm -> tm_hour++, tm -> tm_min -= 60;
+
+/* this ignores odditites in February... */
+    if (tm -> tm_hour < 0) {
+       tm -> tm_mday++, tm -> tm_hour += 24;
+       if (tm -> tm_mday > dmsize[tm -> tm_mon]) {
+           tm -> tm_mon++, tm -> tm_mday = 1;
+           if (tm -> tm_mon > 11)
+               tm -> tm_year++, tm -> tm_mon = 0;
+       }
+       
+    }
+    else
+       if (tm -> tm_hour > 23) {
+           tm -> tm_mday--, tm -> tm_hour -= 24;
+           if (tm -> tm_mday < 1) {
+               tm -> tm_mday = dmsize[--tm -> tm_mon];
+               if (tm -> tm_mon < 0)
+                   tm -> tm_year--, tm -> tm_mon = 11;
+           }
+       }
+
+    return tm;
+}
+
+/* \f */
+
+#define        dysize(y)       \
+       (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
+
+#define        YEAR(y)         ((y) >= 100 ? (y) : (y) + 1900)
+
+
+static  int makewkday (ut)
+UTC     ut;
+{
+    int     d,
+           mon,
+           year;
+
+    mon = ut -> ut_mon;
+    year = YEAR (ut -> ut_year);
+    d = 4 + year + (year + 3) / 4;
+
+    if (year > 1800) {
+       d -= (year - 1701) / 100;
+       d += (year - 1601) / 400;
+    }
+    if (year > 1752)
+       d += 3;
+    if (dysize (year) == 366 && mon > 3)
+       d++;
+    while (--mon >= 0)
+       d += dmsize[mon - 1];
+    d += ut -> ut_mday - 1;
+
+    return (d % 7);
+}
diff --git a/src/isode/psap/uvec2ps.c b/src/isode/psap/uvec2ps.c
new file mode 100644 (file)
index 0000000..01667fb
--- /dev/null
@@ -0,0 +1,206 @@
+/* uvec2ps.c - uvec-backed abstraction for PStreams */
+
+#ifndef        lint
+static char *rcsid = "$Header$";
+#endif
+
+/* 
+ * $Header$
+ *
+ *
+ * $Log$
+ * Revision 1.1  1994/06/10 03:35:26  eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1  1994/06/01 00:39:17  eichin
+ * add psap too
+ *
+ * Revision 8.0  91/07/17  12:47:29  isode
+ * Release 7.0
+ * 
+ * 
+ */
+
+/*
+ *                               NOTICE
+ *
+ *    Acquisition, use, and distribution of this module and related
+ *    materials 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 "psap.h"
+#include "tailor.h"
+
+
+#define        NPSUV           10      /* really should be NSPUV - 2 */
+
+#define        PSDU_MAGIC      64      /* threshold for scattering */
+
+/* \f */
+
+static int  uvec_write (ps, data, n, in_line)
+PS     ps;
+PElementData data;
+PElementLen n;
+int    in_line;
+{
+    register struct udvec *uv;
+    
+    if (in_line && n < PSDU_MAGIC)
+       in_line = 0;
+    if (in_line && ps -> ps_cur -> uv_base)
+       ps -> ps_cur++;
+    if (ps -> ps_cur >= ps -> ps_end) {
+       SLOG (psap_log, LLOG_DEBUG, NULLCP,
+             ("%d elements not enough for pe2uvec", ps -> ps_elems));
+       ps -> ps_elems += NPSUV;
+       if ((uv = (struct udvec *) realloc ((char *) ps -> ps_head,
+                                           (unsigned) (ps -> ps_elems
+                                                       * sizeof *uv)))
+               == NULL)
+           return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+
+       ps -> ps_cur = uv + (ps -> ps_cur - ps -> ps_head);
+       ps -> ps_end = (ps -> ps_head = uv) + ps -> ps_elems - 1;
+    }
+
+    uv = ps -> ps_cur;
+    if (in_line) {
+       if (ps -> ps_cc == 0) {
+           SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("first write in pe2uvec is inline"));
+
+           return ps_seterr (ps, PS_ERR_EOF, NOTOK);
+       }
+
+       uv -> uv_base = (char *) data, uv -> uv_len = n;
+       uv -> uv_inline = 1;
+       (++ps -> ps_cur) -> uv_base = NULL;
+    }
+    else {
+       if (n > ps -> ps_slop) {
+           SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+                 ("insufficient slop in pe2uvec, at least %d octets short",
+                  n - ps -> ps_slop));
+
+           return ps_seterr (ps, PS_ERR_EOF, NOTOK);
+       }
+
+       if (uv -> uv_base == NULL) {
+           uv -> uv_base = ps -> ps_extra, uv -> uv_len = 0;
+           uv -> uv_inline = ps -> ps_cc > 0 ? 1 : 0;
+       }
+
+       uv -> uv_len += n;
+       bcopy ((char *) data, ps -> ps_extra, n);
+       ps -> ps_extra += n, ps -> ps_slop -= n;
+    }
+    ps -> ps_cc += n;
+
+    return n;
+}
+
+
+static int  uvec_flush (ps)
+register PS ps;
+{
+    if (ps -> ps_cur) {
+       if (ps -> ps_cur -> uv_base)
+           ps -> ps_cur++;
+       ps -> ps_cur -> uv_base = NULL;
+    }
+
+    if (ps -> ps_slop != 0)
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("%d octets of slop remaining on pe2uvec flush", ps -> ps_slop));
+
+    return OK;
+}
+
+
+static int  uvec_close (ps)
+register PS ps;
+{
+    register struct udvec *uv;
+
+    if (ps -> ps_head) {
+       for (uv = ps -> ps_head; uv -> uv_base; uv++)
+           if (!uv -> uv_inline)
+               free (uv -> uv_base);
+       free ((char *) ps -> ps_head);
+    }    
+
+    if (ps -> ps_extra && ps -> ps_cc == 0)
+       free (ps -> ps_extra);
+
+    return OK;
+}
+
+/* \f */
+
+int    uvec_open (ps)
+register PS ps;
+{
+    ps -> ps_writeP = uvec_write;
+    ps -> ps_flushP = uvec_flush;
+    ps -> ps_closeP = uvec_close;
+
+    return OK;
+}
+
+
+int    uvec_setup (ps, len)
+register PS   ps;
+int    len;
+{
+    register struct udvec *uv;
+
+    ps -> ps_elems = NPSUV;
+    if ((uv = (struct udvec *) calloc ((unsigned) ps -> ps_elems, sizeof *uv))
+           == NULL)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+    ps -> ps_end = (ps -> ps_head = ps -> ps_cur = uv) + ps -> ps_elems - 1;
+
+    ps -> ps_cc = 0;
+
+    if ((ps -> ps_slop = len) <= 0)
+       SLOG (psap_log, LLOG_EXCEPTIONS, NULLCP,
+             ("bad initial slop in pe2uvec, %d octets", len));
+
+    if ((ps -> ps_extra = malloc ((unsigned) len)) == NULL)
+       return ps_seterr (ps, PS_ERR_NMEM, NOTOK);
+
+    return OK;
+}
+
+/* \f */
+
+int    ps_get_plen (pe)
+register PE    pe;
+{
+    register PElementLen len;
+    register PE            p;
+    
+    len = 0;
+    switch (pe -> pe_form) {
+       case PE_FORM_PRIM:
+       case PE_FORM_ICONS:
+           if (pe -> pe_len >= PSDU_MAGIC)
+               len = pe -> pe_len;
+           break;
+
+       case PE_FORM_CONS:
+           for (p = pe -> pe_cons; p; p = p -> pe_next)
+               len += ps_get_plen (p);
+           break;
+       }
+
+    return len;
+}
diff --git a/src/isode/psap/version.major b/src/isode/psap/version.major
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/src/isode/psap/version.minor b/src/isode/psap/version.minor
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/src/isode/support/Makefile.in b/src/isode/support/Makefile.in
new file mode 100644 (file)
index 0000000..09a7015
--- /dev/null
@@ -0,0 +1,119 @@
+###############################################################################
+#   Instructions to Make, for compilation of ISODE support processes
+###############################################################################
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+BUILDTOP = ../../
+TOPDIR = $(BUILDTOP)
+
+OPTIONS        =       -I. -I$(HDIR) $(PEPYPATH) $(KRBOPT)
+CFLAGS  =       $(OPTIONS) $(LOPTIONS) 
+
+HDIR   =       $(TOPDIR)isode/h/
+UTILDIR        =       $(TOPDIR)isode/util/
+INCDIRM        =       $(HDIR)
+INCDIR =       $(INCDIRM)/
+PEPSYDIRM=     $(INCDIR)pepsy
+PEPSYDIR=      $(PEPSYDIRM)/
+LIBISODE=      $(TOPDIR)libisode.a
+LIBDSAP        =       $(TOPDIR)libdsap.a
+
+LIBES  =       libcompat.a
+LLIBS   =
+HFILES =       $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+LN     =       ln
+
+###############################################################################
+#
+#                               NOTICE
+#
+#    Acquisition, use, and distribution of this module and related
+#    materials 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   =       $(TOPDIR)libpepsy.a $(TOPDIR)libpsap.a $(TOPDIR)libcompat.a
+
+
+LLIBS   =       $(TOPDIR)llib-lpsap $(TOPDIR)llib-lcompat
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:           libisode
+inst-all:      inst-libisode
+install:       inst-all clean
+
+inst-:;
+man-:;
+l-:;
+
+
+################################################################
+# libisode
+################################################################
+
+inst-libisode: $(LIBDIR)libisode.a
+
+libisode:      libisode.a libisode-$(SHAREDLIB)
+
+libisode.a:    isodevrsn.o
+               -rm -f $@ $(TOPDIR)libisode.a
+               -rm -rf tmp
+               -mkdir tmp
+               ln isodevrsn.o tmp || cp isodevrsn.o tmp 
+               for i in $(LIBES); do (cd tmp; ar x ../$$i; \
+                   ../$(UTILDIR)make-lib.sh -quick $(SYSTEM) ../$@ *.o; \
+                   rm -f *); done
+               $(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+               -rm -rf tmp
+               -@rm -f $(TOPDIR)libisode.a
+               -@$(LN) $@ $(TOPDIR)lib/libisode.a || cp $@ $(TOPDIR)lib/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 > $@
+
+
+################################################################
+# clean
+################################################################
+
+clean:;                rm -f *.o *.a *.so.* x* z* _* core isodevrsn.c llib-lisode \
+                   libisode-shared
+
+true:;
+
diff --git a/src/isode/support/aliases.local b/src/isode/support/aliases.local
new file mode 100644 (file)
index 0000000..ad7bf93
--- /dev/null
@@ -0,0 +1,43 @@
+###############################################################################
+#
+# isoaliases - ISODE alias file
+#
+#      Mappings between user-friendly strings and distinguished names
+#
+#
+# $Header$
+#
+#
+# $Log$
+# Revision 1.1  1994/06/10 03:35:41  eichin
+# autoconfed isode for kerberos work
+#
+# Revision 1.1  1994/05/31 20:42:55  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+# Revision 8.0  91/07/17  12:20:17  isode
+# Release 7.0
+# 
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <alias>  <name>
+#
+#      Each token is separated by LWSP, though double-quotes may be
+#      used to prevent separation
+#
+#      Maybe in the future we'll support a macro facility!
+#
+###############################################################################
+
+###############################################################################
+# locally defined aliases
+#      (this section is empty unless you're running an OSI Directory...)
+###############################################################################
+
+
diff --git a/src/isode/support/configure.in b/src/isode/support/configure.in
new file mode 100644 (file)
index 0000000..cdff2db
--- /dev/null
@@ -0,0 +1,2 @@
+AC_INIT(configure.in)
+AC_OUTPUT(Makefile)
diff --git a/src/isode/support/entities.local b/src/isode/support/entities.local
new file mode 100644 (file)
index 0000000..3eaf0ff
--- /dev/null
@@ -0,0 +1,30 @@
+###############################################################################
+#
+# $Header$
+#
+#
+# $Log$
+# Revision 1.1  1994/06/10 03:35:45  eichin
+# autoconfed isode for kerberos work
+#
+# Revision 1.1  1994/05/31 20:42:58  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+# Revision 8.0  91/07/17  12:20:26  isode
+# Release 7.0
+# 
+# 
+###############################################################################
+
+
+# templates for local services: 1.17.4.1
+#      local additions go here...
+
+
+#      local additions end here (do not remove this line)
+
+
+# examples of specific services: 1.17.4.2
+#      this section is empty
+
+
diff --git a/src/isode/support/macros.local b/src/isode/support/macros.local
new file mode 100644 (file)
index 0000000..2f5e891
--- /dev/null
@@ -0,0 +1,25 @@
+###############################################################################
+#
+# $Header$
+#
+#
+# $Log$
+# Revision 1.1  1994/06/10 03:35:47  eichin
+# autoconfed isode for kerberos work
+#
+# Revision 1.1  1994/05/31 20:43:18  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+# Revision 8.0  91/07/17  12:20:28  isode
+# Release 7.0
+# 
+# 
+###############################################################################
+
+
+###############################################################################
+# locally defined macros
+#      (this section is usually empty...)
+###############################################################################
+
+
diff --git a/src/isode/support/objects.local b/src/isode/support/objects.local
new file mode 100644 (file)
index 0000000..025c944
--- /dev/null
@@ -0,0 +1,42 @@
+###############################################################################
+#
+# isobjects - ISODE Objects Database
+#
+#      Mappings between object descriptors and object identifiers
+#
+#
+# $Header$
+#
+#
+# $Log$
+# Revision 1.1  1994/06/10 03:35:49  eichin
+# autoconfed isode for kerberos work
+#
+# Revision 1.1  1994/05/31 20:43:24  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+# Revision 8.0  91/07/17  12:20:30  isode
+# Release 7.0
+# 
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <object descriptor> <object id>
+#
+#      Each token is separated by LWSP, though double-quotes may be
+#      used to prevent separation
+#
+###############################################################################
+
+
+###############################################################################
+# locally defined objects
+#      (this section is usually empty...)
+###############################################################################
+
+
diff --git a/src/isode/support/services.local b/src/isode/support/services.local
new file mode 100644 (file)
index 0000000..cb5ad3f
--- /dev/null
@@ -0,0 +1,45 @@
+###############################################################################
+#
+# isoservices - ISODE Services Database
+#
+#      Mappings between services, selectors, and programs
+#
+#
+# $Header$
+#
+#
+# $Log$
+# Revision 1.1  1994/06/10 03:35:51  eichin
+# autoconfed isode for kerberos work
+#
+# Revision 1.1  1994/05/31 20:43:27  eichin
+# reduced-isode release from /mit/isode/isode-subset/src
+#
+# Revision 8.0  91/07/17  12:20:32  isode
+# Release 7.0
+# 
+# 
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+#      <provider>/<entity> <selector> <arg0> <arg1> ... <argn>
+#
+#      Each token is separated by LWSP, though double-quotes may be
+#      used to prevent separation
+#
+###############################################################################
+
+
+###############################################################################
+# locally defined services
+#      (this section is usually empty...)
+###############################################################################
+
+
+
+# local additions end here (do not remove this line)
+
diff --git a/src/isode/support/version.major b/src/isode/support/version.major
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/src/isode/support/version.minor b/src/isode/support/version.minor
new file mode 100644 (file)
index 0000000..573541a
--- /dev/null
@@ -0,0 +1 @@
+0
diff --git a/src/isode/util/config_for b/src/isode/util/config_for
new file mode 100644 (file)
index 0000000..8eb4b64
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+#
+#
+echo "Configuring for $1..."
+
+if [ ! -f config/$1.make -o ! -f config/$1.h ]; then
+       echo "ISODE configuration for $1 is not available!"
+       exit 1
+fi
+
+rm -f h/config.h config/CONFIG.make
+ln -s $1.make config/CONFIG.make
+ln -s ../config/$1.h h/config.h
diff --git a/src/isode/util/extract.sh b/src/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/src/isode/util/inst-lint.sh b/src/isode/util/inst-lint.sh
new file mode 100644 (file)
index 0000000..b762b8e
--- /dev/null
@@ -0,0 +1,96 @@
+: 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
+               ;;
+
+       -sys5r4)
+               O=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
+               ;;
+
+       -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
+               ;;
+
+       -linux) M=LINUX
+               ;;
+
+       -*)     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
+                           ;;
+
+                   LINUX)  echo "No lint on linux; use gcc -Wall"
+                           ;;
+
+                   *)      echo "inst-lint: mode botch" 1>&2
+                           exit 1
+                           ;;
+               esac
+               ;;
+    esac
+done
+
+exit 0
diff --git a/src/isode/util/make-lib.sh b/src/isode/util/make-lib.sh
new file mode 100644 (file)
index 0000000..cc96e64
--- /dev/null
@@ -0,0 +1,168 @@
+: run this script through /bin/sh
+
+M=BSD42 L= O= S= Q= SHD= MAJ= MIN= LD=ld
+
+while [ $# -gt 0 ]
+do
+    A="$1"
+    case $A in
+       -bsd42|-mips)
+               M=BSD42
+               ;;
+
+       -linux) M=LINUX
+               ;;
+
+       -shared)SHD=T
+               ;;
+
+       -sys5)  M=SYS5
+               ;;
+
+       -sys5r4) 
+               M=SYS54
+               ;;
+
+       -aix)   M=AIX
+               ;;
+
+       -ros)   M=ROS
+               ;;
+
+       -ranlib)
+               case $M in
+                   BSD42|ROS|LINUX)
+                           echo ranlib "$L"
+                           case "$L" in
+                               /*)     (cd /usr/tmp; ranlib "$L")
+                                       ;;
+
+                               *)      ranlib "$L"
+                                       ;;
+                           esac
+                           ;;
+
+                   SYS5|AIX|old|SYS54)
+                           ;;
+
+                   *)      echo "make-lib: mode botch" 1>&2
+                           exit 1
+                           ;;
+               esac
+               exit 0
+               ;;
+
+       -quick) Q=T
+               ;;
+
+       -major) MAJ="$2"
+               shift
+               ;;
+       -minor) MIN="$2"
+               shift
+               ;;
+
+       -ld)    LD="$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|LINUX)
+           if [ "x$SHD" = xT ]; then
+               if [ "$M" = ROS ]; then
+                   echo "Can't build shared libraries for ROS" 1>&2
+                   exit 1
+               fi
+               if [ "$M" = Linux ]; then
+                   echo "Can't build shared libraries for Linux (yet)" 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
+           ;;
+
+    SYS54)  if [ "x$SHD" = xT ]; then
+                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
+                echo $LD -o "$LSO" -G *.o
+                $LD -o "$LSO" -G *.o
+                )
+                rm -rf tmp-shared
+           else
+               echo ar q"$S" "$L" $O
+               ar q"$S" "$L" $O
+           fi
+            ;;
+
+
+    AIX)    if [ "x$SHD" = xT ]; then
+               
+               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/src/isode/util/version.sh b/src/isode/util/version.sh
new file mode 100644 (file)
index 0000000..b04487e
--- /dev/null
@@ -0,0 +1,46 @@
+: 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
+
+VERSION=`cat version.local`
+VERSION=`expr $VERSION + 1`
+echo $VERSION > version.local
+
+echo "char *${1}version = \"${1}${2} `cat version.major`.`cat version.minor` #$VERSION ($LOCAL) of `date`\";"
+
+rm -f version.c