--- /dev/null
+-- ASN.1 UNIVERSAL defined types
+
+-- $Header: /f/osi/pepsy/RCS/UNIV.py,v 7.2 91/02/22 09:48:40 mrose Interim $
+--
+--
+-- $Log: UNIV.py,v $
+-- Revision 7.2 91/02/22 09:48:40 mrose
+-- Interim 6.8
+--
+-- Revision 7.1 90/11/04 19:18:08 mrose
+-- update
+--
+-- Revision 7.0 90/07/01 19:54:12 mrose
+-- *** empty log message ***
+--
+-- Revision 7.0 89/11/23 22:11:36 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+UNIV DEFINITIONS ::=
+
+%{
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/pepsy/RCS/UNIV.py,v 7.2 91/02/22 09:48:40 mrose Interim $";
+#endif
+%}
+
+BEGIN
+
+
+ -- ISO 646-1983
+IA5String ::=
+ [UNIVERSAL 22]
+ IMPLICIT OCTET STRING
+
+NumericString ::=
+ [UNIVERSAL 18]
+ IMPLICIT IA5String
+
+PrintableString ::=
+ [UNIVERSAL 19]
+ IMPLICIT IA5String
+
+
+ -- ISO 6937/2-1983
+T61String ::=
+ [UNIVERSAL 20]
+ IMPLICIT OCTET STRING
+
+TeletexString ::=
+ T61String
+
+ -- ISO 6937/2-1983
+VideotexString ::=
+ [UNIVERSAL 21]
+ IMPLICIT OCTET STRING
+
+
+ -- ISO 2014, 3307, 4031
+ -- date, time, zone
+GeneralizedTime ::=
+ [UNIVERSAL 24]
+ IMPLICIT VisibleString
+
+GeneralisedTime ::=
+ GeneralizedTime
+
+
+UTCTime ::=
+ [UNIVERSAL 23]
+ IMPLICIT VisibleString
+
+UniversalTime ::=
+ UTCTime
+
+ -- ISO 2375
+GraphicString ::=
+ [UNIVERSAL 25]
+ IMPLICIT OCTET STRING
+
+VisibleString ::=
+ [UNIVERSAL 26]
+ IMPLICIT OCTET STRING
+
+ISO646String ::=
+ VisibleString
+
+GeneralString ::=
+ [UNIVERSAL 27]
+ IMPLICIT OCTET STRING
+
+CharacterString ::=
+ [UNIVERSAL 28]
+ IMPLICIT OCTET STRING
+
+
+ -- ISO 8824
+EXTERNAL ::=
+ [UNIVERSAL 8]
+ IMPLICIT SEQUENCE {
+ direct-reference
+ OBJECT IDENTIFIER
+ OPTIONAL,
+
+ indirect-reference
+ INTEGER
+ --* OPTIONAL *-- DEFAULT 0,
+
+ data-value-descriptor
+ ObjectDescriptor
+ OPTIONAL,
+
+ encoding
+ CHOICE {
+ single-ASN1-type[0]
+ ANY,
+
+ octet-aligned[1]
+ IMPLICIT OCTET STRING,
+
+ arbitrary[2]
+ IMPLICIT BIT STRING
+ }
+ }
+
+
+ -- ISO 8824
+ObjectDescriptor ::=
+ [UNIVERSAL 7]
+ IMPLICIT GraphicString
+
+END
+
+%{
+
+#ifndef PEPSY_VERSION
+
+PEPYPARM NullParm = (PEPYPARM) 0;
+
+#endif
+
+%}
--- /dev/null
+/* dfns.c */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/pepsy/RCS/dfns.c,v 7.3 91/02/22 09:48:46 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/pepsy/RCS/dfns.c,v 7.3 91/02/22 09:48:46 mrose Interim $
+ *
+ *
+ * $Log: dfns.c,v $
+ * Revision 7.3 91/02/22 09:48:46 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/12/23 18:42:03 mrose
+ * update
+ *
+ * Revision 7.1 90/11/04 19:18:19 mrose
+ * update
+ *
+ * Revision 7.0 90/07/01 19:54:14 mrose
+ * *** empty log message ***
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include "general.h"
+#include "mine.h"
+#include "pepsydefs.h"
+#include "pass2.h"
+
+id_entry *id_table[TABLESIZE];
+
+#define my_error(mesg) (fprintf(stderr, "%s\n",mesg),exit(1))
+
+extern char *notidtoid(), *my_new_str(), *my_strcat();
+extern char *
+proc_name(), *mymodule;
+
+/*
+ * Lookup the hash table (id_table) for the string t and insert it at
+ * the start of the appropriate chain if it is not already there.
+ * The argument flag indicates whether t is being defined (1) or used
+ * (0).
+ */
+char *
+proc_name(t, flag)
+char *t;
+int flag;
+{
+ int i;
+ static int curr = 0;
+ id_entry *ptr;
+
+ i = hash_val(t);
+ for (ptr = id_table[i]; ptr != NULL && strcmp(t, ptr->h_value); ptr = ptr->next);
+
+ if (ptr == NULL) {
+ if ((ptr = (id_entry *) malloc(sizeof(id_entry))) == NULL)
+ my_error("proc_name: Out of memory");
+ ptr->h_value = t;
+ ptr->r_value = my_strcat(notidtoid(t), notidtoid(mymodule));
+ ptr->count = 1;
+ if (flag) {
+ ptr->def_bit = flag;
+ ptr->def_value = curr++;
+ }
+ ptr->next = id_table[i];
+ id_table[i] = ptr;
+ } else if (!ptr->def_bit)
+ ptr->def_bit = flag;
+
+ return ptr->r_value;
+}
+
+/*
+ * output a sequence of #define statements (one for each value stored
+ * in the hash table) to the file specified by fp
+ */
+out_final_defs(fp)
+FILE *fp;
+{
+ int j;
+ id_entry *ptr;
+
+ for (j = 0; j < TABLESIZE; j++)
+ for (ptr = id_table[j]; ptr != NULL; ptr = ptr->next) {
+ if (ptr->def_bit)
+ (void) fprintf(fp, "#define %s%s\t%d\n", PREFIX, ptr->r_value, ptr->def_value);
+ else
+ ferrs(0, "the identifier %s is used but not defined\n", ptr->h_value);
+ if (ptr->count > 1) /* not used */
+ (void) printf("The id %s has a count of %d\n", ptr->r_value, ptr->count);
+ }
+}
+
+/*
+ * return a copy of the string s with '-' replaced by '_'
+ */
+char *
+notidtoid(s)
+char *s;
+{
+
+ char *t, *r;
+
+ t = my_new_str(s);
+ for (r = t; *r != '\0'; r++)
+ if (*r == '-')
+ *r = '_';
+ return t;
+}
+
+/*
+ * return a copy of the string s
+ */
+char *
+my_new_str(s)
+char *s;
+{
+
+ char *t;
+
+ if ((t = (char *) malloc(strlen(s) + 1)) == NULL)
+ my_error("my_new_str: Out of memory");
+
+ strcpy(t, s);
+ return t;
+}
+
+/*
+ * return the concatenation of the strings s1 and s2
+ */
+char *
+my_strcat(s1, s2)
+char *s1, *s2;
+{
+ char *s3, *s, *t;
+
+ if (s1 == NULL || *s1 == '\0')
+ return my_new_str(s2);
+
+ if ((s3 = (char *) malloc(strlen(s1) + strlen(s2) + 1)) == NULL)
+ my_error("my_strcat: Out of memory");
+
+ for (s = s1, t = s3; *s != '\0'; s++, t++)
+ *t = *s;
+ strcpy(t, s2);
+ return s3;
+}
+
+/*
+ * a simple hash function
+ */
+hash_val(s)
+char *s;
+{
+ int i, sum;
+ char *t;
+
+ sum = 0;
+ for (i = 1, t = s; *t != '\0'; i++, t++)
+ sum = sum + *t * i;
+ return (sum % TABLESIZE);
+}
+
+/*
+ * initialize the table id_table
+ */
+init()
+{
+ int i;
+
+ for (i = 0; i <= TABLESIZE; i++)
+ id_table[i] = NULL;
+}
+#define BUFSIZE 128
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+static char *buf = NULL;
+static int len = 0;
+
+/*
+ * Return in a static buffer the two strings concatenated
+ */
+char *
+concat(s1, s2)
+char *s1, *s2;
+{
+ int tot;
+
+ tot = strlen(s1) + strlen(s2) + 1;
+
+ if (tot > len) {
+ len = MAX(BUFSIZE, tot);
+ if (buf == NULL) {
+ if ((buf = malloc(len)) == NULL)
+ ferr(1, "concat:malloc failed\n");
+ } else if ((buf = realloc(buf, len)) == NULL)
+ ferr(1, "concat:realloc failed\n");
+ }
+ strcpy(buf, s1);
+ strcat(buf, s2);
+
+ return (buf);
+}
+
+/*
+ * Generate a free call given the name of the parameter, the module
+ * name, and the name of the type
+ */
+char *
+gfree(module, id, parm)
+char *module; /* name of module we are in (usually
+ * mymodule) */
+char *id; /* name of type we want to free */
+char *parm; /* name of the pointer to the data */
+{
+ char *p1 = notidtoid(module);
+ char *p2 = notidtoid(id);
+
+ if (buf == NULL) {
+ if ((buf = malloc(BUFSIZE)) == NULL)
+ ferr(1, "gfree:malloc failed\n");
+ len = BUFSIZ;
+ }
+ (void) sprintf(buf, "(void) fre_obj((char *) %s, %s%s%s.md_dtab[%s%s%s], &%s%s%s, 1)",
+ parm,
+ PREFIX, p1, MODTYP_SUFFIX,
+ PREFIX, p2, p1,
+ PREFIX, p1, MODTYP_SUFFIX);
+ free(p1);
+ free(p2);
+
+ return (buf);
+}
--- /dev/null
+diff -rc ../gawk-2.11.orig/Makefile ./Makefile
+*** ../gawk-2.11.orig/Makefile Mon Nov 13 13:51:42 1989
+--- ./Makefile Fri Aug 17 15:50:18 1990
+***************
+*** 103,114 ****
+ # need to customize this file below this point.
+ #
+
+! FLAGS= $(MISSING) $(DEBUG)
+ CFLAGS= $(FLAGS) $(DEBUGGER) $(PROFILE) $(OPTIMIZE) $(WARN)
+
+ # object files
+ AWKOBJS = main.o eval.o builtin.o msg.o debug.o io.o field.o array.o node.o \
+! version.o missing.o
+
+ ALLOBJS = $(AWKOBJS) awk.tab.o
+
+--- 103,117 ----
+ # need to customize this file below this point.
+ #
+
+! FLAGS= $(MISSING) $(DEBUG) -DSNMP
+ CFLAGS= $(FLAGS) $(DEBUGGER) $(PROFILE) $(OPTIMIZE) $(WARN)
++ SNMP-C = snmp.c
++ SNMP-O = snmp.o
++ SNMP-LIB= -lisnmp -lisode
+
+ # object files
+ AWKOBJS = main.o eval.o builtin.o msg.o debug.o io.o field.o array.o node.o \
+! version.o missing.o $(SNMP-O)
+
+ ALLOBJS = $(AWKOBJS) awk.tab.o
+
+***************
+*** 118,124 ****
+
+ # source and documentation files
+ SRC = main.c eval.c builtin.c msg.c \
+! debug.c io.c field.c array.c node.c missing.c
+
+ ALLSRC= $(SRC) awk.tab.c
+
+--- 121,127 ----
+
+ # source and documentation files
+ SRC = main.c eval.c builtin.c msg.c \
+! debug.c io.c field.c array.c node.c missing.c $(SNMP-C)
+
+ ALLSRC= $(SRC) awk.tab.c
+
+***************
+*** 154,160 ****
+
+ # rules to build gawk
+ gawk: $(ALLOBJS) $(GNUOBJS)
+! $(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) -lm
+
+ $(AWKOBJS): awk.h
+
+--- 157,163 ----
+
+ # rules to build gawk
+ gawk: $(ALLOBJS) $(GNUOBJS)
+! $(CC) -o gawk $(CFLAGS) $(ALLOBJS) $(GNUOBJS) $(SNMP-LIB) -lm
+
+ $(AWKOBJS): awk.h
+
+diff -rc ../gawk-2.11.orig/array.c ./array.c
+*** ../gawk-2.11.orig/array.c Mon Nov 13 13:51:44 1989
+--- ./array.c Fri Aug 17 15:21:52 1990
+***************
+*** 35,41 ****
+--- 35,46 ----
+ #define MAKE_POS(v) (v & ~0x80000000) /* make number positive */
+
+ NODE *
++ #ifndef SNMP
+ concat_exp(tree)
++ #else
++ concat_exp(tree,isnmp)
++ int isnmp;
++ #endif
+ NODE *tree;
+ {
+ NODE *r;
+***************
+*** 51,58 ****
+--- 56,73 ----
+ r = force_string(tree_eval(tree->lnode));
+ if (tree->rnode == NULL)
+ return r;
++ #ifdef SNMP
++ if (isnmp) {
++ subseplen = Ndot_string -> stlen;
++ subsep = Ndot_string -> stptr;
++ }
++ else {
++ #endif
+ subseplen = SUBSEP_node->lnode->stlen;
+ subsep = SUBSEP_node->lnode->stptr;
++ #ifdef SNMP
++ }
++ #endif
+ len = r->stlen + subseplen + 1;
+ emalloc(str, char *, len, "concat_exp");
+ memcpy(str, r->stptr, r->stlen+1);
+***************
+*** 89,94 ****
+--- 104,113 ----
+ int i;
+ NODE *bucket, *next;
+
++ #ifdef SNMP
++ if (symbol -> magic)
++ fatal ("split into SNMP array variable not allowed");
++ #endif
+ if (symbol->var_array == 0)
+ return;
+ for (i = 0; i < ASSOC_HASHSIZE; i++) {
+***************
+*** 132,137 ****
+--- 151,161 ----
+ {
+ register NODE *bucket;
+
++ #ifdef SNMP
++ if (symbol -> magic)
++ fatal ("assoc_find: internal error");
++ #endif
++
+ for (bucket = symbol->var_array[hash1]; bucket; bucket = bucket->ahnext) {
+ if (cmp_nodes(bucket->ahname, subs))
+ continue;
+***************
+*** 151,159 ****
+--- 175,192 ----
+
+ if (symbol->type == Node_param_list)
+ symbol = stack_ptr[symbol->param_cnt];
++ #ifdef SNMP
++ if (symbol -> magic)
++ return *assoc_lookup (symbol, concat_exp (subs, 1))
++ != Nnull_string;
++ #endif
+ if (symbol->var_array == 0)
+ return 0;
++ #ifndef SNMP
+ subs = concat_exp(subs);
++ #else
++ subs = concat_exp(subs,0);
++ #endif
+ hash1 = hash_calc(subs);
+ if (assoc_find(symbol, subs, hash1) == NULL) {
+ free_temp(subs);
+***************
+*** 180,185 ****
+--- 213,224 ----
+
+ hash1 = hash_calc(subs);
+
++ #ifdef SNMP
++ if (symbol -> magic) {
++ snmp_get (symbol, force_string (subs) -> stptr);
++ return &symbol -> var_value;
++ }
++ #endif
+ if (symbol->var_array == 0) { /* this table really should grow
+ * dynamically */
+ emalloc(symbol->var_array, NODE **, (sizeof(NODE *) *
+***************
+*** 210,218 ****
+--- 249,265 ----
+ register NODE *bucket, *last;
+ NODE *subs;
+
++ #ifdef SNMP
++ if (symbol -> magic)
++ fatal ("delete into SNMP array variable not allowed");
++ #endif
+ if (symbol->var_array == 0)
+ return;
++ #ifndef SNMP
+ subs = concat_exp(tree);
++ #else
++ subs = concat_exp(tree,0);
++ #endif
+ hash1 = hash_calc(subs);
+
+ last = NULL;
+***************
+*** 234,244 ****
+--- 281,300 ----
+ }
+
+ struct search *
++ #ifndef SNMP
+ assoc_scan(symbol)
++ #else
++ assoc_scan(symbol,instance)
++ NODE *instance;
++ #endif
+ NODE *symbol;
+ {
+ struct search *lookat;
+
++ #ifdef SNMP
++ if (symbol -> magic)
++ return snmp_assoc_scan (symbol,instance);
++ #endif
+ if (!symbol->var_array)
+ return 0;
+ emalloc(lookat, struct search *, sizeof(struct search), "assoc_scan");
+***************
+*** 245,257 ****
+--- 301,326 ----
+ lookat->numleft = ASSOC_HASHSIZE;
+ lookat->arr_ptr = symbol->var_array;
+ lookat->bucket = symbol->var_array[0];
++ #ifndef SNMP
+ return assoc_next(lookat);
++ #else
++ return assoc_next(symbol, lookat);
++ #endif
+ }
+
+ struct search *
++ #ifndef SNMP
+ assoc_next(lookat)
++ #else
++ assoc_next(symbol, lookat)
++ NODE *symbol;
++ #endif
+ struct search *lookat;
+ {
++ #ifdef SNMP
++ if (symbol -> magic)
++ return snmp_assoc_next (lookat, 0);
++ #endif
+ for (; lookat->numleft; lookat->numleft--) {
+ while (lookat->bucket != 0) {
+ lookat->retval = lookat->bucket->ahname;
+diff -rc ../gawk-2.11.orig/awk.h ./awk.h
+*** ../gawk-2.11.orig/awk.h Mon Nov 13 13:51:46 1989
+--- ./awk.h Fri Aug 17 15:21:53 1990
+***************
+*** 62,68 ****
+ #endif
+
+ #ifdef __STDC__
+! extern void *malloc(unsigned), *realloc(void *, unsigned);
+ extern void free(char *);
+ extern char *getenv(char *);
+
+--- 62,68 ----
+ #endif
+
+ #ifdef __STDC__
+! extern char *malloc(unsigned), *realloc(void *, unsigned);
+ extern void free(char *);
+ extern char *getenv(char *);
+
+***************
+*** 224,229 ****
+--- 224,235 ----
+ Node_K_while, /* lnode is condtional, rnode is stuff to run */
+ Node_K_for, /* lnode is for_struct, rnode is stuff to run */
+ Node_K_arrayfor, /* lnode is for_struct, rnode is stuff to run */
++ #ifdef SNMP
++ /* init: target
++ cond: instance (optional)
++ incr: array
++ */
++ #endif
+ Node_K_break, /* no subs */
+ Node_K_continue, /* no stuff */
+ Node_K_print, /* lnode is exp_list, rnode is redirect */
+***************
+*** 245,250 ****
+--- 251,259 ----
+
+ /* Variables */
+ Node_var, /* rnode is value, lnode is array stuff */
++ #ifdef SNMP
++ /* magic is pointer to (OT) */
++ #endif
+ Node_var_array, /* array is ptr to elements, asize num of
+ * eles */
+ Node_val, /* node is a value - type in flags */
+***************
+*** 298,303 ****
+--- 307,315 ----
+ char *name;
+ short number;
+ unsigned char recase;
++ #ifdef SNMP
++ caddr_t cookie;
++ #endif
+ } nodep;
+ struct {
+ AWKNUM fltnum; /* this is here for optimal packing of
+***************
+*** 341,346 ****
+--- 353,361 ----
+ #define lnode sub.nodep.l.lptr
+ #define nextp sub.nodep.l.nextnode
+ #define rnode sub.nodep.r.rptr
++ #ifdef SNMP
++ #define magic sub.nodep.cookie
++ #endif
+ #define source_file sub.nodep.name
+ #define source_line sub.nodep.number
+ #define param_cnt sub.nodep.number
+***************
+*** 533,539 ****
+--- 548,558 ----
+ extern NODE **get_lhs(NODE *, int);
+ extern void do_deref(void );
+ extern struct search *assoc_scan(NODE *);
++ #ifndef SNMP
+ extern struct search *assoc_next(struct search *);
++ #else SNMP
++ extern struct search *assoc_next(NODE *symbol, struct search *lookat);
++ #endif SNMP
+ extern NODE **assoc_lookup(NODE *, NODE *);
+ extern double r_force_number(NODE *);
+ extern NODE *r_force_string(NODE *);
+***************
+*** 608,610 ****
+--- 627,658 ----
+ #endif
+
+ extern char casetable[]; /* for case-independent regexp matching */
++
++
++ #ifdef SNMP
++ extern NODE *AGENT_node,
++ *COMMUNITY_node,
++ *DIAGNOSTIC_node,
++ *ERROR_node,
++ *RETRIES_node,
++ *TIMEOUT_node;
++
++ extern NODE *Ndot_string;
++
++ extern int snmp_enabled;
++ extern char *snmp_file;
++
++
++ #ifdef __STDC__
++ int check_snmp(NODE *r, char *name);
++ int snmp_get(NODE *ptr, char *instname);
++ char *snmp_name(NODE *ptr);
++ struct search *snmp_assoc_scan(NODE *symbol);
++ struct search *snmp_assoc_next(struct search *lookat, int done);
++ #else
++ int check_snmp ();
++ int snmp_get ();
++ char *snmp_name ();
++ struct search *snmp_assoc_scan (), *snmp_assoc_next ();
++ #endif
++ #endif
+diff -rc ../gawk-2.11.orig/builtin.c ./builtin.c
+*** ../gawk-2.11.orig/builtin.c Mon Nov 13 13:51:49 1989
+--- ./builtin.c Fri Aug 17 15:14:58 1990
+***************
+*** 533,538 ****
+--- 533,606 ----
+ fflush(fp);
+ }
+
++ #ifdef SNMP
++ NODE *do_band (tree)
++ NODE *tree;
++ {
++ #ifdef sun386
++ long l;
++ #endif
++ unsigned long d1,
++ d2;
++ NODE *s1,
++ *s2;
++
++ get_two (tree, &s1, &s2);
++
++ #ifdef sun386
++ l = force_number (s1);
++ d1 = (unsigned long) l;
++ #else
++ d1 = (unsigned long) force_number (s1);
++ #endif
++
++ #ifdef sun386
++ l = force_number (s2);
++ d2 = (unsigned long) l;
++ #else
++ d2 = (unsigned long) force_number (s2);
++ #endif
++
++ free_temp (s1);
++ free_temp (s2);
++
++ return tmp_number ((AWKNUM) ((unsigned long) (d1 & d2)));
++ }
++
++ NODE *do_bor (tree)
++ NODE *tree;
++ {
++ #ifdef sun386
++ long l;
++ #endif
++ unsigned long d1,
++ d2;
++ NODE *s1,
++ *s2;
++
++ get_two (tree, &s1, &s2);
++
++ #ifdef sun386
++ l = force_number (s1);
++ d1 = (unsigned long) l;
++ #else
++ d1 = (unsigned long) force_number (s1);
++ #endif
++
++ #ifdef sun386
++ l = force_number (s2);
++ d2 = (unsigned long) l;
++ #else
++ d2 = (unsigned long) force_number (s2);
++ #endif
++
++ free_temp (s1);
++ free_temp (s2);
++
++ return tmp_number ((AWKNUM) ((unsigned long) (d1 | d2)));
++ }
++ #endif
++
+ NODE *
+ do_sqrt(tree)
+ NODE *tree;
+diff -rc ../gawk-2.11.orig/debug.c ./debug.c
+*** ../gawk-2.11.orig/debug.c Mon Nov 13 13:51:51 1989
+--- ./debug.c Fri Aug 17 15:14:59 1990
+***************
+*** 107,114 ****
+--- 107,122 ----
+ {
+ struct search *l;
+
++ #ifndef SNMP
+ printf("(0x%x Array)\n", ptr);
+ for (l = assoc_scan(ptr); l; l = assoc_next(l)) {
++ #else
++ printf("(0x%x Array%s)\n", ptr,
++ ptr -> magic ? " {SNMP}": "");
++ if (ptr -> magic)
++ return;
++ for (l = assoc_scan(ptr); l; l = assoc_next(ptr, l)) {
++ #endif
+ printf("\tindex: ");
+ print_parse_tree(l->retval);
+ printf("\tvalue: ");
+***************
+*** 344,349 ****
+--- 352,361 ----
+ for (buc = variables[n]; buc; buc = buc->hnext) {
+ if (buc->hvalue == ptr) {
+ printf("%.*s", buc->hlength, buc->hname);
++ #ifdef SNMP
++ if (ptr -> magic)
++ printf ("{SNMP}");
++ #endif
+ n = HASHSIZE;
+ break;
+ }
+diff -rc ../gawk-2.11.orig/eval.c ./eval.c
+*** ../gawk-2.11.orig/eval.c Mon Nov 13 13:51:53 1989
+--- ./eval.c Fri Aug 17 15:21:52 1990
+***************
+*** 302,308 ****
+--- 302,314 ----
+ if (t->type == Node_param_list)
+ t = stack_ptr[t->param_cnt];
+ stable_tree = tree;
++ #ifndef SNMP
+ for (l = assoc_scan(t); l; l = assoc_next((struct search *)l)) {
++ #else
++ for (l = assoc_scan (t, tree -> forloop -> cond);
++ l;
++ l = assoc_next (t, l)) {
++ #endif
+ deref = *((NODE **) lhs);
+ do_deref();
+ *lhs = dupnode(l->retval);
+***************
+*** 318,323 ****
+--- 324,333 ----
+ break;
+
+ case TAG_BREAK:
++ #ifdef SNMP
++ if (t -> magic)
++ (void) snmp_assoc_next (l, 1);
++ #endif
+ RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
+ field_num = -1;
+ return 1;
+***************
+*** 916,922 ****
+--- 926,936 ----
+ */
+ if (arg->type == Node_param_list)
+ arg = stack_ptr[arg->param_cnt];
++ #ifndef SNMP
+ if (arg->type == Node_var_array)
++ #else
++ if (arg -> type == Node_var_array && !arg -> magic)
++ #endif
+ *r = *arg;
+ else {
+ n = tree_eval(arg);
+***************
+*** 984,989 ****
+--- 998,1008 ----
+ arg = argp->lnode;
+ n = *sp++;
+ if (arg->type == Node_var && n->type == Node_var_array) {
++ #ifdef SNMP
++ if (arg -> magic)
++ fatal ("array assignment to SNMP scalar variable \"%s\"",
++ snmp_name (arg));
++ #endif
+ arg->var_array = n->var_array;
+ arg->type = Node_var_array;
+ }
+***************
+*** 1035,1040 ****
+--- 1054,1068 ----
+ switch (ptr->type) {
+ case Node_var:
+ case Node_var_array:
++ #ifdef SNMP
++ if (ptr -> magic)
++ if (assign)
++ fatal ("attempt to set SNMP %s variable \"%s\"",
++ ptr -> type == Node_var ? "scalar" : "array",
++ snmp_name (ptr));
++ else
++ snmp_get (ptr, (char *) NULL);
++ #endif
+ if (ptr == NF_node && (int) NF_node->var_value->numbr == -1)
+ (void) get_field(HUGE-1, assign); /* parse record */
+ deref = ptr->var_value;
+***************
+*** 1071,1077 ****
+--- 1099,1113 ----
+ n = ptr->lnode;
+ if (n->type == Node_param_list)
+ n = stack_ptr[n->param_cnt];
++ #ifdef SNMP
++ if (n -> magic && assign)
++ fatal ("attempt to set SNMP array variable \"%s\"",
++ snmp_name (n));
++ aptr = assoc_lookup(n,
++ concat_exp(ptr->rnode, n -> magic ? 1 : 0));
++ #else
+ aptr = assoc_lookup(n, concat_exp(ptr->rnode));
++ #endif
+ deref = *aptr;
+ #ifdef DEBUG
+ if (deref->type != Node_val)
+diff -rc ../gawk-2.11.orig/node.c ./node.c
+*** ../gawk-2.11.orig/node.c Mon Nov 13 13:52:13 1989
+--- ./node.c Fri Aug 17 15:15:01 1990
+***************
+*** 277,282 ****
+--- 277,285 ----
+ #endif
+ it->type = ty;
+ it->flags = MALLOC;
++ #ifdef SNMP
++ it->magic = NULL;
++ #endif
+ #ifdef MEMDEBUG
+ fprintf(stderr, "node: new: %0x\n", it);
+ #endif
+*** ../gawk-2.11.orig/awk.y Mon Nov 13 13:51:48 1989
+--- awk.y Fri Aug 17 16:57:20 1990
+***************
+*** 325,330 ****
+--- 325,335 ----
+ { $$ = node ($3, Node_K_while, $6); }
+ | LEX_DO opt_nls statement LEX_WHILE '(' exp r_paren opt_nls
+ { $$ = node ($6, Node_K_do, $3); }
++ | LEX_FOR '(' NAME LEX_IN NAME comma exp r_paren opt_nls statement
++ {
++ $$ = node ($10, Node_K_arrayfor, make_for_loop(variable($3),
++ $7, variable($5)));
++ }
+ | LEX_FOR '(' NAME LEX_IN NAME r_paren opt_nls statement
+ {
+ $$ = node ($8, Node_K_arrayfor, make_for_loop(variable($3),
+***************
+*** 684,689 ****
+--- 689,697 ----
+ *do_split(), *do_system(), *do_int(), *do_close(),
+ *do_atan2(), *do_sin(), *do_cos(), *do_rand(),
+ *do_srand(), *do_match(), *do_tolower(), *do_toupper(),
++ #ifdef SNMP
++ *do_band (), *do_bor (),
++ #endif
+ *do_sub(), *do_gsub();
+
+ /* Special functions for debugging */
+***************
+*** 697,702 ****
+--- 705,714 ----
+ { "BEGIN", Node_illegal, LEX_BEGIN, 0, 0 },
+ { "END", Node_illegal, LEX_END, 0, 0 },
+ { "atan2", Node_builtin, LEX_BUILTIN, 0, do_atan2 },
++ #ifdef SNMP
++ { "bit_and", Node_builtin, LEX_BUILTIN, 0, do_band },
++ { "bit_or", Node_builtin, LEX_BUILTIN, 0, do_bor },
++ #endif
+ #ifdef DEBUG
+ { "bp", Node_builtin, LEX_BUILTIN, 0, do_bp },
+ #endif
+***************
+*** 1680,1686 ****
+--- 1692,1706 ----
+ register NODE *r;
+
+ if ((r = lookup(variables, name)) == NULL)
++ #ifdef SNMP
++ {
++ #endif
+ r = install(variables, name,
+ node(Nnull_string, Node_var, (NODE *) NULL));
++ #ifdef SNMP
++ if (snmp_enabled && r)
++ snmp_check (r, name);
++ }
++ #endif
+ return r;
+ }
+*** ../gawk-2.11.orig/main.c Mon Nov 13 13:52:08 1989
+--- main.c Fri Aug 17 17:00:30 1990
+***************
+*** 94,101 ****
+--- 94,106 ----
+ */
+ #define EXTENSIONS 8 /* where to clear */
+ #ifdef DEBUG
++ #ifndef SNMP
+ char awk_opts[] = "F:f:v:caeCVdD";
+ #else
++ char awk_opts[] = "F:f:v:caeCVdDsS";
++ extern int debug;
++ #endif
++ #else
+ char awk_opts[] = "F:f:v:caeCV";
+ #endif
+
+***************
+*** 192,198 ****
+--- 197,213 ----
+ debugging++;
+ yydebug = 2;
+ break;
++
++ #ifdef SNMP
++ case 's':
++ debug = 1;
++ break;
++
++ case 'S':
++ debug = 2;
++ break;
+ #endif
++ #endif
+
+ #ifndef STRICT
+ case 'c':
+***************
+*** 483,488 ****
+--- 498,512 ----
+ RSTART_node = spc_var("RSTART", make_number(0.0));
+ SUBSEP_node = spc_var("SUBSEP", make_string("\034", 1));
+ IGNORECASE_node = spc_var("IGNORECASE", make_number(0.0));
++ #ifdef SNMP
++ if (snmp_init ())
++ AGENT_node = spc_var ("AGENT", make_string ("localhost", 9));
++ COMMUNITY_node = spc_var ("COMMUNITY", make_string ("public", 6));
++ DIAGNOSTIC_node = spc_var ("DIAGNOSTIC", Nnull_string);
++ ERROR_node = spc_var ("ERROR", make_number (0.0));
++ RETRIES_node = spc_var ("RETRIES", make_number (3.0));
++ TIMEOUT_node = spc_var ("TIMEOUT", make_number (10.0));
++ #endif
+
+ ENVIRON_node = spc_var("ENVIRON", Nnull_string);
+ for (i = 0; environ[i]; i++) {
--- /dev/null
+[ READ-ME-FIRST - Wed Oct 17 16:21:24 1990 - notes on SNMP+gawk - /mtr ]
+
+
+0. You should already have installed the 4BSD/ISODE SNMP software.
+
+1. Get a copy of GNU Awk 2.11. Extract the gawk-2.11/ hierarchy into
+ this directory, snmp/gawk-2.11/.
+
+2. Apply the patches to the sources by
+
+ % patch -p < GAWK-PATCHES
+
+3. Follow the instructions in the README file to configure gawk.
+
+4. If your $(INCDIR) is not /usr/include, then add
+
+ -I$(INCDIR)
+
+ to the "FLAGS=" definition in the Makefile.
+
+5. Type
+
+ % make
+
+ to generate gawk.
+
+6. As the super-user copy gawk to $(BINDIR) and create the directory
+ /usr/local/lib/awk.
+
+7. At this point you should be able to do a trivial test:
+
+ % gawk -f s-gawk/mib.system
+
+ which will contact your local SNMP agent using the default
+ community and ask for information from the system group. The
+ output looks something like this:
+
+ agent cheetah.ca.psi.com
+ running: 4BSD/ISODE SNMP
+ (1.3.6.1.4.1.4.1.2.1)
+ services: applications, end-to-end
+ location: upstairs machine room
+ contact: Marshall Rose <mrose@psi.com>
+ uptime: 5 days, 17 hours, 24 minutes, 37.69 seconds
+
+8. Now you can install the primarly application supplied, s-netstat:
+
+ # (cd s-gawk; ./make inst-all)
--- /dev/null
+###############################################################################
+# Instructions to Make, for compilation of SNMP-capable gawk processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/snmp/gawk-2.11/s-gawk/RCS/Makefile,v 7.2 91/02/22 09:45:12 mrose Interim $
+#
+# Contributed by NYSERNet Inc. This work was partially supported by the
+# U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+# Center of the U.S. Air Force Systems Command under contract number
+# F30602-88-C-0016.
+#
+#
+# $Log: Makefile,v $
+# Revision 7.2 91/02/22 09:45:12 mrose
+# Interim 6.8
+#
+# Revision 7.1 90/08/29 15:33:39 mrose
+# update
+#
+# Revision 7.0 90/08/29 15:26:02 mrose
+# *** empty log message ***
+#
+###############################################################################
+
+###############################################################################
+#
+# NOTICE
+#
+# Acquisition, use, and distribution of this module and related
+# materials are subject to the restrictions of a license agreement.
+# Consult the Preface in the User's Manual for the full terms of
+# this agreement.
+#
+###############################################################################
+
+AWKDIR = /usr/local/lib/awk/
+
+SHELLS = s-netstat s-traceroute
+AWKS = mib.*
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all:;
+inst-all: inst-scripts manuals
+install: inst-all clean
+lint:;
+
+
+##################################################################
+# scripts
+##################################################################
+
+inst-scripts:; -mkdir /usr/local/lib/awk
+ @for h in $(SHELLS); \
+ do $(MAKE) TARGET=$$h inst-script;done
+ @for h in $(AWKS); \
+ do $(MAKE) BINDIR=$(AWKDIR) TARGET=$$h inst-script;done
+
+inst-script: $(BINDIR)$(TARGET)
+
+$(BINDIR)$(TARGET): $(TARGET)
+ -cp $@ z$(TARGET)
+ cp $(TARGET) $@
+ -@ls -gls $@
+ -@echo ""
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS = s-netstat.1c s-traceroute.1c
+
+manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+ -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:; rm -f z* _*
+
+grind:; iprint Makefile
+ tgrind -lsh s-*.sh
+ iprint mib.*
+ @echo $(MANUALS) | \
+ tr " " "\012" | \
+ sed -e "s%.*%itroff -man &%" | \
+ sh -ve
+
+true:;
--- /dev/null
+: run this script through /bin/sh
+M=/bin/make
+if [ -f /usr/bin/make ]; then
+ M=/usr/bin/make
+fi
+
+exec $M TOPDIR=../../../ -f ../../../config/CONFIG.make -f Makefile ${1+"$@"}
--- /dev/null
+function at_type(f) {
+ if (f in types)
+ return types[f];
+
+ return (f ? f : "unknown");
+}
+
+BEGIN {
+ types[1] = "Other";
+ types[2] = "Invalid";
+ types[3] = "Dynamic";
+ types[4] = "Static";
+
+ printf "ARP table:\n";
+ didone = 0;
+ for (i in ipNetToMediaIfIndex) {
+ didone = 1;
+
+ printf "%-15s at %s flags %s on interface #%d (%s)\n",
+ ipNetToMediaNetAddress, ipNetToMediaPhysAddress,
+ at_type(ipNetToMediaType), ipNetToMediaIfIndex,
+ ifDescr[ipNetToMediaIfIndex];
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "ipNetToMediaTable: %s\n", DIAGNOSTIC;
+ if (!didone) {
+ for (i in atIfIndex) {
+ didone = 1;
+
+ printf "%-15s at %s on interface #%d (%s)\n",
+ atNetAddress, atPhysAddress, atIfIndex,
+ ifDescr[atIfIndex];
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "atTable: %s\n", DIAGNOSTIC;
+ }
+ if (!didone && !DIAGNOSTIC)
+ printf "\tempty.\n";
+
+ if (!oflag)
+ exit(0);
+
+ printf "\nNet to media:\n";
+ didone = 0;
+ for (i in clnpNetToMediaIfIndex) {
+ didone = 1;
+
+ printf "NS+%s at %s type %s age %d hold %d on interface #%d (%s)\n",
+ clnpNetToMediaNetAddress, clnpNetToMediaPhysAddress,
+ clnp_type(clnpNetToMediaType), clnpNetToMediaAge,
+ clnpNetToMediaHoldTime,
+ clnpNetToMediaIfIndex, ifDescr[clnpNetToMediaIfIndex];
+ }
+ if (!didone)
+ if (DIAGNOSTIC)
+ printf "clnpNetToMediaTable: %s\n", DIAGNOSTIC;
+ else
+ printf "\tempty.\n";
+ }
--- /dev/null
+function socket(t,a,p, s1,s2) {
+ s1 = a == "0.0.0.0" ? "*" : a;
+ if (p == 0)
+ s2 = "*";
+ else
+ if ((p, t) in services)
+ s2 = services[p, t];
+ else
+ s2 = p;
+
+ return (s1 "." s2);
+}
+
+function tt_type(f) {
+ if (f in types)
+ return types[f];
+
+ return (f ? f : "unknown");
+}
+
+BEGIN {
+ types[1] = "CLOSED";
+ types[2] = "LISTEN";
+ types[3] = "SYN_SENT";
+ types[4] = "SYN_RCVD";
+ types[5] = "ESTABLISHED";
+ types[6] = "FIN_WAIT_1";
+ types[7] = "FIN_WAIT_2";
+ types[8] = "CLOSE_WAIT";
+ types[9] = "LAST_ACK";
+ types[10] = "CLOSING";
+ types[11] = "TIME_WAIT";
+
+ services[7, "udp"] = "echo";
+ services[9, "udp"] = "discard";
+ services[11, "tcp"] = "systat";
+ services[13, "tcp"] = "daytime";
+ services[15, "tcp"] = "netstat";
+ services[20, "tcp"] = "ftp-data";
+ services[21, "tcp"] = "ftp";
+ services[23, "tcp"] = "telnet";
+ services[25, "tcp"] = "smtp";
+ services[37, "tcp"] = "time";
+ services[37, "udp"] = "time";
+ services[42, "udp"] = "name";
+ services[43, "tcp"] = "whois";
+ services[53, "udp"] = "domain";
+ services[53, "tcp"] = "domain";
+ services[101, "tcp"] = "hostnames";
+ services[102, "tcp"] = "tsap";
+ services[109, "tcp"] = "pop";
+ services[111, "udp"] = "sunrpc";
+ services[111, "tcp"] = "sunrpc";
+ services[69, "udp"] = "tftp";
+ services[77, "tcp"] = "rje";
+ services[79, "tcp"] = "finger";
+ services[87, "tcp"] = "link";
+ services[95, "tcp"] = "supdup";
+ services[105, "tcp"] = "csnet-ns";
+ services[117, "tcp"] = "uucp-path";
+ services[119, "tcp"] = "untp";
+ services[123, "tcp"] = "ntp";
+ services[161, "udp"] = "snmp";
+ services[162, "udp"] = "snmp-trap";
+ services[199, "tcp"] = "smux";
+ services[1524, "tcp"] = "ingreslock";
+ services[512, "tcp"] = "exec";
+ services[513, "tcp"] = "login";
+ services[514, "tcp"] = "shell";
+ services[515, "tcp"] = "printer";
+ services[530, "tcp"] = "courier";
+ services[512, "udp"] = "biff";
+ services[513, "udp"] = "who";
+ services[514, "udp"] = "syslog";
+ services[517, "udp"] = "talk";
+ services[520, "udp"] = "route";
+ services[550, "udp"] = "new-rwho";
+ services[560, "udp"] = "rmonitor";
+ services[561, "udp"] = "monitor";
+
+ printf "Active connections%s\n", aflag ? " (including servers)" : "";
+ printf "%-5s %-6s %-6s %-20s %-20s %s\n",
+ "Proto",
+ "Recv-Q",
+ "Send-Q",
+ "Local Address",
+ "Foreign Address",
+ "(state)";
+
+ hasunix = unixNetstat == 1;
+
+ didone = 0;
+ for (i in tcpConnState) {
+ didone = 1;
+
+ if (!aflag && tcpConnLocalAddress == "0.0.0.0")
+ continue;
+
+ printf "%-5s %6s %6s %-20s %-20s %s\n",
+ "tcp",
+ hasunix ? unixTcpConnRecvQ[i] : "",
+ hasunix ? unixTcpConnSendQ[i] : "",
+ socket("tcp",tcpConnLocalAddress,tcpConnLocalPort),
+ socket("tcp",tcpConnRemAddress,tcpConnRemPort),
+ tt_type(tcpConnState);
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "tcpConnTable: %s\n", DIAGNOSTIC;
+
+ didone = 0;
+ for (i in udpLocalAddress) {
+ didone = 1;
+
+ if (!aflag && udpLocalAddress == "0.0.0.0")
+ continue;
+
+ printf "%-5s %6s %6s %-20s %-20s %s\n",
+ "udp",
+ hasunix ? unixUdpRecvQ[i] : "",
+ hasunix ? unixUdpSendQ[i] : "",
+ socket("udp",udpLocalAddress,udpLocalPort),
+ hasunix ? socket("udp",unixUdpRemAddress[i],unixUdpRemPort[i]) : "",
+ "";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "udpTable: %s\n", DIAGNOSTIC;
+ }
--- /dev/null
+function neigh_state(f) {
+ if (f in states)
+ return states[f];
+
+ return (f ? f : "unknown");
+}
+
+function neigh_mode(f) {
+ if (f in modes)
+ return modes[f];
+
+ return (f ? f : "unknown");
+}
+
+function neigh_trigger(f) {
+ if (f in triggers)
+ return triggers[f];
+
+ return (f ? f : "unknown");
+}
+
+function do_stats() {
+ didone = 0;
+ for (i in egpInMsgs) {
+ didone = 1;
+
+ printf "%9s packets received\n", egpInMsgs;
+ printf "%9s packets received in error\n", egpInErrors;
+ printf "\n";
+ printf "%9s packets generated\n", egpOutMsgs;
+ printf "%9s packets discarded due to error\n", egpOutErrors;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "egp statistics: %s\n", DIAGNOSTIC;
+}
+
+BEGIN {
+ if (sflag) {
+ do_stats();
+ exit(0);
+ }
+
+ states[1] = "Idle";
+ states[2] = "Acquisition";
+ states[3] = "Down";
+ states[4] = "Up";
+ states[5] = "Cease";
+
+ modes[1] = "Active";
+ modes[2] = "Passive";
+
+ triggers[1] = "Start";
+ triggers[2] = "Stop";
+
+ mibii = egpAs ? 1 : 0;
+ if (mibii)
+ printf "autonomous system: %d\n", egpAs;
+ printf "%-15s %-11s",
+ "Neighbor",
+ "State";
+ if (mibii)
+ printf " %-5s %-7s %-6s %-6s %-6s\n",
+ "AS",
+ "Mode",
+ "Trigger",
+ "Hello",
+ "Poll";
+ else
+ printf "\n";
+
+ didone = 0;
+ for (i in egpNeighAddr) {
+ didone = 1;
+
+ printf "%-15s %-11s",
+ egpNeighAddr,
+ neigh_state(egpNeighState);
+ if (mibii)
+ printf " %-5d %-7s %-6s %-6d %-6d\n",
+ egpNeighAs,
+ neigh_mode(egpNeighMode),
+ neigh_trigger(egpNeighEventTrigger),
+ egpNeighIntervalHello,
+ egpNeighIntervalPoll;
+ else
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "egpNeigh group: %s\n", DIAGNOSTIC;
+}
--- /dev/null
+function paths(i,j, s) {
+ if (i >= j) return i;
+
+ s = "";
+ if (j > 8) {
+ if (i >= 8) { s = s "I"; i -= 8; } else s = (s " ");
+ }
+ if (i >= 4) { s = s "L"; i -= 4; } else s = (s " ");
+ if (i >= 2) { s = s "S"; i -= 2; } else s = (s " ");
+ if (i >= 1) { s = s "P"; i -= 1; } else s = (s " ");
+
+ return s;
+}
+
+function config(i, s) {
+ if (i >= 4) return i;
+
+ s = "";
+ if (i >= 2) { s = s "W"; i -= 2; } else s = (s " ");
+ if (i >= 1) { s = s "H"; i -= 1; } else s = (s " ");
+
+ return s;
+}
+
+function connection(i, f,s) {
+ if (i >= 65536) return i;
+
+ f = "%s%s"; s = "";
+ if (i >= 32768) { s = sprintf(f, s, "M-M"); f = "%s,%s"; i -= 32768; }
+ if (i >= 16384) { s = sprintf(f, s, "M-S"); f = "%s,%s"; i -= 16384; }
+ if (i >= 8192) { s = sprintf(f, s, "M-B"); f = "%s,%s"; i -= 8192; }
+ if (i >= 4096) { s = sprintf(f, s, "M-A"); f = "%s,%s"; i -= 4096; }
+ if (i >= 2048) { s = sprintf(f, s, "S-M"); f = "%s,%s"; i -= 2048; }
+ if (i >= 1024) { s = sprintf(f, s, "S-S"); f = "%s,%s"; i -= 1024; }
+ if (i >= 512) { s = sprintf(f, s, "S-B"); f = "%s,%s"; i -= 512; }
+ if (i >= 256) { s = sprintf(f, s, "S-A"); f = "%s,%s"; i -= 256; }
+ if (i >= 128) { s = sprintf(f, s, "B-M"); f = "%s,%s"; i -= 128; }
+ if (i >= 64) { s = sprintf(f, s, "B-S"); f = "%s,%s"; i -= 64; }
+ if (i >= 32) { s = sprintf(f, s, "B-B"); f = "%s,%s"; i -= 32; }
+ if (i >= 16) { s = sprintf(f, s, "B-A"); f = "%s,%s"; i -= 16; }
+ if (i >= 8) { s = sprintf(f, s, "A-M"); f = "%s,%s"; i -= 8; }
+ if (i >= 4) { s = sprintf(f, s, "A-S"); f = "%s,%s"; i -= 4; }
+ if (i >= 2) { s = sprintf(f, s, "A-B"); f = "%s,%s"; i -= 2; }
+ if (i >= 1) { s = sprintf(f, s, "A-A"); f = "%s,%s"; i -= 1; }
+
+ return s;
+}
+
+function binary_type(f) {
+ if (f in binary)
+ return binary[f];
+
+ return (f ? f : "unknown");
+}
+
+function ecm_type(f) {
+ if (f in ecm)
+ return ecm[f];
+
+ return (f ? f : "unknown");
+}
+
+function cf_type(f) {
+ if (f in cf)
+ return cf[f];
+
+ return (f ? f : "unknown");
+}
+
+function hold_type(f) {
+ if (f in hold)
+ return hold[f];
+
+ return (f ? f : "unknown");
+}
+
+function capability(i,j, f,s) {
+ if (i >= j) return i;
+
+ f = "%s%s"; s = "";
+ if (j > 8) {
+ if (i >= 1024) { s = sprintf(f, s, "P2"); f = "%s,%s"; i -= 1024; }
+ if (i >= 512) { s = sprintf(f, s, "P1"); f = "%s,%s"; i -= 512; }
+ if (i >= 256) { s = sprintf(f, s, "P0"); f = "%s,%s"; i -= 256; }
+ if (i >= 128) { s = sprintf(f, s, "<7>"); f = "%s,%s"; i -= 128; }
+ if (i >= 64) { s = sprintf(f, s, "<6>"); f = "%s,%s"; i -= 64; }
+ if (i >= 32) { s = sprintf(f, s, "<5>"); f = "%s,%s"; i -= 32; }
+ if (i >= 16) { s = sprintf(f, s, "<4>"); f = "%s,%s"; i -= 16; }
+ if (i >= 8) { s = sprintf(f, s, "<3>"); f = "%s,%s"; i -= 8; }
+ }
+ if (i >= 4) { s = sprintf(f, s, "T2"); f = "%s,%s"; i -= 4; }
+ if (i >= 2) { s = sprintf(f, s, "T1"); f = "%s,%s"; i -= 2; }
+ if (i >= 1) { s = sprintf(f, s, "T0"); f = "%s,%s"; i -= 1; }
+
+ return s;
+}
+
+function cp_type(f) {
+ if (f in cp)
+ return cp[f];
+
+ return (f ? f : "unknown");
+}
+
+function dup_type(f) {
+ if (f in dup)
+ return dup[f];
+
+ return (f ? f : "unknown");
+}
+
+function port_type(f,s) {
+ if (f in port)
+ return port[f];
+
+ return (f ? f : s ? "U" : "unknown");
+}
+
+function rm_type(f) {
+ if (f in rm)
+ return rm[f];
+
+ return (f ? f : "unknown");
+}
+
+function class_type(f) {
+ if (f in class)
+ return class[f];
+
+ return (f ? f : "unknown");
+}
+
+function order_type(f) {
+ if (f in order)
+ return order[f];
+
+ return (f ? f : "unknown");
+}
+
+function status_type(f) {
+ if (f in status)
+ return status[f];
+
+ return (f ? f : "unknown");
+}
+
+function pcps(i, s) {
+ if (i >= 8) return i;
+
+ s = "";
+ if (i >= 4) { s = s "P"; i -= 4; } else s = (s " ");
+ if (i >= 2) { s = s "L"; i -= 2; } else s = (s " ");
+ if (i >= 1) { s = s "C"; i -= 1; } else s = (s " ");
+
+ return s;
+}
+
+function ce_type(f) {
+ if (f in ce)
+ return ce[f];
+
+ return (f ? f : "unknown");
+}
+
+function pcs_type(f) {
+ if (f in pcs)
+ return pcs[f];
+
+ return (f ? f : "unknown");
+}
+
+function pcm_type(f) {
+ if (f in pcm)
+ return pcm[f];
+
+ return (f ? f : "unknown");
+}
+
+function wh_type(f) {
+ if (f in wh)
+ return wh[f];
+
+ return (f ? f : "unknown");
+}
+
+function aclass_type(f) {
+ if (f in aclass)
+ return aclass[f];
+
+ return (f ? f : "unknown");
+}
+
+
+BEGIN {
+ binary[1] = "true";
+ binary[2] = "false";
+
+ ecm[1] = "out";
+ ecm[2] = "in";
+ ecm[3] = "trace";
+ ecm[4] = "leave";
+ ecm[5] = "path_test";
+ ecm[6] = "insert";
+ ecm[7] = "check";
+ ecm[8] = "deinsert";
+
+ cf[1] = "isolated";
+ cf[2] = "wrap_s";
+ cf[3] = "wrap_a";
+ cf[4] = "wrap_b";
+ cf[5] = "wrap_ab";
+ cf[6] = "thru";
+
+ hold[1] = "not-implemented";
+ hold[2] = "not-holding";
+ hold[3] = "holding-prm";
+ hold[4] = "holding-sec";
+
+ printf "%-10s%-17s|%-8s|%-11s|%-3s|%-7s|%s\n",
+ "smtNumber=",
+ smtNumber,
+ "Versions",
+ " MACs",
+ "", "Config",
+ "";
+ printf "%-3s %-23s|%-8s|%-11s|%-3s|%-3s %-3s|%s\n",
+ "Idx",
+ "Station ID",
+ "Op Hi Lo",
+ "Tot Non Mas",
+ "Pth",
+ "Cap",
+ "Pol",
+ "Connection Policy";
+
+ didone = 0;
+ for (i in snmpFddiSMTIndex) {
+ if (didone)
+ printf "\n";
+ else
+ didone = 1;
+
+ printf "%-3s %-23s %2d %2d %2d %3d %3d %3d ",
+ snmpFddiSMTIndex,
+ snmpFddiSMTStationId,
+ snmpFddiSMTOpVersionId,
+ snmpFddiSMTHiVersionId,
+ snmpFddiSMTLoVersionId,
+ snmpFddiSMTMACCt,
+ snmpFddiSMTNonMasterCt,
+ snmpFddiSMTMasterCt;
+ printf "%-3s %-3s %-3s %s\n",
+ paths(snmpFddiSMTPathsAvailable,8),
+ config(snmpFddiSMTConfigCapabilities),
+ config(snmpFddiSMTConfigPolicy),
+ connection(snmpFddiSMTConnectionPolicy);
+
+ printf "\tnotify=%5d secs reporting=%-7s remote-disconnect=%s\n",
+ snmpFddiSMTTNotify,
+ binary_type(snmpFddiSMTStatusReporting),
+ binary_type(snmpFddiSMTRemoteDisconnectFlag);
+
+ printf "\tstates: ecm=%-9s cf=%-8s hold=%s\n",
+ ecm_type(snmpFddiSMTECMState),
+ cf_type(snmpFddiSMTCFState),
+ hold_type(snmpFddiSMTHoldState);
+
+ printf "\tstamps: msg=%-23s trans=%s\n",
+ snmpFddiSMTMsgTimeStamp,
+ snmpFddiSMTTransitionTimeStamp;
+
+ if (snmpFddiSMTSetInformation || snmpFddiSMTLastSetStationId)
+ printf "\tset: SMT=%-23s info=%s\n",
+ snmpFddiSMTLastSetStationId,
+ snmpFddiSMTSetInformation;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "smtTable: %s\n", DIAGNOSTIC;
+ printf "\n";
+
+ cp[1] = "unknown";
+ cp[2] = "primary";
+ cp[4] = "secondary";
+ cp[8] = "local";
+ cp[16] = "isolated";
+
+ dup[1] = "none";
+ dup[2] = "pass";
+ dup[3] = "fail";
+
+ port[0] = "A";
+ port[1] = "B";
+ port[2] = "S";
+ port[3] = "M";
+
+ rm[1] = "isolated";
+ rm[2] = "non_op";
+ rm[3] = "ring_op";
+ rm[4] = "detect";
+ rm[5] = "non_op_dup";
+ rm[6] = "ring_op_dup";
+ rm[7] = "directed";
+ rm[8] = "trace";
+
+ printf "%-10s%-15s|%-26s|%-19s|%s\n",
+ "macNumber=",
+ macNumber,
+ " Frames",
+ " Paths",
+ "";
+ printf "%-3s %-3s %-17s|%-8s %-8s %-8s|%-5s %-8s %-4s|%s\n",
+ "Idx",
+ "SMT",
+ "Address",
+ " Total",
+ "Errors",
+ " Lost",
+ "Avail",
+ " Current",
+ "Req",
+ "Cap";
+ didone = 0;
+ for (i in snmpFddiMACSMTIndex) {
+ if (didone)
+ printf "\n";
+ else
+ didone = 1;
+
+ printf "%-3s %-3s %-17s %8d %8d %8d %-5s %-8s %-4s %s\n",
+ snmpFddiMACIndex,
+ snmpFddiMACSMTIndex,
+ snmpFddiMACSMTAddress,
+ snmpFddiMACFrameCt,
+ snmpFddiMACErrorCt,
+ snmpFddiMACLostCt,
+ paths(snmpFddiMACPathsAvailable,8),
+ cp_type(snmpFddiMACCurrentPath),
+ paths(snmpFddiMACPathsRequested,16),
+ capability(snmpFddiMACFrameStatusCapabilities,2048);
+
+ printf "\tgreatest-lb: t_max=%-11s tvx=%s\n",
+ snmpFddiMACTMaxGreatestLowerBound,
+ snmpFddiMACTVXGreatestLowerBound;
+
+ printf "\tupstream: cur=%-17s old=%s\n",
+ snmpFddiMACUpstreamNbr,
+ snmpFddiMACOldUpstreamNbr;
+
+ printf "\tdownstream: port=%-7s rm-state=%s\n",
+ port_type(snmpFddiMACDownstreamPORTType,0),
+ rm_type(snmpFddiMACRMTState);
+
+ printf "\ttimers: req=%-11s neg=%-11s tvx=%s\n",
+ snmpFddiMACTReq,
+ snmpFddiMACTNeg,
+ snmpFddiMACTvxValue;
+
+ printf "\t max=%-11s min=%s\n",
+ snmpFddiMACTMax,
+ snmpFddiMACTMin;
+
+ printf "\tdup-addrs: test=%-7s flag=%s\n",
+ dup_type(snmpFddiMACDupAddrTest),
+ binary_type(snmpFddiMACDaFlag);
+
+ printf "\tmisc: cf-status=%-21s frame-cond=%s\n",
+ capability(snmpFddiMACCurrentFrameStatus,8),
+ binary_type(snmpFddiMACFrameMACCondition);
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "macTable: %s\n", DIAGNOSTIC;
+ printf "\n";
+
+ class[1] = "local";
+ class[2] = "non-local";
+
+ printf "PATH Classes:\n";
+ printf "%-3s %-9s %s\n",
+ "Idx",
+ "Index",
+ "Trace-MaxExpiration";
+ didone = 0;
+ for (i in snmpFddiPATHClassSMTIndex) {
+ didone = 1;
+
+ printf "%-3s %-9s %s\n",
+ snmpFddiPATHClassSMTIndex,
+ class_type(snmpFddiPATHClassIndex),
+ snmpFddiPATHClassTraceMaxExpiration;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "pathClassTable: %s\n", DIAGNOSTIC;
+ printf "\n";
+
+ order[1] = "unsup";
+ order[2] = "up";
+ order[3] = "down";
+
+ status[1] = "wrapped";
+ status[2] = "thru";
+
+ printf "PATH Config:\n";
+ printf "%-3s %-3s %-4s %-5s %-10s %-10s %s\n",
+ "Idx",
+ "SMT",
+ "Type",
+ "Order",
+ " SBA",
+ " SBA-OH",
+ "Status";
+ didone = 0;
+ for (i in snmpFddiPATHConfigSMTIndex) {
+ didone = 1;
+
+ printf "%-3s %-3s %-4s %-7s %10d %10d %s\n",
+ snmpFddiPATHConfigIndex,
+ snmpFddiPATHConfigSMTIndex,
+ paths(snmpFddiPATHType,8),
+ order_type(snmpFddiPATHPORTOrder),
+ snmpFddiPATHSba,
+ snmpFddiPATHSbaOverhead,
+ status_type(snmpFddiPATHStatus);
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "pathConfigTable: %s\n", DIAGNOSTIC;
+ printf "\n";
+
+ ce[1] = "isolated";
+ ce[2] = "insert_p";
+ ce[3] = "insert_s";
+ ce[4] = "insert_x";
+ ce[5] = "local";
+
+ pcs[1] = "disabled";
+ pcs[2] = "connecting";
+ pcs[3] = "standby";
+ pcs[4] = "active";
+
+ pcm[ 1] = "off";
+ pcm[ 2] = "break";
+ pcm[ 3] = "trace";
+ pcm[ 4] = "connect";
+ pcm[ 5] = "next";
+ pcm[ 6] = "signal";
+ pcm[ 7] = "join";
+ pcm[ 8] = "verify";
+ pcm[ 9] = "active";
+ pcm[10] = "maint";
+
+ wh[1] = "none";
+ wh[2] = "m-m";
+ wh[3] = "other";
+
+ printf "%-11s%-7s|%-8s|%-7s|%-8s|%-17s|%s\n",
+ "portNumber=",
+ portNumber,
+ "Connect",
+ "Remote",
+ " CE",
+ " Paths",
+ "";
+
+ printf "%-3s %-3s %-4s %-5s|%-8s|%-7s|%-8s|%-5s %-5s %-5s|%s\n",
+ "Idx",
+ "SMT",
+ "Type",
+ "Neigh",
+ "Policies",
+ " MAC",
+ " State",
+ " Req",
+ "Place",
+ "Avail",
+ "Loop Time";
+ didone = 0;
+ for (i in snmpFddiPORTSMTIndex) {
+ didone = 1;
+
+ printf "%-3s %-3s %-4s %-5s %-8s %-7s %-8s %-5s %5d %-5s %10d\n",
+ snmpFddiPORTIndex,
+ snmpFddiPORTSMTIndex,
+ port_type(snmpFddiPORTPCType,1),
+ port_type(snmpFddiPORTPCNeighbor),
+ pcps(snmpFddiPORTConnectionPolicies),
+ binary_type(snmpFddiPORTRemoteMACIndicated),
+ ce_type(snmpFddiPORTCEState),
+ paths(snmpFddiPORTPathsRequested,16),
+ snmpFddiPORTMACPlacement,
+ paths(snmpFddiPORTAvailablePaths,8),
+ snmpFddiPORTMACLoopTime;
+
+ printf "\tstates: connect=%-10s pcm=%-7s withhold=%s\n",
+ pcs_type(snmpFddiPORTConnectState),
+ pcm_type(snmpFddiPORTPCMState),
+ wh_type(snmpFddiPORTPCWithhold);
+
+ printf "\tlem: count=%-10d reject-count=%-10d\n",
+ snmpFddiPORTLemCt,
+ snmpFddiPORTLemRejectCt;
+
+ printf "\tbase-ler: count=%-10d reject-count=%-10d estimate=%02d\n",
+ snmpFddiPORTBaseLerRejectCt,
+ snmpFddiPORTBaseLerCt,
+ snmpFddiPORTBaseLerEstimate;
+
+ printf "\t stamp=%s\n",
+ snmpFddiPORTBaseLerTimeStamp;
+
+ printf "\tler: cutoff=%02d alarm=%02d estimate=%02d\n",
+ snmpFddiPORTLerCutoff,
+ snmpFddiPORTLerAlarm,
+ snmpFddiPORTLerEstimate;
+
+ printf "\t condition=%s\n",
+ binary_type(snmpFddiPORTLerCondition);
+
+ printf "\tmisc: bs_flag=%-7s lct-fails=%-10d tb_max=%s\n",
+ binary_type(snmpFddiPORTBSFlag),
+ snmpFddiPORTLCTFailCt,
+ snmpFddiPORTTBMax;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "portTable: %s\n", DIAGNOSTIC;
+ printf "\n";
+
+ aclass[1] = "single";
+ aclass[2] = "dual";
+ aclass[3] = "concen";
+
+ printf "%-12s%-23s| Insertion\n",
+ "Attachments=",
+ attachmentNumber;
+ printf "%-3s %-3s %-7s %-7s %-11s|%-7s %s\n",
+ "Idx",
+ "SMT",
+ "Class",
+ "Bypass",
+ "Expire",
+ "Status",
+ "Policy";
+ didone = 0;
+ for (i in snmpFddiATTACHMENTSMTIndex) {
+ didone = 1;
+
+ printf "%-3s %-3s %-7s %-7s %-11s",
+ snmpFddiATTACHMENTIndex,
+ snmpFddiATTACHMENTSMTIndex,
+ aclass_type(snmpFddiATTACHMENTClass),
+ binary_type(snmpFddiATTACHMENTOpticalBypassPresent),
+ snmpFddiATTACHMENTIMaxExpiration;
+ if (snmpFddiATTACHMENTOpticalBypassPresent)
+ printf " %-8s %s",
+ binary_type(snmpFddiATTACHMENTInsertedStatus),
+ binary_type(snmpFddiATTACHMENTInsertPolicy);
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "attachmentTable: %s\n", DIAGNOSTIC;
+ printf "\n";
+ }
--- /dev/null
+BEGIN {
+ printf "%-4s %-4s %-14s %-15s %-7s %-5s %-7s %-5s %-4s %-5s\n",
+ "Name",
+ "Mtu",
+ "Net/Dest",
+ "Address",
+ "Ipkts",
+ "Ierrs",
+ "Opkts",
+ "Oerrs",
+ "Drop",
+ "Queue";
+
+ didone = 0;
+ for (i in ifIndex) {
+ didone = 1;
+
+ dest = "";
+ addr = "";
+ for (j in ipAdEntAddr) {
+ if (ipAdEntIfIndex == ifIndex) {
+ split(addr = ipAdEntAddr, a, ".");
+ split(ipAdEntNetMask, b, ".");
+ dest = bit_and(a[1],b[1]) "." \
+ bit_and(a[2],b[2]) "." \
+ bit_and(a[3],b[3]) "." \
+ bit_and(a[4],b[4]);
+ break;
+ }
+ }
+
+ printf (length(ifDescr) <= 4 ? "%-4s " : "%s\n "),
+ ifDescr;
+ printf "%-4d %-14s %-15s %-7d %-5d %-7d %-5d %-4d %-5d\n",
+ ifMtu,
+ dest,
+ addr,
+ ifInUcastPkts+ifInNUcastPkts,
+ ifInErrors,
+ ifOutUcastPkts+ifOutNUcastPkts,
+ ifOutErrors,
+ ifOutDiscards,
+ ifOutQLen;
+ if (oflag)
+ for (j in clnpAdEntAddr) {
+ if (clnpAdEntIfIndex == ifIndex) {
+ printf "%-4s %-5s %-14s NS+%s\n",
+ "", "", "", clnpAdEntAddr;
+ break;
+ }
+ }
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "ifTable: %s\n", DIAGNOSTIC;
+
+ }
--- /dev/null
+BEGIN {
+ MSIZE = 128; MCLBYTES = 1024;
+ keys[0] = "free";
+ keys[1] = "data";
+ keys[2] = "packet headers";
+ keys[3] = "socket structures";
+ keys[4] = "protocol control blocks";
+ keys[5] = "routing tables";
+ keys[6] = "IMP host tables";
+ keys[7] = "address resolution tables";
+ keys[8] = "socket names";
+ keys[9] = "zombie process status";
+ keys[10] = "socket options";
+ keys[11] = "fragment reassembly headers";
+
+ total = 0; inuse = 0;
+
+ didany = 0;
+ for (i in mbufS) {
+ didany = 1;
+
+ i = mbufS; j = mbufFrees;
+ if (i == 0) { printf "no mbufS!?!\n"; exit(1); }
+ printf "%d/%d mbufs in use:\n", i - j, i;
+ total += i * MSIZE; inuse += (i - j) * MSIZE;
+
+ didone = 0;
+ for (i in mbufType) {
+ didone = 1;
+
+ if (mbufAllocates) {
+ printf "\t%d mbufs allocated to ", mbufAllocates;
+ if (k = keys[mbufType])
+ printf "%s\n", k;
+ else
+ printf "mbuf type %d\n", mbufType;
+ }
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "mbufTable: %s\n", DIAGNOSTIC;
+
+ i = mbufClusters; j = mbufFreeClusters
+ printf "%d/%d mapped pages in use\n", i - j, i;
+ total += i * MCLBYTES; inuse += (i - j) * MCLBYTES;
+
+ printf "%d Kbytes allocated to network (%d%% in use) ESTIMATE\n",
+ total / 1024, (inuse * 100) / total;
+ printf "%d requests for memory denied\n", mbufDrops;
+ }
+ if (!didany && DIAGNOSTIC)
+ printf "mbuf group: %s\n", DIAGNOSTIC;
+ }
--- /dev/null
+function ip_stats() {
+ didone = 0;
+ for (i in ipForwarding) {
+ didone = 1;
+
+ printf "ip (acting as %s):\n",
+ ipForwarding == 1 ? "gateway" : "host";
+ printf "%9s packets received\n", ipInReceives;
+ printf "%9s packets with header errors\n", ipInHdrErrors;
+ printf "%9s packets discarded due to congestion\n",
+ ipInDiscards;
+ printf "%9s datagrams for unknown ULP\n", ipInUnknownProtos;
+ printf "%9s datagrams delivered to ULPs\n", ipInDelivers;
+ printf "\n";
+ printf "%9s of %s datagrams reassembled\n",
+ ipReasmOKs, ipReasmReqds;
+ printf "%9s of %s+%s datagrams fragmented\n",
+ ipFragOKs, ipFragCreates, ipFragFails;
+ printf "\n";
+ printf "%9s datagrams forwarded\n", ipForwDatagrams;
+ printf "%9s datagrams sent by ULPs\n", ipOutRequests;
+ printf "%9s packets discarded due to congestion\n",
+ ipOutDiscards;
+ printf "%9s packets discarded due to no route\n",
+ ipOutNoRoutes;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "ip statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function icmp_stats() {
+ didone = 0;
+ for (i in icmpInMsgs) {
+ didone = 1;
+
+ printf "icmp:\n";
+ printf "%9s datagrams received\n", icmpInMsgs;
+ printf "%9s datagrams received in error\n", icmpInErrors;
+ printf "\tInput histogram:\n"
+ if (i = icmpInDestUnreachs)
+ printf "\t\tdestination unreachable: %d\n", i;
+ if (i = icmpInTimeExcds)
+ printf "\t\ttime exceeded: %d\n", i;
+ if (i = icmpInParmProbs)
+ printf "\t\tparameter problem: %d\n", i;
+ if (i = icmpInSrcQuenchs)
+ printf "\t\tsource quench: %d\n", i;
+ if (i = icmpInRedirects)
+ printf "\t\tredirect: %d\n", i;
+ if (i = icmpInEchos)
+ printf "\t\techo request: %d\n", i;
+ if (i = icmpInEchoReps)
+ printf "\t\techo reply: %d\n", i;
+ if (i = icmpInTimestamps)
+ printf "\t\ttimestamp request: %d\n", i;
+ if (i = icmpInTimestampReps)
+ printf "\t\ttimestamp reply: %d\n", i;
+ if (i = icmpInAddrMasks)
+ printf "\t\taddress mask request: %d\n", i;
+ if (i = icmpInAddrMaskReps)
+ printf "\t\taddress mask reply: %d\n", i;
+ printf "\n";
+ printf "%9s datagrams sent\n", icmpOutMsgs;
+ printf "%9s datagrams discarded due to error\n", icmpOutErrors;
+ printf "\tOutput histogram:\n"
+ if (i = icmpOutDestUnreachs)
+ printf "\t\tdestination unreachable: %d\n", i;
+ if (i = icmpOutTimeExcds)
+ printf "\t\ttime exceeded: %d\n", i;
+ if (i = icmpOutParmProbs)
+ printf "\t\tparameter problem: %d\n", i;
+ if (i = icmpOutSrcQuenchs)
+ printf "\t\tsource quench: %d\n", i;
+ if (i = icmpOutRedirects)
+ printf "\t\tredirect: %d\n", i;
+ if (i = icmpOutEchos)
+ printf "\t\techo request: %d\n", i;
+ if (i = icmpOutEchoReps)
+ printf "\t\techo reply: %d\n", i;
+ if (i = icmpOutTimestamps)
+ printf "\t\ttimestamp request: %d\n", i;
+ if (i = icmpOutTimestampReps)
+ printf "\t\ttimestamp reply: %d\n", i;
+ if (i = icmpOutAddrMasks)
+ printf "\t\taddress mask request: %d\n", i;
+ if (i = icmpOutAddrMaskReps)
+ printf "\t\taddress mask reply: %d\n", i;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "icmp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function rtoa(r) {
+ if (r in to)
+ return to[r];
+
+ return (r ? r : "unknown");
+}
+
+function tcp_stats() {
+ didone = 0;
+ for (i in tcpRtoAlgorithm) {
+ didone = 1;
+
+ to[1] = "other"; to[2] = "constant" ; to[3] = "rsre"; to[4] = "vanj";
+ printf "tcp (using %s algorithm):\n", rtoa(tcpRtoAlgorithm);
+ printf "%9s segments received\n", tcpInSegs;
+ printf "%9s segments with header errors\n", tcpInErrs;
+ printf "\n";
+ printf "%9s connection attempts failed\n", tcpAttemptFails;
+ printf "%9s RSTs received on connections\n", tcpEstabResets;
+ printf "\n";
+ printf "%9s segments sent\n", tcpOutSegs;
+ printf "%9s segments retransmitted\n", tcpRetransSegs;
+ printf "%9s RSTs sent\n", tcpOutRsts;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "tcp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function udp_stats() {
+ didone = 0;
+ for (i in udpInDatagrams) {
+ didone = 1;
+
+ printf "udp:\n";
+ printf "%9s datagrams received\n", udpInDatagrams;
+ printf "%9s datagrams for unknown port\n", udpNoPorts;
+ printf "%9s datagrams with header errors\n", udpInErrors;
+ printf "\n";
+ printf "%9s datagrams sent\n", udpOutDatagrams;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "udp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function clnp_stats() {
+ for (i in clnpForwarding) {
+ didone = 1;
+
+ printf "clnp (acting as %s-system):\n",
+ clnpForwarding == 1 ? "intermediate" : "end";
+ printf "%9s packets received\n", clnpInReceives;
+ printf "%9s packets with header errors\n", clnpInHdrErrors;
+ printf "%9s packets discarded due to congestion\n", clnpInDiscards;
+ printf "%9s datagrams for unknown ULP\n", clnpInUnknownULPs;
+ printf "%9s datagrams delivered to ULPs\n", clnpInDelivers;
+ printf "\n";
+ printf "%9s of %s datagrams reassembled\n",
+ clnppReasmOKs, clnpReasmReqds;
+ printf "%9s of %s+%s datagrams segmented\n",
+ clnpSegOKs, clnpSegCreates, clnpSegFails;
+ printf "\n";
+ printf "%9s datagrams forwarded\n", clnpForwPDUs;
+ printf "%9s datagrams sent by ULPs\n", clnpOutRequests;
+ printf "%9s packets discarded due to congestion\n",
+ clnpOutDiscards;
+ printf "%9s packets discarded due to no route\n", clnpOutNoRoutes;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "clnp statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function error_stats() {
+ didone = 0;
+ for (i in clnpInErrors) {
+ didone = 1;
+
+ printf "clnp error:\n";
+ printf "%9s error PDUs received\n", clnpInErrors;
+ printf "\tInput histogram:\n";
+ if (i = clnpInErrUnspecs)
+ printf "\t\tclnpInErrUnspecs: %d\n", i;
+ if (i = clnpInErrProcs)
+ printf "\t\tclnpInErrProcs: %d\n", i;
+ if (i = clnpInErrCksums)
+ printf "\t\tclnpInErrCksums: %d\n", i;
+ if (i = clnpInErrCongests)
+ printf "\t\tclnpInErrCongests: %d\n", i;
+ if (i = clnpInErrHdrs)
+ printf "\t\tclnpInErrHdrs: %d\n", i;
+ if (i = clnpInErrSegs)
+ printf "\t\tclnpInErrSegs: %d\n", i;
+ if (i = clnpInErrIncomps)
+ printf "\t\tclnpInErrIncomps: %d\n", i;
+ if (i = clnpInErrDups)
+ printf "\t\tclnpInErrDups: %d\n", i;
+ if (i = clnpInErrUnreachDsts)
+ printf "\t\tclnpInErrUnreachDsts: %d\n", i;
+ if (i = clnpInErrUnknownDsts)
+ printf "\t\tclnpInErrUnknownDsts: %d\n", i;
+ if (i = clnpInErrSRUnspecs)
+ printf "\t\tclnpInErrSRUnspecs: %d\n", i;
+ if (i = clnpInErrSRSyntaxes)
+ printf "\t\tclnpInErrSRSyntaxes: %d\n", i;
+ if (i = clnpInErrSRUnkAddrs)
+ printf "\t\tclnpInErrSRUnkAddrs: %d\n", i;
+ if (i = clnpInErrSRBadPaths)
+ printf "\t\tclnpInErrSRBadPaths: %d\n", i;
+ if (i = clnpInErrHops)
+ printf "\t\tclnpInErrHops: %d\n", i;
+ if (i = clnpInErrHopReassms)
+ printf "\t\tclnpInErrHopReassms: %d\n", i;
+ if (i = clnpInErrUnsOptions)
+ printf "\t\tclnpInErrUnsOptions: %d\n", i;
+ if (i = clnpInErrUnsVersions)
+ printf "\t\tclnpInErrUnsVersions: %d\n", i;
+ if (i = clnpInErrUnsSecurities)
+ printf "\t\tclnpInErrUnsSecurities: %d\n", i;
+ if (i = clnpInErrUnsSRs)
+ printf "\t\tclnpInErrUnsSRs: %d\n", i;
+ if (i = clnpInErrUnsRRs)
+ printf "\t\tclnpInErrUnsRRs: %d\n", i;
+ if (i = clnpInErrInterferences)
+ printf "\t\tclnpInErrInterferences: %d\n", i;
+ printf "\n";
+ printf "%9s error PDUs sent\n", clnpOutErrors;
+ printf "\tOutput histogram:\n";
+ if (i = clnpOutErrUnspecs)
+ printf "\t\tclnpOutErrUnspecs: %d\n", i;
+ if (i = clnpOutErrProcs)
+ printf "\t\tclnpOutErrProcs: %d\n", i;
+ if (i = clnpOutErrCksums)
+ printf "\t\tclnpOutErrCksums: %d\n", i;
+ if (i = clnpOutErrCongests)
+ printf "\t\tclnpOutErrCongests: %d\n", i;
+ if (i = clnpOutErrHdrs)
+ printf "\t\tclnpOutErrHdrs: %d\n", i;
+ if (i = clnpOutErrSegs)
+ printf "\t\tclnpOutErrSegs: %d\n", i;
+ if (i = clnpOutErrIncomps)
+ printf "\t\tclnpOutErrIncomps: %d\n", i;
+ if (i = clnpOutErrDups)
+ printf "\t\tclnpOutErrDups: %d\n", i;
+ if (i = clnpOutErrUnreachDsts)
+ printf "\t\tclnpOutErrUnreachDsts: %d\n", i;
+ if (i = clnpOutErrUnknownDsts)
+ printf "\t\tclnpOutErrUnknownDsts: %d\n", i;
+ if (i = clnpOutErrSRUnspecs)
+ printf "\t\tclnpOutErrSRUnspecs: %d\n", i;
+ if (i = clnpOutErrSRSyntaxes)
+ printf "\t\tclnpOutErrSRSyntaxes: %d\n", i;
+ if (i = clnpOutErrSRUnkAddrs)
+ printf "\t\tclnpOutErrSRUnkAddrs: %d\n", i;
+ if (i = clnpOutErrSRBadPaths)
+ printf "\t\tclnpOutErrSRBadPaths: %d\n", i;
+ if (i = clnpOutErrHops)
+ printf "\t\tclnpOutErrHops: %d\n", i;
+ if (i = clnpOutErrHopReassms)
+ printf "\t\tclnpOutErrHopReassms: %d\n", i;
+ if (i = clnpOutErrUnsOptions)
+ printf "\t\tclnpOutErrUnsOptions: %d\n", i;
+ if (i = clnpOutErrUnsVersions)
+ printf "\t\tclnpOutErrUnsVersions: %d\n", i;
+ if (i = clnpOutErrUnsSecurities)
+ printf "\t\tclnpOutErrUnsSecurities: %d\n", i;
+ if (i = clnpOutErrUnsSRs)
+ printf "\t\tclnpOutErrUnsSRs: %d\n", i;
+ if (i = clnpOutErrUnsRRs)
+ printf "\t\tclnpOutErrUnsRRs: %d\n", i;
+ if (i = clnpOutErrInterferences)
+ printf "\t\tclnpOutErrInterferences: %d\n", i;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "clnp error statistics: %s\n\n", DIAGNOSTIC;
+}
+
+function esis_stats() {
+ didone = 0;
+ for (i in esisESHins) {
+ didone = 1;
+
+ printf "es-is:\n";
+ printf "%9s ESHs received\n", esisESHins;
+ printf "%9s ISHs received\n", esisISHins;
+ printf "%9s RDUs received\n", esisRDUins;
+ printf "\n";
+ printf "%9s ESHs sent\n", esisESHouts;
+ printf "%9s ISHs sent\n", esisISHouts;
+ printf "%9s RDUs sent\n", esisRDUouts;
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "es-is statistics: %s\n\n", DIAGNOSTIC;
+}
+
+BEGIN {
+ ip_stats();
+ icmp_stats();
+ tcp_stats();
+ udp_stats();
+ if (!oflag)
+ exit(0);
+
+ clnp_stats();
+ error_stats();
+ esis_stats();
+ }
--- /dev/null
+function rt_type(f) {
+ if (f in types)
+ return types[f];
+
+ return (f ? f : "unknown");
+}
+
+function rt_flags(f) {
+ s = "";
+
+ if (bit_and(f, 1))
+ s = (s "U");
+ if (bit_and(f, 2))
+ s = (s "G");
+ if (bit_and(f, 4))
+ s = (s "H");
+ if (bit_and(f, 8))
+ s = (s "R");
+ if (bit_and(f, 16))
+ s = (s "D");
+ if (bit_and(f, 32))
+ s = (s "M");
+ if (bit_and(f, 64))
+ s = (s "Do");
+ if (bit_and(f, 128))
+ s = (s "C");
+ if (bit_and(f, 256))
+ s = (s "X");
+
+ return s;
+}
+
+function do_stats() {
+ if (!hasunix) {
+ printf "routing statistics not implemented\n";
+ exit(1);
+ }
+
+ didone = 0;
+ for (i in unixRouteBadRedirects) {
+ didone = 1;
+
+ printf "routing:\n";
+ printf "%9s bad routing redirects\n", unixRouteBadRedirects;
+ printf "%9s dynamic created routes\n", unixRouteCreatedByRedirects;
+ printf "%9s new gateways due to redirects\n", unixRouteModifiedByRedirects;
+ printf "%9s destinations found unreachable\n", unixRouteLookupFails;
+ printf "%9s uses of a wildcard route\n", unixRouteWildcardUses;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "routing statistics: %s\n\n", DIAGNOSTIC;
+}
+
+BEGIN {
+ hasunix = unixNetstat == 1;
+
+ if (sflag) {
+ do_stats();
+ exit(0);
+ }
+
+ types[1] = "Other";
+ types[2] = "Invalid";
+ types[3] = "Direct";
+ types[4] = "Remote";
+
+ printf "Routing tables\n";
+ printf "%-15s %-15s %-8s %-6s %-10s %s\n",
+ "Destination",
+ "Gateway",
+ hasunix ? "Flags" : "Type",
+ "Refcnt",
+ "Use",
+ "Interface";
+ didone = 0;
+ for (i in ipRouteDest) {
+ didone = 1;
+
+ printf "%-15s %-15s %-8s %-6s %-10s %s (#%d)\n",
+ ipRouteDest == "0.0.0.0" ? "default" : ipRouteDest,
+ ipRouteNextHop,
+ hasunix ? rt_flags(unixIpRouteFlags[i]) \
+ : rt_type(ipRouteType),
+ hasunix ? unixIpRouteRefCnt[i] : "",
+ hasunix ? unixIpRouteUses[i] : "",
+ ifDescr[ipRouteIfIndex],
+ ipRouteIfIndex;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "ipRoutingTable: %s\n", DIAGNOSTIC;
+
+ if (!oflag)
+ exit(0);
+
+ didone = 0;
+ for (i in clnpRouteDest) {
+ didone = 1;
+
+ printf "NS+%-28s %-8s %-6s %-10s %s (#%d)\n",
+ clnpRouteDest == "0" ? "default" : clnpRouteDest,
+ hasunix ? rt_flags(unixclnpRouteFlags[i]) \
+ : rt_type(clnpRouteType),
+ hasunix ? unixclnpRouteRefCnt[i] : "",
+ hasunix ? unixclnpRouteUses[i] : "",
+ ifDescr[clnpRouteIfIndex],
+ clnpRouteIfIndex;
+ printf " %-15s NS+%s\n",
+ "", clnpRouteNextHop;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "clnpRoutingTable: %s\n", DIAGNOSTIC;
+ }
--- /dev/null
+function p_name(f) {
+ if (f in peers)
+ return peers[f];
+
+ return (f);
+}
+
+function p_type(f) {
+ if (f in ptypes)
+ return ptypes[f];
+
+ return (f ? f : "unknown");
+}
+
+function do_stats() {
+ didone = 0;
+ for (i in snmpInPkts) {
+ didone = 1;
+
+ printf "%9s packets received\n", snmpInPkts;
+ printf "%9s packets with bad version\n", snmpInBadVersions;
+ printf "%9s packets with bad community\n",
+ snmpInBadCommunityNames;
+ printf "%9s packets with authentication failures\n",
+ snmpInBadCommunityUses;
+ printf "%9s packets with BER parse errors\n",
+ snmpInASNParseErrs;
+ printf "%9s packets with ASN.1 parse errors\n", snmpInBadTypes;
+ printf "%9s packets with tooBigs\n", snmpInTooBigs;
+ printf "%9s packets with noSuchNames\n", snmpInNoSuchNames;
+ printf "%9s packets with badValues\n", snmpInBadValues;
+ printf "%9s packets with readOnlys\n", snmpInReadOnlys;
+ printf "%9s packets with genErrs\n", snmpInGenErrs;
+ printf "%9s variables read\n", snmpInTotalReqVars;
+ printf "%9s variables written\n", snmpInTotalSetVars;
+ printf "%9s getRequests received\n", snmpInGetRequests;
+ printf "%9s getNexts received\n", snmpInGetNexts;
+ printf "%9s setRequests received\n", snmpInSetRequests;
+ printf "%9s getResponses received\n", snmpInGetResponses;
+ printf "%9s traps received\n", snmpInTraps;
+ printf "\n";
+ printf "%9s packets generated\n", snmpOutPkts;
+ printf "%9s packets with tooBigs\n", snmpOutTooBigs;
+ printf "%9s packets with noSuchNames\n", snmpOutNoSuchNames;
+ printf "%9s packets with badValues\n", snmpOutBadValues;
+ printf "%9s packets with readOnlys\n", snmpOutReadOnlys;
+ printf "%9s packets with genErrs\n", snmpOutGenErrs;
+ printf "%9s getRequests generated\n", snmpOutGetRequests;
+ printf "%9s getNexts generated\n", snmpOutGetNexts;
+ printf "%9s setRequests generated\n", snmpOutSetRequests;
+ printf "%9s getResponses generated\n", snmpOutGetResponses;
+ printf "%9s traps generated\n", snmpOutTraps;
+ printf "%9s authorization traps\n",
+ snmpEnableAuthTraps == 1 ? "enabled" : "disabled";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "snmp statistics: %s\n", DIAGNOSTIC;
+}
+
+BEGIN {
+ if (sflag) {
+ do_stats();
+ exit(0);
+ }
+
+ INVALID = 2; CONNECTING = 3;
+ ptypes[1] = "valid";
+ ptypes[2] = "invalid";
+ ptypes[3] = "connecting";
+
+
+ printf "Primitive views:\n";
+ printf "%-20s %-20s %-15s %-15s\n",
+ "View",
+ "Transport",
+ "Address",
+ "User";
+
+ didone = 0;
+ for (i in viewPrimName) {
+ didone = 0;
+
+ if (viewPrimType == INVALID)
+ continue;
+ printf "%-20s %-20s %-15s %-15s\n",
+ viewPrimName,
+ viewPrimTDomain,
+ viewPrimTaddr,
+ viewPrimUser;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "primitive views: %s\n", DIAGNOSTIC;
+
+
+ printf "\nAccess policy:\n";
+ printf "%-5s %-20s %-30s %s\n",
+ "Priv.",
+ "View",
+ "Community",
+ "User";
+
+ didone = 0;
+ for (i in viewAclView) {
+ didone = 0;
+
+ if (viewAclType == INVALID)
+ continue;
+ printf "%5d %-20s %-30s %s\n",
+ viewAclPrivileges,
+ viewAclView,
+ viewAclCommunity,
+ viewAclUser;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "access policies: %s\n", DIAGNOSTIC;
+
+
+ printf "\nTrap Destinations:\n";
+ printf "%-20s %s\n",
+ "View",
+ "Generics";
+
+ didone = 0;
+ for (i in viewTrapView) {
+ didone = 0;
+
+ if (viewTrapView == INVALID)
+ continue;
+ printf "%-20s %s\n",
+ viewTrapView,
+ viewTrapGenerics;
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "traps destinations: %s\n", DIAGNOSTIC;
+
+
+ printf "\nSMUX peers:\n";
+ printf "%-5s %-25s %s\n",
+ "Index",
+ "Identity",
+ "Description";
+
+ didone = 0;
+ for (i in smuxPindex) {
+ didone = 1;
+
+ if (smuxPstatus == INVALID)
+ continue;
+ printf "%5d%s %-25s %s\n",
+ smuxPindex,
+ smuxPstatus == CONNECTING ? "*" : " ",
+ smuxPidentity,
+ smuxPdescription;
+ peers[smuxPindex] = smuxPindex " (" smuxPdescription ")";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "smux peers: %s\n", DIAGNOSTIC;
+
+
+ printf "\nSMUX subtrees:\n";
+ printf "%-5s %-25s %s\n",
+ "Prio.",
+ "Subtree",
+ "Peer";
+
+ didone = 0;
+ for (i in smuxTsubtree) {
+ didone = 1;
+
+ if (smuxTstatus == INVALID)
+ continue;
+ printf "%5d %-25s %s\n",
+ smuxTpriority,
+ smuxTsubtree,
+ p_name(smuxTindex);
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "smux peers: %s\n", DIAGNOSTIC;
+ }
--- /dev/null
+function services(i, s) {
+ if (i >= 128){ printf "%d", i; return; }
+
+ s = "%s";
+ if (i >= 64) { printf s, "applications"; s = ", %s"; i -= 64; }
+ if (i >= 32) { printf s, "presentation"; s = ", %s"; i -= 32; }
+ if (i >= 16) { printf s, "session"; s = ", %s"; i -= 16; }
+ if (i >= 8) { printf s, "end-to-end"; s = ", %s"; i -= 8; }
+ if (i >= 4) { printf s, "internet"; s = ", %s"; i -= 4; }
+ if (i >= 2) { printf s, "datalink"; s = ", %s"; i -= 2; }
+ if (i >= 1) { printf s, "physical"; s = ", %s"; i -= 1; }
+}
+
+function uptime(ds) {
+ s = ds / 100; ds = ds % 100;
+ m = s / 60; s = s % 60;
+ h = m / 60; m = m % 60;
+ d = h / 24; h = h % 24;
+
+ if (d > 0) { printf "%d days, ", d; }
+ if (d > 0 || h > 0) { printf "%d hours, ", h; }
+ if (d > 0 || h > 0 || m > 0) { printf "%d minutes, ", m; }
+ printf "%d", s;
+ if (ds > 0) { printf ".%02d", ds; }
+ printf " seconds";
+}
+
+BEGIN {
+ didone = 0;
+ for (i in sysDescr) {
+ didone = 1;
+
+ if ((name = sysName) == "")
+ name = AGENT;
+ printf "agent %s\n", name;
+ printf "%10.10s: %s\n", "running", sysDescr;
+ printf "%10.10s (%s)\n", "", sysObjectID;
+ if (name = sysServices) {
+ printf "%10.10s: ", "services";
+ services(name);
+ printf "\n";
+ }
+ if (name = sysLocation)
+ printf "%10.10s: %s\n", "location", name;
+ if (name = sysContact)
+ printf "%10.10s: %s\n", "contact", name;
+ printf "%10.10s: ", "uptime";
+ uptime(sysUpTime);
+ printf "\n";
+ }
+ if (!didone && DIAGNOSTIC)
+ printf "system group: %s\n", DIAGNOSTIC;
+ }
--- /dev/null
+: run this script through /bin/sh
+
+P=/usr/local/lib/awk
+
+F=mib.connections S= T=mib.protocols
+
+agent= community= flags=
+
+for A in $*
+do
+ case $A in
+ -m) F=mib.mbufs T=mib.mbufs ;;
+ -i) F=mib.interfaces T=mib.interfaces ;;
+ -h) F=mib.egp T=mib.egp ;;
+ -r) F=mib.routes T=mib.routes ;;
+ -z) F=mib.arp T=mib.arp ;;
+ -Z) F=mib.system T=mib.system ;;
+ -S) F=mib.snmp T=mib.snmp ;;
+
+ -a) flags="$flags -v aflag=1" ;;
+ -n) ;;
+ -o) flags="$flags -v oflag=1" ;;
+ -s) S=1 flags="$flags -v sflag=1" ;;
+ -t) echo "$A: unimplemented (warning)" 1>&2 ;;
+ -A) echo "$A: unimplemented (warning)" 1>&2 ;;
+
+ -*) echo "$A: unknown flag" 1>&2
+ exit 1 ;;
+
+ *) if [ "x$agent" = "x" ]; then
+ agent="-v AGENT=$A"
+ elif [ "x$community" = "x" ]; then
+ community="-v COMMUNITY=$A"
+ else
+ echo "usage: s-netstat [switches] [agent [community]]" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if [ "x$S" != "x" ]; then
+ F="$T"
+fi
+
+if [ ! -f $F ]; then
+ F="$P/$F"
+fi
+
+exec gawk $flags $agent $community -f $F
--- /dev/null
+.TH S-NETSTAT 1C "29 Aug 1990"
+.\" $Header: /f/osi/snmp/gawk-2.11/s-gawk/RCS/s-netstat.1c,v 7.4 91/02/22 09:45:27 mrose Interim $
+.\"
+.\" Contributed by NYSERNet Inc. This work was partially supported by the
+.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+.\" Center of the U.S. Air Force Systems Command under contract number
+.\" F30602-88-C-0016.
+.\"
+.\"
+.\" $Log: s-netstat.1c,v $
+.\" Revision 7.4 91/02/22 09:45:27 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.3 90/09/07 11:12:09 mrose
+.\" update
+.\"
+.\" Revision 7.2 90/08/30 15:15:40 mrose
+.\" update
+.\"
+.\" Revision 7.1 90/08/29 13:53:15 mrose
+.\" typo
+.\"
+.\" Revision 7.0 90/08/29 13:48:08 mrose
+.\" *** empty log message ***
+.\"
+.SH NAME
+s-netstat \- SNMP-based network status
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B s-netstat
+\%[-m|-i|-h|-r|-z|-Z|-S]
+\%[-a]
+\%[-o]
+\%[-s]
+.br
+\%[agent\0\%[community]]
+.in -.5i
+.SH DESCRIPTION
+The \fIs-netstat\fR script invokes SNMP-capable \fIgawk\fR with the
+arguments necessary to display the contents of various network-related
+data structures on the named \fIagent\fR
+(using the indicated \fIcommunity\fR).
+.PP
+Note that because \fIs-netstat\fR uses the SNMP to retrieve information,
+all addresses are shown as numbers, not as symbolic names.
+.SH OPTIONS
+Not all of the options listed here can be used in combination.
+If one of these primary switches does not appear,
+then connection information is shown.
+.TP
+.B -m
+Show mbuf information.
+.TP
+.B -i
+Show interface information.
+.TP
+.B -h
+Show EGP information.
+.TP
+.B -r
+Show routing information.
+.TP
+.B -z
+Show address translation information.
+.TP
+.B -Z
+Show system information.
+.TP
+.B -S
+Show SNMP information.
+.PP
+Options listed below provide further qualification of the display
+formats listed above.
+.TP
+.B -a
+Show information on all connections.
+(Meaningful only if none of the above options are present.)
+.TP
+.B -o
+Show OSI-related information in addition to internet-related information.
+(Not meaningful for -m, -h, -Z, or -S options.)
+.TP
+.B -s
+Show statistical information.
+(Not meaningful for -m, -i, -z, or -Z options.)
+.SH FILES
+.nf
+.ta \w'\*(EDobjects.defs 'u
+\*(EDobjects.defs MIB definitions
+.re
+.fi
+.SH AUTHOR
+Marshall T. Rose,
+Performance Systems International.
+.PP
+This work was partially supported by the
+U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+Center of the U.S. Air Force Systems Command under contract number
+F30602-88-C-0016.
+.PP
+Although this package is distributed with the ISODE,
+it is not an OSI program, per se.
+Inasmuch as the continued survival of the Internet hinges on all nodes
+becoming network manageable,
+this package was developed using the ISODE and is being freely
+distributed with releases of Berkeley UNIX.
--- /dev/null
+: run this script through /bin/sh
+
+agent= community= dest= flags=
+
+for A in $*
+do
+ case $A in
+ -*) echo "$A: unknown flag" 1>&2
+ exit 1 ;;
+
+ *) if [ "x$dest" = "x" ]; then
+ dest="-v DEST=$A"
+ elif [ "x$community" = "x" ]; then
+ community="-v COMMUNITY=$A"
+ elif [ "x$agent" = "x" ]; then
+ agent="-v AGENT=$A"
+ else
+ echo "usage: s-traceroute [switches] destination [community [agent]]" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if [ "x$dest" = "x" ]; then
+ echo "no destination specified" 1>&2
+ exit 1
+fi
+
+exec gawk $flags $agent $community $dest '
+BEGIN {
+ printf "from %s to %s:\n", AGENT, DEST;
+ tried[AGENT] = 1;
+ INVALID = 2; DIRECT = 3;
+
+ split (DEST, dest, ".");
+
+ if (dest[1] < 128)
+ net = dest[1];
+ else
+ if (dest[1] < 192)
+ net = dest[1] "." dest[2];
+ else
+ net = dest[1] "." dest[2] "." dest[3];
+
+ while (DEST != AGENT) {
+ dr = 0;
+ gotit = 0;
+ for (i in ipRouteMask, net) {
+ if ((type = ipRouteType) == INVALID)
+ continue;
+
+ split(ipRouteMask, mask, ".");
+ mask = bit_and(dest[1],mask[1]) "." \
+ bit_and(dest[2],mask[2]) "." \
+ bit_and(dest[3],mask[3]) "." \
+ bit_and(dest[4],mask[4]);
+ if (mask == ipRouteDest) {
+ hop = ipRouteNextHop;
+ gotit = 1;
+ break;
+ }
+ }
+ if (!gotit) {
+ if ((hop = ipRouteNextHop[addr = DEST]) \
+ && (type = ipRouteType[addr]) == INVALID)
+ hop = 0;
+ if (!hop \
+ && (hop = ipRouteNextHop[addr = net]) \
+ && (type = ipRouteType[addr]) == INVALID)
+ hop = 0;
+ if (!hop && (hop = ipRouteNextHop[addr = "0.0.0.0"])) {
+ if ((type = ipRouteType[addr]) == INVALID)
+ hop = 0;
+ else
+ dr = 1;
+ }
+ }
+
+ if (hop) {
+ printf " via %-15s metric %2d%s\n",
+ hop, ipRouteMetric1[addr],
+ dr ? " (default route)" : "";
+ }
+ else {
+ printf "\nno path to %s from %s\n%s\n",
+ DEST, AGENT, DIAGNOSTIC;
+ exit(1);
+ }
+
+ if (type == DIRECT) {
+ printf "\tdirect route.\n";
+ exit(0);
+ }
+
+ if (hop in tried)
+ printf "\nrouting loop!\n";
+ else
+ tried[hop] = 1;
+ AGENT = hop;
+ }
+
+ printf "\tdone.\n";
+ }
+'
--- /dev/null
+.TH S-TRACEROUTE 1C "29 Aug 1990"
+.\" $Header: /f/osi/snmp/gawk-2.11/s-gawk/RCS/s-traceroute.1c,v 7.2 91/02/22 09:45:29 mrose Interim $
+.\"
+.\" Contributed by NYSERNet Inc. This work was partially supported by the
+.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+.\" Center of the U.S. Air Force Systems Command under contract number
+.\" F30602-88-C-0016.
+.\"
+.\"
+.\" $Log#
+.\"
+.SH NAME
+s-traceroute \- SNMP-based route tracing facility
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B s-traceroute
+destination
+\%[community\0\%[agent]]
+.in -.5i
+.SH DESCRIPTION
+The \fIs-traceroute\fR script invokes SNMP-capable \fIgawk\fR with the
+arguments necessary to trace a route through the Internet.
+.PP
+Note that because \fIs-traceroute\fR uses SNMP to retrieve
+information,
+the destination (and optional agent) addresses should be specified in
+dot-notation,
+not as symbolic names.
+.SH FILES
+.nf
+.ta \w'\*(EDobjects.defs 'u
+\*(EDobjects.defs MIB definitions
+.re
+.fi
+.SH AUTHOR
+Marshall T. Rose,
+Performance Systems International.
+.PP
+This work was partially supported by the
+U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+Center of the U.S. Air Force Systems Command under contract number
+F30602-88-C-0016.
+.PP
+Although this package is distributed with the ISODE,
+it is not an OSI program, per se.
+Inasmuch as the continued survival of the Internet hinges on all nodes
+becoming network manageable,
+this package was developed using the ISODE and is being freely
+distributed with releases of Berkeley UNIX.
--- /dev/null
+/* snmp.c - SNMP changes for gawk */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/gawk-2.11/RCS/snmp.c,v 7.10 91/02/22 09:45:08 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/gawk-2.11/RCS/snmp.c,v 7.10 91/02/22 09:45:08 mrose Interim $
+ *
+ *
+ * $Log: snmp.c,v $
+ * Revision 7.10 91/02/22 09:45:08 mrose
+ * Interim 6.8
+ *
+ * Revision 7.9 91/01/07 12:42:41 mrose
+ * update
+ *
+ * Revision 7.8 90/10/23 20:44:36 mrose
+ * update
+ *
+ * Revision 7.7 90/10/02 15:17:05 mrose
+ * robust
+ *
+ * Revision 7.6 90/09/07 11:11:50 mrose
+ * update
+ *
+ * Revision 7.3 90/08/17 15:12:28 mrose
+ * for-in
+ *
+ * Revision 7.2 90/06/06 22:59:38 mrose
+ * update
+ *
+ * Revision 7.1 90/03/22 16:44:22 mrose
+ * touch-up
+ *
+ * Revision 7.0 90/03/05 10:33:19 mrose
+ * *** empty log message ***
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#ifdef SNMP
+#include "awk.h"
+#ifdef HUGE
+#undef HUGE
+#endif
+#include <isode/snmp/objects.h>
+#include <isode/pepsy/SNMP-types.h>
+#include <isode/dgram.h>
+#include <isode/internet.h>
+#include <isode/isoaddrs.h>
+#include <isode/tailor.h>
+
+/* \f DATA */
+
+int debug = 0;
+
+int snmp_enabled = 1;
+int snmp_scalars_as_arrays = 1;
+char *snmp_file = NULLCP;
+
+static integer snmp_id = 0;
+static int snmp_portno = 0;
+static int snmp_retries = 3;
+static int snmp_timeout = 10;
+
+static char *snmp_agent = NULL;
+static char *snmp_community = NULL;
+
+NODE *AGENT_node,
+ *COMMUNITY_node,
+ *DIAGNOSTIC_node,
+ *ERROR_node,
+ *RETRIES_node,
+ *TIMEOUT_node;
+NODE *Ndot_string;
+
+static int snmp_fd = NOTOK;
+static struct sockaddr_in in_socket;
+static PS ps = NULLPS;
+
+static struct type_SNMP_Message msgs;
+static struct type_SNMP_PDUs pdus;
+static struct type_SNMP_PDU parms;
+static struct type_SNMP_VarBindList vps;
+static struct type_SNMP_VarBind vs;
+
+
+struct snmp_search {
+ struct search s_search; /* must be first element in struct */
+
+ OT s_parent;
+
+ struct type_SNMP_VarBindList *s_prototype;
+
+#define NREQ 10
+ struct snmp_req {
+ struct type_SNMP_VarBindList *r_bindings;
+ PE r_pb;
+
+ integer r_id;
+ PE r_pe;
+
+ struct type_SNMP_Message *r_msg;
+ } s_reqs[NREQ];
+
+ struct snmp_search *s_prev;
+ struct snmp_search *s_next;
+};
+
+static struct snmp_search *head = NULL;
+static struct snmp_search *tail = NULL;
+
+
+char *snmp_error (), *snmp_variable ();
+
+
+#ifndef SYS5
+long random ();
+#endif
+
+/* \f INIT */
+
+int snmp_init ()
+{
+ char *addr;
+ register struct hostent *hp;
+ struct sockaddr_in lo_socket;
+
+ snmp_onceonly ();
+
+ if (lookup (variables, "AGENT")
+ || !(hp = gethostbystring (getlocalhost ())))
+ return 1;
+
+ inaddr_copy (hp, &lo_socket);
+ addr = inet_ntoa (lo_socket.sin_addr);
+ AGENT_node = install (variables, "AGENT",
+ node (make_string (addr, strlen (addr)),
+ Node_var, (NODE *) NULL));
+
+ return 0;
+}
+
+/* \f */
+
+int f_integer (), f_octets (), f_display (), f_objectID (), f_null (),
+ f_ulong (), f_ipaddr (), f_clnpaddr ();
+
+
+static struct pair {
+ char *pp_name;
+ IFP pp_value;
+} pairs[] = {
+ "INTEGER", f_integer,
+ "Services", f_integer,
+ "Privileges", f_integer,
+ "OctetString", f_octets,
+ "DisplayString", f_display,
+ "ObjectID", f_objectID,
+ "NULL", f_null,
+ "IpAddress", f_ipaddr,
+ "NetworkAddress", f_ipaddr,
+ "Counter", f_ulong,
+ "Gauge", f_ulong,
+ "TimeTicks", f_ulong,
+ "ClnpAddress", f_clnpaddr,
+
+ NULL
+};
+
+
+static snmp_onceonly () {
+ int i;
+ register struct pair *pp;
+ register struct type_SNMP_Message *msg = &msgs;
+ register struct type_SNMP_PDUs *pdu = &pdus;
+ register struct type_SNMP_PDU *parm = &parms;
+ register struct type_SNMP_VarBindList *vp = &vps;
+ register struct type_SNMP_VarBind *v = &vs;
+ OS os;
+ register OT ot,
+ ot2;
+
+ Ndot_string = make_string (".", 1);
+ Ndot_string -> flags |= PERM;
+
+ if (readobjects (snmp_file) == NOTOK)
+ fatal ("readobjects: %s", PY_pepy);
+
+ /* mark entries that are actually columns! */
+ for (ot = text2obj ("ccitt"); ot; ot = ot -> ot_next) {
+ if (ot -> ot_syntax
+ || (i = strlen (ot -> ot_text)) <= 5
+ || strcmp (ot -> ot_text + i - 5, "Entry"))
+ continue;
+ for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling)
+ if (ot2 -> ot_children)
+ break;
+ if (ot2)
+ continue;
+ for (ot2 = ot -> ot_children; ot2; ot2 = ot2 -> ot_sibling)
+ if (ot2 -> ot_syntax)
+ ot2 -> ot_getfnx = (IFP) 1;
+ else
+ if (debug > 0)
+ fprintf (stderr, "no syntax for columnar object \"%s\"\n",
+ ot -> ot_text);
+ }
+
+ for (pp = pairs; pp -> pp_name; pp++)
+ if ((os = text2syn (pp -> pp_name)) == NULL)
+ fatal ("lost syntax for \"%s\"", pp -> pp_name);
+ else
+ os -> os_decode = pp -> pp_value;
+
+ bzero ((char *) msg, sizeof *msg);
+ msg -> version = int_SNMP_version_version__1;
+ msg -> data = pdu;
+
+ bzero ((char *) pdu, sizeof *pdu);
+ pdu -> offset = type_SNMP_PDUs_get__request;
+ pdu -> un.get__request = parm;
+
+ bzero ((char *) parm, sizeof *parm);
+ parm -> variable__bindings = vp;
+
+ bzero ((char *) vp, sizeof *vp);
+ vp -> VarBind = v;
+
+ bzero ((char *) v, sizeof *v);
+ if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
+ == NULLPE)
+ fatal ("pe_alloc: out of memory");
+
+ ps_len_strategy = PS_LEN_LONG;
+
+#ifndef SYS5
+ srandom (getpid ());
+#else
+ srand (getpid ());
+#endif
+}
+
+/* \f CHECK */
+
+int snmp_check (r, name)
+NODE *r;
+char *name;
+{
+ char c;
+ register char *cp;
+ OT ot;
+
+ for (cp = name; is_identchar (*cp); cp++)
+ continue;
+ if (c = *cp)
+ *cp = NULL;
+ if ((ot = text2obj (name)) && ot -> ot_syntax) {
+ r -> magic = (caddr_t) ot;
+ if (ot -> ot_getfnx || snmp_scalars_as_arrays)
+ r -> type = Node_var_array;
+ }
+ *cp = c;
+}
+
+/* \f GET */
+
+int snmp_get (ptr, instname)
+NODE *ptr;
+char *instname;
+{
+ int gotone,
+ retries,
+ status = -1;
+ struct type_SNMP_Message *msg = &msgs;
+ register struct type_SNMP_PDU *parm = msg -> data -> un.get__request;
+ register struct type_SNMP_VarBind *v =
+ parm -> variable__bindings -> VarBind;
+ PE pe = NULLPE,
+ p = NULLPE;
+ OID oid;
+ OT ot = (OT) ptr -> magic;
+ NODE *value = NULL;
+
+ if (snmp_ready (1) == NOTOK)
+ goto out;
+
+ parm -> request__id = snmp_id;
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name), v -> name = NULL;
+
+ if (instname == NULL) {
+ if (ot -> ot_getfnx || snmp_scalars_as_arrays) {
+ register struct snmp_search *s;
+
+ for (s = tail; s; s = s -> s_prev) {
+ register struct snmp_req *sr;
+
+ if (ot -> ot_name -> oid_nelem
+ != (oid = s -> s_parent -> ot_name) -> oid_nelem + 1
+ || bcmp ((char *) ot -> ot_name -> oid_elements,
+ (char *) oid -> oid_elements,
+ oid -> oid_nelem
+ * sizeof ot -> ot_name -> oid_elements[0]))
+ continue;
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+ register struct type_SNMP_VarBindList *vp;
+
+ for (vp = sr -> r_bindings; vp; vp = vp -> next) {
+ if (ot -> ot_name -> oid_nelem
+ >= (v = vp -> VarBind) -> name -> oid_nelem)
+ fatal ("snmp_get: internal error");
+ if (bcmp ((char *) v -> name -> oid_elements,
+ (char *) ot -> ot_name -> oid_elements,
+ ot -> ot_name -> oid_nelem
+ * sizeof ot -> ot_name
+ -> oid_elements[0]))
+ continue;
+
+ goto get_value;
+ }
+ }
+ status = int_SNMP_error__status_noSuchName;
+ goto out;
+ }
+ if (ot -> ot_getfnx) {
+ snmp_diag (NULLCP,
+ "can't use SNMP array variable as scalar unless within for-in construct");
+ goto out;
+ }
+ }
+
+ if ((oid = v -> name = oid_extend (ot -> ot_name, 1)) == NULL) {
+no_mem_for_inst: ;
+ snmp_diag (NULLCP, "oid_extend: out of memory");
+ goto out;
+ }
+ v -> name -> oid_elements[v -> name -> oid_nelem - 1] = 0;
+ }
+ else {
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ OID inst = str2oid (instname);
+
+ if (inst == NULL) {
+ snmp_diag (NULLCP, "str2oid: bad instance identifier \"%s\"",
+ instname);
+ goto out;
+ }
+ if ((oid = v -> name = oid_extend (ot -> ot_name, inst -> oid_nelem))
+ == NULL)
+ goto no_mem_for_inst;
+ ip = oid -> oid_elements + oid -> oid_nelem - inst -> oid_nelem;
+ jp = inst -> oid_elements;
+ for (i = inst -> oid_nelem; i > 0; i--)
+ *ip++ = *jp++;
+ }
+
+ if (encode_SNMP_Message (&pe, 1, 0, NULLCP, msg) == NOTOK) {
+ snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
+ goto out;
+ }
+
+ msg = NULL, gotone = 0;
+ for (retries = snmp_retries; retries > 0; ) {
+ int len;
+ fd_set rfds;
+
+ if (debug > 1)
+ print_SNMP_Message (pe, 1, NULLIP, NULLVP, NULLCP);
+ len = ps -> ps_byteno;
+ if (pe2ps (ps, pe) == NOTOK) {
+ snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno));
+ goto error_x;
+ }
+ if (debug > 0 && (len = ps -> ps_byteno - len) > 484)
+ fprintf (stderr, "sent message of %d octets\n", len);
+
+ FD_ZERO (&rfds);
+ FD_SET (snmp_fd, &rfds);
+
+ switch (xselect (snmp_fd + 1, &rfds, NULLFD, NULLFD, snmp_timeout)) {
+ case NOTOK:
+ snmp_diag ("failed", "xselect");
+ goto error_x;
+
+ default:
+ if (FD_ISSET (snmp_fd, &rfds))
+ break;
+ /* else fall... */
+ case OK:
+ if (debug > 0)
+ fprintf (stderr, "timeout...\n");
+ retries--;
+ continue;
+ }
+
+ if ((p = ps2pe (ps)) == NULLPE) {
+ snmp_diag (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno));
+ goto error_x;
+ }
+ if (decode_SNMP_Message (p, 1, NULLIP, NULLVP, &msg) == NOTOK) {
+ snmp_diag (NULLCP, "decode_SNMP_Message: %s", PY_pepy);
+ goto out;
+ }
+ if (debug > 1)
+ print_SNMP_Message (p, 1, NULLIP, NULLVP, NULLCP);
+
+ if (msg -> data -> offset != type_SNMP_PDUs_get__response) {
+ snmp_diag (NULLCP, "unexpected message type %d",
+ msg -> data -> offset);
+ goto out;
+ }
+
+ if ((parm = msg -> data -> un.get__response) -> request__id == snmp_id)
+ break;
+
+ if (debug > 0)
+ fprintf (stderr, "bad ID (got %ld, wanted %ld)\n",
+ (long) parm -> request__id, (long) snmp_id);
+
+ if (msg)
+ free_SNMP_Message (msg), msg = NULL;
+ if (p)
+ pe_free (p), p = NULLPE;
+
+ gotone++;
+ }
+ if (retries <= 0) {
+ snmp_diag (NULLCP,
+ "no %sresponse within %d retries of %s%d second%s each",
+ gotone ? "acceptable " : "", snmp_retries + gotone,
+ gotone ? "upto " : "",
+ snmp_timeout, snmp_timeout != 1 ? "s" : "");
+ goto out;
+ }
+
+ if ((status = parm -> error__status) != int_SNMP_error__status_noError) {
+ char *cp = snmp_variable (parm, parm -> error__index);
+
+ snmp_diag (NULLCP, cp ? "%s at position %d (%s)" : "%s at position %d",
+ snmp_error (status), parm -> error__index, cp);
+ goto out;
+ }
+
+ if (parm -> variable__bindings == NULL
+ || (v = parm -> variable__bindings -> VarBind) == NULL) {
+ snmp_diag (NULLCP, "missing variable in response");
+ goto out;
+ }
+ if (debug > 0 && parm -> variable__bindings -> next)
+ fprintf (stderr, "too many responses starting with: %s\n",
+ oid2ode (parm -> variable__bindings -> next -> VarBind -> name));
+
+ if (oid_cmp (oid, v -> name)) {
+ char buffer[BUFSIZ];
+
+ (void) strcpy (buffer, oid2ode (v -> name));
+ snmp_diag (NULLCP, "wrong variable returned (got %s, wanted %s)",
+ buffer, oid2ode (oid));
+ goto out;
+ }
+
+get_value: ;
+ if ((*ot -> ot_syntax -> os_decode) (&value, v -> value) == NOTOK) {
+ snmp_diag (NULLCP, "decode error for variable \"%s\": %s",
+ oid2ode (v -> name), PY_pepy);
+ goto out;
+ }
+
+ goto out;
+
+error_x: ;
+ if (ps)
+ ps_free (ps), ps = NULLPS;
+ if (snmp_fd != NOTOK)
+ (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
+
+out: ;
+ if (msg && msg != &msgs)
+ free_SNMP_Message (msg);
+ if (p)
+ pe_free (p);
+ if (pe)
+ pe_free (pe);
+
+ deref = ptr -> var_value;
+ do_deref ();
+
+ ptr -> var_value = value ? value : Nnull_string;
+
+ assign_number (&ERROR_node -> var_value, (AWKNUM) status);
+}
+
+/* \f SCAN */
+
+struct search *snmp_assoc_scan (symbol, instance)
+NODE *symbol,
+ *instance;
+{
+ register struct snmp_search *s;
+ OID inst;
+ register OT ot = (OT) symbol -> magic;
+ register struct type_SNMP_VarBindList **vp,
+ **vp2;
+
+ if (!ot -> ot_getfnx && (!snmp_scalars_as_arrays || instance))
+ fatal ("can't use SNMP scalar variable as control for for-in");
+
+ if (instance) {
+ char *instname;
+ NODE *r;
+
+ if ((r = instance) -> type != Node_val)
+ r = r_tree_eval (instance);
+
+ if ((inst = str2oid (instname = force_string (r) -> stptr)) == NULL) {
+ snmp_diag (NULLCP, "str2oid: bad instance identifier \"%s\"",
+ instname);
+ free_temp (r);
+ return NULL;
+ }
+
+ if (r != instance)
+ free_temp (r);
+ }
+ else
+ inst = NULL;
+ emalloc (s, struct snmp_search *, sizeof *s, "snmp_assoc_scan1");
+ bzero ((char *) s, sizeof *s);
+
+ ot -> ot_name -> oid_nelem--;
+ s -> s_parent = name2obj (ot -> ot_name);
+ ot -> ot_name -> oid_nelem++;
+
+ if ((ot = s -> s_parent) == NULL)
+ fatal ("unable to find parent for \"%s\"", snmp_name (symbol));
+
+ s -> s_prototype = NULL;
+
+ vp = &s -> s_reqs[0].r_bindings, vp2 = &s -> s_prototype;
+ for (ot = ot -> ot_children; ot; ot = ot -> ot_sibling) {
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ register struct type_SNMP_VarBindList *bind;
+ register struct type_SNMP_VarBind *v,
+ *v2;
+
+ if (!ot -> ot_syntax)
+ continue;
+ emalloc (bind, struct type_SNMP_VarBindList *, sizeof *bind,
+ "snmp_assoc_scan2");
+ *vp = bind, vp = &bind -> next;
+ bind -> next = NULL;
+
+ emalloc (v, struct type_SNMP_VarBind *, sizeof *v, "snmp_assoc_scan3");
+ bind -> VarBind = v;
+ if (inst) {
+ if ((v -> name = oid_extend (ot -> ot_name, inst -> oid_nelem))
+ == NULL)
+ fatal ("oid_extend: out of memory");
+ ip = v -> name -> oid_elements + v -> name -> oid_nelem
+ - inst -> oid_nelem;
+ jp = inst -> oid_elements;
+ for (i = inst -> oid_nelem; i > 0; i--)
+ *ip++ = *jp++;
+ }
+ else
+ if ((v -> name = oid_cpy (ot -> ot_name)) == NULL)
+ fatal ("oid_cpy: out of memory");
+ v -> value = NULL;
+
+ emalloc (bind, struct type_SNMP_VarBindList *, sizeof *bind,
+ "snmp_assoc_scan4");
+ *vp2 = bind, vp2 = &bind -> next;
+ bind -> next = NULL;
+
+ emalloc (v2, struct type_SNMP_VarBind *, sizeof *v2,
+ "snmp_assoc_scan5");
+ bind -> VarBind = v2;
+ if ((v2 -> name = oid_cpy (v -> name)) == NULL)
+ fatal ("oid_cpy: out of memory");
+ v2 -> value = NULL;
+ }
+
+ if (head == NULL)
+ head = tail = s;
+ else {
+ tail -> s_next = s;
+ s -> s_prev = tail;
+ tail = s;
+ }
+
+ return snmp_assoc_next (&s -> s_search, 0);
+}
+
+/* \f */
+
+struct search *snmp_assoc_next (lookat, done)
+struct search *lookat;
+int done;
+{
+ int i;
+ char *cp;
+ register struct snmp_search *s = (struct snmp_search *) lookat;
+ register struct search *l = &s -> s_search;
+ struct OIDentifier oids;
+ OID oid;
+ OT ot = s -> s_parent;
+ register struct type_SNMP_VarBind *v;
+
+ deref = l -> retval, l -> retval = NULL;
+ do_deref ();
+
+ if (done
+ || snmp_get_next (s) == NOTOK
+ || s -> s_reqs[0].r_bindings == NULL) {
+ register struct snmp_req *sr;
+
+ if (s -> s_prototype)
+ free_SNMP_VarBindList (s -> s_prototype);
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+ free_SNMP_VarBindList (sr -> r_bindings);
+ if (sr -> r_pb)
+ pe_free (sr -> r_pb);
+ if (sr -> r_msg)
+ free_SNMP_Message (sr -> r_msg);
+ if (sr -> r_pe)
+ pe_free (sr -> r_pe);
+ }
+
+ if (tail != s)
+ fatal ("snmp_assoc_next: internal error1");
+ if (tail = s -> s_prev)
+ tail -> s_next = NULL;
+ else
+ head = NULL;
+
+ free ((char *) s);
+ return NULL;
+ }
+
+ if ((v = s -> s_reqs[0].r_bindings -> VarBind) == NULL
+ || (oid = v -> name) == NULL)
+ fatal ("snmp_assoc_next: internal error2");
+ if (ot -> ot_name -> oid_nelem >= oid -> oid_nelem
+ || bcmp ((char *) ot -> ot_name -> oid_elements,
+ (char *) oid -> oid_elements,
+ ot -> ot_name -> oid_nelem
+ * sizeof oid -> oid_elements[0]))
+ fatal ("snmp_assoc_next: internal error3");
+
+ oids.oid_nelem = oid -> oid_nelem - (i = ot -> ot_name -> oid_nelem + 1);
+ oids.oid_elements = oid -> oid_elements + i;
+
+ cp = sprintoid (&oids);
+ l -> retval = make_string (cp, strlen (cp));
+
+ return l;
+}
+
+/* \f */
+
+static int snmp_get_next (s)
+register struct snmp_search *s;
+{
+ register struct type_SNMP_VarBindList *vp,
+ *vp2,
+ **vpp,
+ **vpp2;
+ register struct snmp_req *sr,
+ *sp;
+
+ if (snmp_ready (0) == NOTOK || snmp_get_next_aux (s) == NOTOK)
+ return NOTOK;
+
+ vpp = &s -> s_prototype, vp = NULL;
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+ vpp2 = &sr -> r_msg -> data -> un.get__request -> variable__bindings;
+
+ while ((vp = *vpp) && (vp2 = *vpp2)) {
+ OID v = vp -> VarBind -> name,
+ v2 = vp2 -> VarBind -> name;
+
+ if (v -> oid_nelem > v2 -> oid_nelem
+ || bcmp ((char *) v -> oid_elements,
+ (char *) v2 -> oid_elements,
+ v -> oid_nelem
+ * sizeof v -> oid_elements[0])) {
+ *vpp = vp -> next;
+ vp -> next = NULL;
+ free_SNMP_VarBindList (vp);
+
+ *vpp2 = vp2 -> next;
+ vp2 -> next = NULL;
+ free_SNMP_VarBindList (vp2);
+ }
+ else
+ vpp = &vp -> next, vpp2 = &vp2 -> next;
+ }
+
+ if (vp == NULL && (vp2 = *vpp)) {
+ snmp_diag (NULLCP, "too many responses starting with: %s\n",
+ oid2ode (vp2 -> VarBind -> name));
+ return NOTOK;
+ }
+ }
+ if (vp) {
+ snmp_diag (NULLCP, "missing variable in response");
+ return NOTOK;
+ }
+
+ for (sp = s -> s_reqs; sp < sr; sp++) {
+ if (sp -> r_bindings)
+ free_SNMP_VarBindList (sp -> r_bindings);
+ if (sp -> r_pb)
+ pe_free (sp -> r_pb);
+
+ if (sp -> r_bindings
+ && sp -> r_msg -> data -> un.get__request
+ -> variable__bindings) {
+ sp -> r_bindings = sp -> r_msg -> data -> un.get__request
+ -> variable__bindings;
+ sp -> r_msg -> data -> un.get__request -> variable__bindings =NULL;
+
+ sp -> r_pb = sp -> r_pe, sp -> r_pe = NULL;
+
+ free_SNMP_Message (sp -> r_msg), sp -> r_msg = NULL;
+ continue;
+ }
+
+ if (sp -> r_msg)
+ free_SNMP_Message (sp -> r_msg);
+ if (sp -> r_pe)
+ pe_free (sp -> r_pe);
+
+ bzero ((char *) sp, sizeof *sp);
+ }
+
+ for (sr--; sr >= s -> s_reqs; sr--)
+ if (sr -> r_bindings)
+ for (sp = s -> s_reqs; sp < sr; sp++)
+ if (!sp -> r_bindings) {
+ *sp = *sr; /* struct copy */
+ bzero ((char *) sr, sizeof *sr);
+ break;
+ }
+
+ return OK;
+}
+
+/* \f */
+
+static int snmp_get_next_aux (s)
+register struct snmp_search *s;
+{
+ int gotone,
+ result,
+ retries,
+ status = -1;
+ struct type_SNMP_Message *msg;
+ register struct type_SNMP_PDU *parm;
+ struct type_SNMP_VarBindList *vp;
+ register struct snmp_req *sr;
+ PE p = NULLPE;
+
+ vp = msgs.data -> un.get__request -> variable__bindings;
+ msgs.data -> offset = type_SNMP_PDUs_get__next__request;
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++)
+ if ((result = req_ready (sr, 1)) == NOTOK)
+ break;
+ msgs.data -> un.get__request -> variable__bindings = vp;
+ msgs.data -> offset = type_SNMP_PDUs_get__request;
+
+ if (result == NOTOK) {
+ snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
+ return NOTOK;
+ }
+
+ msg = NULL, gotone = 0;
+ for (retries = snmp_retries; retries > 0; ) {
+ int len;
+ fd_set rfds;
+
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++) {
+ if (sr -> r_msg)
+ continue;
+
+ if (debug > 1)
+ print_SNMP_Message (sr -> r_pe, 1, NULLIP, NULLVP, NULLCP);
+ len = ps -> ps_byteno;
+ if (pe2ps (ps, sr -> r_pe) == NOTOK) {
+ snmp_diag (NULLCP, "pe2ps: %s", ps_error (ps -> ps_errno));
+ goto error_x;
+ }
+ if (debug > 0 && (len = ps -> ps_byteno - len) > 484)
+ fprintf (stderr, "sent message of %d octets\n", len);
+ }
+
+ FD_ZERO (&rfds);
+ FD_SET (snmp_fd, &rfds);
+
+ switch (xselect (snmp_fd + 1, &rfds, NULLFD, NULLFD, snmp_timeout)) {
+ case NOTOK:
+ snmp_diag ("failed", "xselect");
+ goto error_x;
+
+ default:
+ if (FD_ISSET (snmp_fd, &rfds))
+ break;
+ /* else fall... */
+ case OK:
+ retries--;
+ continue;
+ }
+
+again: ;
+ if ((p = ps2pe (ps)) == NULLPE) {
+ snmp_diag (NULLCP, "ps2pe: %s", ps_error (ps -> ps_errno));
+ goto error_x;
+ }
+ if (decode_SNMP_Message (p, 1, NULLIP, NULLVP, &msg) == NOTOK) {
+ snmp_diag (NULLCP, "decode_SNMP_Message: %s", PY_pepy);
+ goto out;
+ }
+ if (debug > 1)
+ print_SNMP_Message (p, 1, NULLIP, NULLVP, NULLCP);
+
+ if (msg -> data -> offset != type_SNMP_PDUs_get__response) {
+ snmp_diag (NULLCP, "unexpected message type %d",
+ msg -> data -> offset);
+ goto out;
+ }
+ gotone++;
+
+ parm = msg -> data -> un.get__response;
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++)
+ if (parm -> request__id == sr -> r_id)
+ break;
+ if (!sr -> r_bindings || sr -> r_msg) {
+ if (debug > 0)
+ fprintf (stderr, "%s response ID (got %ld)\n",
+ sr -> r_bindings ? "duplicate" : "unexpected",
+ (long) parm -> request__id);
+ if (msg)
+ free_SNMP_Message (msg), msg = NULL;
+ if (p)
+ pe_free (p), p = NULLPE;
+ goto check;
+ }
+
+ switch (status = parm -> error__status) {
+ case int_SNMP_error__status_noError:
+ break;
+
+ case int_SNMP_error__status_tooBig:
+ {
+ register int i;
+ register struct type_SNMP_VarBindList **vpp;
+ register struct snmp_req *sp;
+ struct snmp_req *sz = s -> s_reqs + NREQ;
+
+ i = 0;
+ for (vp = sr -> r_bindings; vp; vp = vp -> next)
+ i++;
+ if ((i >>= 1) < 1) {
+ snmp_diag (NULLCP,
+ "%s for request with single variable",
+ snmp_error (status));
+ goto out;
+ }
+ for (sp = sr + 1; sp -> r_bindings; sp++)
+ if (sp >= sz) {
+ snmp_diag (NULLCP,
+ "too many operations needed (%d max)",
+ NREQ - 1);
+ goto out;
+ }
+ for (sz = sr + 1; sp > sz; sp--)
+ *sp = *(sp - 1); /* struct copy */
+ bzero ((char *) sp, sizeof *sp);
+
+ for (vpp = &sr -> r_bindings;
+ i-- > 0;
+ vpp = &((*vpp) -> next))
+ continue;
+ sp -> r_bindings = *vpp, *vpp = NULL;
+
+ vp = msgs.data -> un.get__request -> variable__bindings;
+ msgs.data -> offset = type_SNMP_PDUs_get__next__request;
+ if ((result = req_ready (sr, 0)) != NOTOK)
+ result = req_ready (sp, 0);
+ msgs.data -> un.get__request -> variable__bindings = vp;
+ msgs.data -> offset = type_SNMP_PDUs_get__request;
+ if (result == NOTOK) {
+ snmp_diag (NULLCP, "encode_SNMP_Message: %s", PY_pepy);
+ goto out;
+ }
+
+ retries = snmp_retries;
+ goto check;
+ }
+ break;
+
+ default:
+ {
+ char *cp = snmp_variable (parm, parm -> error__index);
+
+ snmp_diag (NULLCP, cp ? "%s at position %d (%s)"
+ : "%s at position %d",
+ snmp_error (status), parm -> error__index, cp);
+ }
+ goto out;
+ }
+
+ pe_free (sr -> r_pe);
+ sr -> r_pe = p, p = NULLPE;
+
+ sr -> r_msg = msg, msg = NULL;
+
+ for (sr = s -> s_reqs; sr -> r_bindings; sr++)
+ if (!sr -> r_msg)
+ break;
+ if (!sr -> r_bindings) {
+ assign_number (&ERROR_node -> var_value, (AWKNUM) status);
+
+ return OK;
+ }
+
+check: ;
+ FD_ZERO (&rfds);
+ FD_SET (snmp_fd, &rfds);
+
+ if (select_dgram_socket (snmp_fd + 1, &rfds, NULLFD, NULLFD, 1) > OK)
+ goto again;
+ }
+ snmp_diag (NULLCP,
+ "no %sresponse within %d retries of %s%d second%s each",
+ gotone ? "acceptable " : "", snmp_retries + gotone,
+ gotone ? "up to " : "", snmp_timeout,
+ snmp_timeout != 1 ? "s" : "");
+ return NOTOK;
+
+error_x: ;
+ if (ps)
+ ps_free (ps), ps = NULLPS;
+ if (snmp_fd != NOTOK)
+ (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
+
+out: ;
+ if (p)
+ pe_free (p);
+
+ return NOTOK;
+}
+
+/* \f */
+
+static int req_ready (sr, do_val)
+register struct snmp_req *sr;
+int do_val;
+{
+ register struct type_SNMP_Message *msg = &msgs;
+ register struct type_SNMP_PDU *parm = msg -> data -> un.get__request;
+
+ if (do_val) {
+ register struct type_SNMP_VarBindList *vp;
+
+ for (vp = sr -> r_bindings; vp; vp = vp -> next) {
+ register struct type_SNMP_VarBind *v = vp -> VarBind;
+
+ if (v -> value)
+ pe_free (v -> value);
+ if ((v -> value = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM,
+ PE_PRIM_NULL)) == NULLPE)
+ fatal ("pe_alloc: out of memory");
+ }
+ }
+
+ if (snmp_id >= 0x7fffffff)
+ snmp_id = 0;
+ snmp_id++;
+
+ parm -> request__id = sr -> r_id = snmp_id;
+ parm -> variable__bindings = sr -> r_bindings;
+
+ if (sr -> r_msg)
+ free_SNMP_Message (sr -> r_msg), sr -> r_msg = NULL;
+ if (sr -> r_pe)
+ pe_free (sr -> r_pe), sr -> r_pe = NULL;
+
+ return encode_SNMP_Message (&sr -> r_pe, 1, 0, NULLCP, &msgs);
+}
+
+/* \f DECODE */
+
+static NODE *make_octet_node (base, len)
+char *base;
+int len;
+{
+ register char *bp,
+ *cp,
+ *ep;
+ char *s = "";
+ register NODE *r;
+
+ r = newnode (Node_val);
+ emalloc (r -> stptr, char *, len * 3 + 1, "make_octet_node");
+ bp = r -> stptr;
+ for (ep = (cp = base) + len; cp < ep; cp++, s = ":") {
+ (void) sprintf (bp, "%s%02x", s, *cp & 0xff);
+ bp += strlen (bp);
+ }
+ *bp = NULL; /* in case len == 0 */
+ r -> stlen = bp - r -> stptr;
+ r -> stref = 1;
+ r -> flags |= STR | MALLOC;
+
+ return r;
+}
+
+
+static int f_integer (x, pe)
+NODE **x;
+PE pe;
+{
+ integer i = prim2num (pe);
+
+ if (i == NOTOK && pe -> pe_errno != PE_ERR_NONE) {
+ (void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
+ return NOTOK;
+ }
+
+ *x = make_number ((AWKNUM) i);
+
+ return OK;
+}
+
+
+static int f_octets (x, pe)
+NODE **x;
+PE pe;
+{
+ struct qbuf *qb = prim2qb (pe);
+
+ if (qb == NULL || qb_pullup (qb) == NOTOK) {
+ (void) strcpy (PY_pepy, qb ? "qb_pullup: out of memory"
+ : pe_error (pe -> pe_errno));
+ return NOTOK;
+ }
+
+ *x = make_octet_node (qb -> qb_forw -> qb_data, qb -> qb_forw -> qb_len);
+
+ qb_free (qb);
+
+ return OK;
+}
+
+
+static int f_display (x, pe)
+NODE **x;
+PE pe;
+{
+ struct qbuf *qb = prim2qb (pe);
+
+ if (qb == NULL || qb_pullup (qb) == NOTOK) {
+ (void) strcpy (PY_pepy, qb ? "qb_pullup: out of memory"
+ : pe_error (pe -> pe_errno));
+ return NOTOK;
+ }
+
+ *x = make_string (qb -> qb_forw -> qb_data, qb -> qb_forw -> qb_len);
+
+ qb_free (qb);
+
+ return OK;
+}
+
+
+static int f_objectID (x, pe)
+NODE **x;
+PE pe;
+{
+ char *cp;
+ OID oid = prim2oid (pe);
+
+ if (oid == NULLOID) {
+ (void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
+ return NOTOK;
+ }
+ cp = sprintoid (oid);
+
+ *x = make_string (cp, strlen (cp));
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int f_null (x, pe)
+NODE **x;
+PE pe;
+{
+ *x = make_str_node ("NULL", 4, 0);
+
+ return OK;
+}
+
+
+static int f_ipaddr (x, pe)
+NODE **x;
+PE pe;
+{
+ char ipaddr[16];
+ struct type_SNMP_IpAddress *ip;
+ struct qbuf *qb;
+
+ if (decode_SNMP_IpAddress (pe, 1, NULLIP, NULLVP, &ip) == NOTOK)
+ return NOTOK;
+ if (qb_pullup (ip) == NOTOK) {
+ (void) strcpy (PY_pepy, "qb_pullup: out of memory");
+ free_SNMP_IpAddress (ip);
+ return NOTOK;
+ }
+ if ((qb = ip -> qb_forw) -> qb_len != 4) {
+ (void) sprintf (PY_pepy,
+ "IpAddress is wrong length (got %d, wanted 4)",
+ qb -> qb_len);
+ free_SNMP_IpAddress (ip);
+ return NOTOK;
+ }
+ (void) sprintf (ipaddr, "%d.%d.%d.%d",
+ qb -> qb_data[0] & 0xff, qb -> qb_data[1] & 0xff,
+ qb -> qb_data[2] & 0xff, qb -> qb_data[3] & 0xff);
+
+ *x = make_str_node (ipaddr, strlen (ipaddr), 0);
+
+ free_SNMP_IpAddress (ip);
+
+ return OK;
+}
+
+
+extern u_long prim2ulong ();
+
+static int f_ulong (x, pe)
+NODE **x;
+PE pe;
+{
+ u_long i = prim2ulong (pe);
+
+ if (i == 0 && pe -> pe_errno != PE_ERR_NONE) {
+ (void) strcpy (PY_pepy, pe_error (pe -> pe_errno));
+ return NOTOK;
+ }
+
+ *x = make_number ((AWKNUM) i);
+
+ return OK;
+}
+
+
+static int f_clnpaddr (x, pe)
+NODE **x;
+PE pe;
+{
+ int len;
+ struct type_SNMP_ClnpAddress *clnp;
+ struct qbuf *qb;
+
+ if (decode_SNMP_ClnpAddress (pe, 1, NULLIP, NULLVP, &clnp) == NOTOK)
+ return NOTOK;
+ if (qb_pullup (clnp) == NOTOK) {
+ (void) strcpy (PY_pepy, "qb_pullup: out of memory");
+ free_SNMP_ClnpAddress (clnp);
+ return NOTOK;
+ }
+ qb = clnp -> qb_forw;
+ if ((len = qb -> qb_data[0] & 0xff) >= qb -> qb_len)
+ len = qb -> qb_len - 1;
+
+ *x = make_octet_node (qb -> qb_data + 1, len);
+
+ free_SNMP_ClnpAddress (clnp);
+
+ return OK;
+}
+
+/* \f MISC */
+
+static snmp_ready (do_id)
+int do_id;
+{
+ int changed = 0;
+ char *pp;
+ struct sockaddr_in lo_socket;
+ register struct sockaddr_in *lsock = &lo_socket;
+ register struct sockaddr_in *isock = &in_socket;
+ register struct hostent *hp;
+ register struct servent *sp;
+ register NODE *tmp;
+
+ deref = DIAGNOSTIC_node -> var_value;
+ do_deref ();
+
+ DIAGNOSTIC_node -> var_value = Nnull_string;
+
+ if ((snmp_retries = (int) RETRIES_node -> var_value -> numbr) <= 0)
+ snmp_retries = 1;
+ if ((snmp_timeout = (int) TIMEOUT_node -> var_value -> numbr) <= 0)
+ snmp_timeout = 1;
+
+ if (do_id) {
+ if (snmp_id >= 0x7fffffff)
+ snmp_id = 0;
+ snmp_id++;
+ }
+
+ if (snmp_fd == NOTOK || ps == NULLPS)
+ changed++;
+
+ tmp = force_string (AGENT_node -> var_value);
+ if (snmp_agent == NULL || strcmp (snmp_agent, tmp -> stptr)) {
+ if (snmp_agent)
+ free (snmp_agent), snmp_agent = NULL;
+
+ emalloc (snmp_agent, char *, strlen (tmp -> stptr) + 1, "snmp_ready1");
+ (void) strcpy (snmp_agent, tmp -> stptr);
+
+ changed++;
+ }
+
+ tmp = force_string (COMMUNITY_node -> var_value);
+ if (snmp_community == NULL || strcmp (snmp_community, tmp -> stptr)) {
+ register struct type_SNMP_Message *msg = &msgs;
+
+ if (snmp_community)
+ free (snmp_community), snmp_community = NULL;
+
+ emalloc (snmp_community, char *, strlen (tmp -> stptr) + 1,
+ "snmp_ready2");
+ (void) strcpy (snmp_community, tmp -> stptr);
+ if ((msg -> community = str2qb (snmp_community,
+ strlen (snmp_community), 1)) == NULL) {
+ snmp_diag (NULLCP, "str2qb: out of memory");
+ free (snmp_community), snmp_community = NULL;
+ return NOTOK;
+ }
+ }
+
+ if (changed) {
+ if (ps)
+ ps_free (ps), ps = NULLPS;
+ if (snmp_fd != NOTOK)
+ (void) close_udp_socket (snmp_fd), snmp_fd = NOTOK;
+ }
+ else
+ return OK;
+
+ bzero ((char *) lsock, sizeof *lsock);
+ if ((hp = gethostbystring (pp = strcmp (snmp_agent, "localhost")
+ ? getlocalhost () : "localhost"))
+ == NULL) {
+ snmp_diag (NULLCP, "%s: unknown host", pp);
+ return NOTOK;
+ }
+ lsock -> sin_family = hp -> h_addrtype;
+ inaddr_copy (hp, lsock);
+ if ((snmp_fd = start_udp_client (lsock, 0, 0, 0)) == NOTOK) {
+ snmp_diag ("failed", "start_udp_server");
+ return NOTOK;
+ }
+
+ if ((hp = gethostbystring (pp = snmp_agent)) == NULL) {
+ struct TSAPaddr *ta;
+ struct NSAPaddr *na;
+
+ if ((ta = str2taddr (snmp_agent))
+ && ta -> ta_naddr > 0
+ && (na = ta -> ta_addrs) -> na_stack == NA_TCP) {
+ snmp_portno = na -> na_port;
+
+ if (hp = gethostbystring (pp = na -> na_domain))
+ goto got_host;
+ }
+
+ snmp_diag (NULLCP, "%s: unknown host", pp);
+ return NOTOK;
+ }
+got_host: ;
+ if (snmp_portno == 0)
+ snmp_portno = (sp = getservbyname ("snmp", "udp"))
+ ? sp -> s_port
+ : htons ((u_short) 161);
+
+ bzero ((char *) isock, sizeof *isock);
+ isock -> sin_family = hp -> h_addrtype;
+ inaddr_copy (hp, isock);
+ isock -> sin_port = snmp_portno;
+
+ if (*snmp_community == '/' && snmp_map (isock) == NOTOK)
+ return NOTOK;
+
+ if (join_udp_server (snmp_fd, isock) == NOTOK) {
+ snmp_diag ("failed", "join_udp_server");
+ return NOTOK;
+ }
+
+ if ((ps = ps_alloc (dg_open)) == NULLPS
+ || dg_setup (ps, snmp_fd, MAXDGRAM, read_udp_socket,
+ write_udp_socket, check_udp_socket) == NOTOK) {
+ if (ps == NULLPS)
+ snmp_diag (NULLCP, "ps_alloc: out of memory");
+ else
+ snmp_diag (NULLCP, "dg_setup: %s", ps_error (ps -> ps_errno));
+
+ return NOTOK;
+ }
+
+#ifndef SYS5
+ snmp_id = ((int) random ()) & 0x7fffffff;
+#else
+ snmp_id = ((int) rand ()) & 0x7fffffff;
+#endif
+
+ return OK;
+}
+
+/* \f */
+
+/* Reads an IP address to community mapping file. Use UNIX modes for
+ protection of information therein...
+
+ Syntax:
+
+ <netaddr> [<netmask>] <community>
+
+ Each token is seperated by LWSP, though double-quotes may be used to
+ prevent separation.
+
+ */
+
+static snmp_map (isock)
+struct sockaddr_in *isock;
+{
+ int result = NOTOK;
+ u_long hostaddr,
+ netmask,
+ netaddr;
+ register char *cp;
+ char buffer[BUFSIZ + 1],
+ *vec[NVEC + 1];
+ FILE *fp;
+
+ if ((fp = fopen (snmp_community, "r")) == NULL) {
+ snmp_diag (snmp_community, "unable to read");
+ return NOTOK;
+ }
+
+ hostaddr = isock -> sin_addr.s_addr;
+
+ while (fgets (buffer, sizeof buffer, fp)) {
+ if (*buffer == '#')
+ continue;
+ if (cp = index (buffer, '\n'))
+ *cp = NULL;
+ bzero ((char *) vec, sizeof vec);
+ switch (str2vec (buffer, vec)) {
+ case 3:
+ netmask = inet_addr (vec[1]);
+ cp = vec[2];
+ break;
+
+ case 2:
+ netmask = 0xffffffff;
+ cp = vec[1];
+ break;
+
+ default:
+ continue;
+ }
+ if ((netaddr = inet_network (vec[0])) == NOTOK)
+ continue;
+ netaddr = ntohl (netaddr);
+ if (!(netaddr & 0xff000000))
+ netaddr <<= (netaddr & 0x00ff0000) ? 8
+ : (netaddr & 0x0000ff00) ? 16
+ : 24;
+ netaddr = htonl (netaddr);
+ if ((hostaddr & netmask) != netaddr)
+ continue;
+
+ if ((msgs.community = str2qb (cp, strlen (cp), 1)) == NULL) {
+ snmp_diag (NULLCP, "str2qb: out of memory");
+ goto done;
+ }
+
+ result = OK;
+ break;
+ }
+ if (result == NOTOK)
+ snmp_diag (NULLCP, "no match for IP-address in %s", snmp_community);
+
+done: ;
+ (void) fclose (fp);
+
+ return result;
+}
+
+/* \f */
+
+#ifndef lint
+static snmp_diag (va_alist)
+va_dcl
+{
+ char *what,
+ buffer[BUFSIZ];
+ va_list ap;
+
+ va_start (ap);
+
+ what = va_arg (ap, char *);
+
+ _asprintf (buffer, what, ap);
+
+ va_end (ap);
+
+ if (debug > 0)
+ fprintf (stderr, "%s\n", buffer);
+
+ deref = DIAGNOSTIC_node -> var_value;
+ do_deref ();
+
+ DIAGNOSTIC_node -> var_value = make_string (buffer, strlen (buffer));
+}
+#else
+/* VARARGS */
+
+static snmp_diag (what, fmt)
+char *what,
+ *fmt;
+{
+ snmp_diag (what, fmt);
+}
+#endif
+
+/* \f */
+
+char *snmp_name (ptr)
+NODE *ptr;
+{
+ return ((OT) (ptr -> magic)) -> ot_text;
+}
+
+/* \f */
+
+static char *errors[] = {
+ "noError", "tooBig", "noSuchName", "badValue", "readOnly", "genErr"
+};
+
+
+static char *snmp_error (i)
+int i;
+{
+ static char buffer[BUFSIZ];
+
+ if (0 < i && i < sizeof errors / sizeof errors[0])
+ return errors[i];
+ (void) sprintf (buffer, "error %d", i);
+
+ return buffer;
+}
+
+
+static char *snmp_variable (parm, idx)
+register struct type_SNMP_PDU *parm;
+int idx;
+{
+ register struct type_SNMP_VarBindList *vp;
+
+ if (idx <= 0 || (vp = parm -> variable__bindings) == NULL)
+ return NULL;
+ for (idx--; idx > 0; idx--)
+ if ((vp = vp -> next) == NULL)
+ return NULL;
+
+ return oid2ode (vp -> VarBind -> name);
+}
+#endif /* SNMP */
--- /dev/null
+###############################################################################
+#
+# snmpd.peers - SNMP configuration for SMUX peers
+#
+# $Header: /f/osi/snmp/RCS/snmpd.peers,v 7.3 91/02/22 09:44:29 mrose Interim $
+#
+# Contributed by NYSERNet Inc. This work was partially supported by the
+# U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+# Center of the U.S. Air Force Systems Command under contract number
+# F30602-88-C-0016.
+#
+#
+# $Log: snmpd.peers,v $
+# Revision 7.3 91/02/22 09:44:29 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/07/09 14:49:31 mrose
+# sync
+#
+# Revision 7.1 90/02/19 15:39:04 mrose
+# one more time
+#
+# Revision 7.0 90/02/17 10:40:24 mrose
+# *** empty log message ***
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+# <name> <object id> <password> [<priority>]
+#
+# Each token is seperated by LWSP, though double-quotes may be
+# used to prevent separation
+#
+###############################################################################
+
+
+###############################################################################
+# SMUX peers standard to 4BSD/ISODE
+###############################################################################
+
+"unixd" 1.3.6.1.4.1.4.3.1.1 "noBigDeal"
+
+
+###############################################################################
+# locally defined SMUX peers
+###############################################################################
+
+
--- /dev/null
+###############################################################################
+#
+# snmpd.rc - SNMP configuration information
+#
+# $Header: /f/osi/snmp/RCS/snmpd.rc,v 7.15 91/02/22 09:44:31 mrose Interim $
+#
+# Contributed by NYSERNet Inc. This work was partially supported by the
+# U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+# Center of the U.S. Air Force Systems Command under contract number
+# F30602-88-C-0016.
+#
+#
+# $Log: snmpd.rc,v $
+# Revision 7.15 91/02/22 09:44:31 mrose
+# Interim 6.8
+#
+# Revision 7.14 91/01/11 15:35:26 mrose
+# sets
+#
+# Revision 7.13 90/10/17 14:33:20 mrose
+# update
+#
+# Revision 7.12 90/06/20 20:38:38 mrose
+# ho hum
+#
+# Revision 7.11 90/06/13 17:46:24 mrose
+# touch-up
+#
+# Revision 7.10 90/06/12 02:05:49 mrose
+# views ...
+#
+# Revision 7.9 90/05/14 16:27:35 mrose
+# again
+#
+# Revision 7.8 90/05/14 13:28:19 mrose
+# system
+#
+# Revision 7.7 90/05/13 17:54:55 mrose
+# views again
+#
+# Revision 7.6 90/05/13 16:18:30 mrose
+# views
+#
+# Revision 7.5 90/03/27 07:39:58 mrose
+# touch-up
+#
+# Revision 7.4 90/03/05 23:04:23 mrose
+# touch-up
+#
+# Revision 7.3 90/02/19 15:39:06 mrose
+# one more time
+#
+# Revision 7.2 90/01/11 18:34:39 mrose
+# real-sync
+#
+# Revision 7.1 89/12/08 22:49:52 mrose
+# touch-up
+#
+# Revision 7.0 89/11/23 22:23:28 mrose
+# Release 6.0
+#
+###############################################################################
+
+###############################################################################
+#
+# How to configure this file for your system:
+#
+# 1. Fill-in the value for "sysContact" and "sysLocation" below, e.g.,
+#
+# variable sysContact "Marshall Rose <mrose@psi.com>"
+#
+# variable sysLocation "upstairs machine room"
+#
+# All the other objects in the system group are automatically filled-in by
+# the agent.
+#
+# 2. If your site has a management station that listens for traps, fill-in
+# the information for the trap sink, e.g.,
+#
+# trap traps a.b.c.d
+#
+# where "traps" is the community that the traps should be logged under and
+# a.b.c.d is the IP-address of the host where a trap sink is listening on
+# UDP port 162.
+#
+# 3. Make sure that all of the network interfaces are listed below. If you
+# have a strange interface name, define it accordingly, e.g.,
+#
+# variable interface NAME ifType=XX ifSpeed=YY
+#
+# where "NAME" is the interface name according to ifconfig(8c), "XX" is
+# the type of interface according to the MIB (look at the definition of
+# the ifType variable), and "YY" is the speed in bits/second.
+#
+###############################################################################
+
+community secret 0.0.0.0 readWrite 1.17.2
+community public
+
+community system 0.0.0.0 readOnly 1.17.2
+view 1.17.2 system unix
+
+logging file=snmpd.log size=50
+logging slevel=fatal slevel=exceptions slevel=notice
+logging sflags=close sflags=create sflags=zero
+
+#variable sysContact "Marshall Rose <mrose@psi.com>"
+#variable sysLocation "northside machine room, PSI Santa Clara Office"
+
+# replace a.b.c.d with real IP-address
+# trap traps a.b.c.d
+
+variable interface lo0 ifType=24 ifSpeed=0
+
+# here are all the ethernet names I know about...
+variable interface ace0 ifType=6
+variable interface de0 ifType=6
+variable interface ec0 ifType=6
+variable interface ei0 ifType=6
+variable interface en0 ifType=6
+variable interface enp0 ifType=6
+variable interface ex0 ifType=6
+variable interface ie0 ifType=6
+variable interface il0 ifType=6
+variable interface ix0 ifType=6
+variable interface le0 ifType=6
+variable interface qe0 ifType=6
+variable interface se0 ifType=6
+variable interface ln0 ifType=6
+
+# and slip...
+variable interface sl0 ifType=22
+variable interface sl1 ifType=22
+variable interface sl2 ifType=22
+variable interface sl3 ifType=22
+
+# and miscellany...
+variable interface ddn0 ifType=4
+variable interface dmc0 ifType=22
+variable interface dmv0 ifType=22
+variable interface hy0 ifType=14
+#could be proteon-80MBit
+#variable interface vv0 ifType=12
--- /dev/null
+.TH SNMPI 1C "14 Sep 1989"
+.\" $Header: /f/osi/snmp/RCS/snmpi.1c,v 7.6 91/02/22 09:44:32 mrose Interim $
+.\"
+.\" Contributed by NYSERNet Inc. This work was partially supported by the
+.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+.\" Center of the U.S. Air Force Systems Command under contract number
+.\" F30602-88-C-0016.
+.\"
+.\"
+.\" $Log: snmpi.1c,v $
+.\" Revision 7.6 91/02/22 09:44:32 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.5 90/10/18 11:34:09 mrose
+.\" psi
+.\"
+.\" Revision 7.4 90/08/29 15:04:14 mrose
+.\" doc
+.\"
+.\" Revision 7.3 90/05/13 15:55:57 mrose
+.\" update
+.\"
+.\" Revision 7.2 90/02/19 19:17:03 mrose
+.\" again
+.\"
+.\" Revision 7.1 90/01/11 18:34:41 mrose
+.\" real-sync
+.\"
+.\" Revision 7.0 89/11/23 22:23:29 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+snmpi \- really minimal SNMP initiator
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B snmpi
+\%[-a\0agent]
+\%[-c\0community]
+\%[-f\0file]
+\%[-p\0portno]
+\%[-d]
+\%[-v]
+\%[-w]
+.in -.5i
+.SH DESCRIPTION
+The \fIsnmpi\fR program is an extremely simple program,
+used to test \fIsnmpd\fR.
+Once \fIsnmpd\fR is started,
+to see if it's running,
+do:
+.sp
+.in +.5i
+.nf
+% snmpi dump
+.fi
+.in -.5i
+.sp
+This should generate voluminous output.
+.SH OPTIONS
+The `-a' switch sets the address of the SNMP agent.
+Either a hostname, an IP-address, or a transport address (using
+Kille's string syntax) may be used.
+The default is the localhost.
+Similarly,
+the `-p' switch sets the UDP port number that the agent resides on
+(if an IP-style address is given, obviously).
+The default is UDP port 161.
+.PP
+The `-c' switch sets the community name for the SNMP request.
+The default is public.
+.PP
+The `-d' switch enables debugging.
+This doesn't do anything yet.
+.PP
+The `-f' switch selects a file containing compiled MIB module definitions.
+The default is \fIobjects.defs\fR.
+.PP
+The `-w' switch enables watching.
+When SNMP messages are exchanged,
+they will be pretty-printed on the terminal if the user is watching.
+.PP
+The `-v' switch enables verbose interaction.
+This doesn't do anything yet.
+.SH FILES
+.nf
+.ta \w'\*(EDobjects.defs 'u
+\*(EDobjects.defs MIB definitions
+.re
+.fi
+.SH "NOTE WELL"
+The names of the objects in \fBobjects.defs\fR are case sensitive.
+This was necessary to improve the efficiency of the hashing algorithm
+used for object lookup.
+.SH "SEE ALSO"
+RFCs 1155, 1156, and 1157.
+.PP
+S.E.\0Kille,
+\fIA string encoding of Presentation Address\fR,
+Research Note RN/89/14,
+Department of Computer Science,
+University College London,
+(February, 1989).
+.SH AUTHOR
+Marshall T. Rose,
+Performance Systems International
+.PP
+This work was partially supported by the
+U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+Center of the U.S. Air Force Systems Command under contract number
+F30602-88-C-0016.
+.PP
+Although this package is distributed with the ISODE,
+it is not an OSI program, per se.
+Inasmuch as the continued survival of the Internet hinges on all nodes
+becoming network manageable,
+this package was developed using the ISODE and is being freely
+distributed with releases of Berkeley UNIX.
+.PP
+It must be stressed that this package is not a complete network management
+system.
+In particular,
+whilst \fIsnmpd\fR provides a minimal agent functionality,
+there are no Network Operation Center (NOC) tools--\fIsnmpi\fR is a
+debugging aid only.
--- /dev/null
+.TH SNMPT 8c "21 Jun 1990"
+.\" $Header: /f/osi/snmp/RCS/snmpt.8c,v 7.3 91/02/22 09:44:37 mrose Interim $
+.\"
+.\" Contributed by NYSERNet Inc. This work was partially supported by the
+.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+.\" Center of the U.S. Air Force Systems Command under contract number
+.\" F30602-88-C-0016.
+.\"
+.\"
+.\" $Log: snmpt.8c,v $
+.\" Revision 7.3 91/02/22 09:44:37 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.2 90/08/29 15:04:15 mrose
+.\" doc
+.\"
+.\" Revision 7.1 90/06/23 17:02:01 mrose
+.\" update
+.\"
+.\" Revision 7.0 90/06/21 20:35:54 mrose
+.\" *** empty log message ***
+.\"
+.SH NAME
+snmpt \- SNMP trap sink
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDsnmpt
+\%[\-t] \%[\-x] \%[\-z]
+\%[-p portno]
+\%[\-a x121address] \%[\-i\ pid]
+\%[\-f\ audit-file]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIsnmpt\fR server acts as a trap sink.
+Unon receipt of a message,
+it simply logs it to an audit-file.
+.SH TRANSPORTS
+For a UDP\-based network service,
+the server listens on port 162 for SNMP messages.
+The `\-p' option overrides the default UDP port.
+.PP
+For an X.25\-based network service,
+the server implements the transport class 0 protocol,
+decodes the connection request packet,
+and execs the appropriate program to enter the protocol and provide the
+service.
+The `\-a' switch is used to specify the X.121 address of the local host
+\(em this overrides the entry in the \fBisotailor\fP file.
+In addition,
+the `\-i' switch is used to specify the protocol ID to listen on
+\(em the default is 03019000.
+Note that on most X.25 implementations,
+if the local X.121 address is not present in the \fBisotailor\fR file,
+then the `-a' switch must be used in order for the server to
+receive incoming calls.
+.PP
+For a TP4\-based transport service,
+the server simply listens to any incoming connections for selector
+\*(lqsnmp-trap\*(rq.
+.PP
+By default,
+all network services are enabled
+(if defined in the configuration).
+The `\-t' option specifies TCP\-only operation,
+the `\-x' option specifies X.25\-only operation,
+and the `\-z' option specifies TP4\-only operation.
+.SH "DEBUG OPERATION"
+If \fIsnmpt\fR is started interactively,
+or if the `\-d' switch is given,
+then debug mode is entered.
+In this case,
+all logging activity is displayed on the user's terminal.
+In addition,
+the logging information is more verbose.
+.SH FILES
+.nf
+.ta \w'\*(LDsnmp.traps 'u
+\*(LDsnmpt.log log file
+\*(LDsnmp.traps trap file
+/etc/snmpt.pid daemon PID file
+.re
+.fi
+.SH "SEE ALSO"
+RFCs 1155, 1156, and 1157.
+.SH AUTHOR
+Marshall T. Rose,
+PSI Inc.
+This work was partially supported by the
+U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+Center of the U.S. Air Force Systems Command under contract number
+F30602-88-C-0016.
+.PP
+Although this package is distributed with the ISODE,
+it is not an OSI program, per se.
+Inasmuch as the continued survival of the Internet hinges on all nodes
+becoming network manageable,
+this package was developed using the ISODE and is being freely
+distributed with releases of Berkeley UNIX.
+.PP
+It must be stressed that this package is not a complete network management
+system.
+In particular,
+whilst \fIsnmpd\fR provides a minimal agent functionality,
+there are no Network Operation Center (NOC) tools--\fIsnmpi\fR is a
+debugging aid only.
--- /dev/null
+/* syntax.c - SMI syntax handling */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/syntax.c,v 7.19 91/02/22 09:44:38 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/RCS/syntax.c,v 7.19 91/02/22 09:44:38 mrose Interim $
+ *
+ * Contributed by NYSERNet Inc. This work was partially supported by the
+ * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+ * Center of the U.S. Air Force Systems Command under contract number
+ * F30602-88-C-0016.
+ *
+ *
+ * $Log: syntax.c,v $
+ * Revision 7.19 91/02/22 09:44:38 mrose
+ * Interim 6.8
+ *
+ * Revision 7.18 91/01/13 11:05:45 mrose
+ * update
+ *
+ * Revision 7.17 91/01/12 21:22:58 mrose
+ * update
+ *
+ * Revision 7.16 91/01/11 15:35:36 mrose
+ * sets
+ *
+ * Revision 7.15 90/12/18 10:14:07 mrose
+ * update
+ *
+ * Revision 7.14 90/11/20 15:32:55 mrose
+ * update
+ *
+ * Revision 7.13 90/11/04 19:16:36 mrose
+ * update
+ *
+ * Revision 7.12 90/10/29 18:39:12 mrose
+ * updates
+ *
+ * Revision 7.11 90/10/23 20:37:17 mrose
+ * update
+ *
+ * Revision 7.10 90/08/18 00:44:42 mrose
+ * touch-up
+ *
+ * Revision 7.9 90/08/08 14:01:39 mrose
+ * stuff
+ *
+ * Revision 7.8 90/07/09 14:49:41 mrose
+ * sync
+ *
+ * Revision 7.7 90/04/18 08:52:03 mrose
+ * oid_normalize
+ *
+ * Revision 7.6 90/04/08 03:23:20 mrose
+ * touch-up
+ *
+ * Revision 7.5 90/03/23 17:27:35 mrose
+ * update
+ *
+ * Revision 7.4 90/03/08 08:05:25 mrose
+ * touch-up
+ *
+ * Revision 7.3 90/02/19 19:23:14 mrose
+ * again
+ *
+ * Revision 7.2 90/02/19 19:17:11 mrose
+ * again
+ *
+ * Revision 7.1 90/01/11 18:34:48 mrose
+ * real-sync
+ *
+ * Revision 7.0 89/11/23 22:23:32 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <ctype.h>
+#include <stdio.h>
+#include "SNMP-types.h"
+#include "objects.h"
+#include "tailor.h"
+
+#include "internet.h"
+#include "clns.h"
+
+/* \f DATA */
+
+#define MAXSYN 50
+
+static object_syntax syntaxes[MAXSYN + 1];
+static OS synlast = syntaxes;
+
+/* \f INTEGER */
+
+static int integer_encode (x, pe)
+integer *x;
+PE *pe;
+{
+ if ((*pe = int2prim (*x)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int integer_decode (x, pe)
+integer **x;
+PE pe;
+{
+ integer i = prim2num (pe);
+
+ if (i == NOTOK && pe -> pe_errno != PE_ERR_NONE)
+ return NOTOK;
+ if ((*x = (integer *) malloc (sizeof **x)) == NULL)
+ return NOTOK;
+ **x = i;
+
+ return OK;
+}
+
+
+static int integer_free (x)
+integer *x;
+{
+ free ((char *) x);
+}
+
+
+static int integer_parse (x, s)
+integer **x;
+char *s;
+{
+ long l;
+
+ if (sscanf (s, "%ld", &l) != 1)
+ return NOTOK;
+ if ((*x = (integer *) malloc (sizeof **x)) == NULL)
+ return NOTOK;
+ **x = (integer) l;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int integer_print (x, os)
+integer *x;
+OS os;
+{
+ printf ("%d", *x);
+}
+
+
+/* ARGSUSED */
+
+static int services_print (x, os)
+integer *x;
+OS os;
+{
+ printf ("%s", sprintb ((int) *x,
+ "\020\01physical\02datalink/subnetwork\03internet\04transport\05session\06presentation\07application"));
+}
+
+
+/* ARGSUSED */
+
+static int privs_print (x, os)
+integer *x;
+OS os;
+{
+ printf ("%s", sprintb ((int) *x,
+ "\020\01get\02get-next\03get-response\04set\05trap"));
+}
+
+
+static add_integer ()
+{
+ (void) add_syntax ("INTEGER", integer_encode, integer_decode, integer_free,
+ integer_parse, integer_print);
+ (void) add_syntax ("Services", integer_encode, integer_decode,
+ integer_free, integer_parse, services_print);
+ (void) add_syntax ("Privileges", integer_encode, integer_decode,
+ integer_free, integer_parse, privs_print);
+}
+
+/* \f OCTET STRING */
+
+static int string_encode (x, pe)
+struct qbuf *x;
+PE *pe;
+{
+ if ((*pe = qb2prim_aux (x, PE_CLASS_UNIV, PE_PRIM_OCTS, 0)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int string_decode (x, pe)
+struct qbuf **x;
+PE pe;
+{
+ struct qbuf *qb = prim2qb (pe);
+
+ if (qb == NULL)
+ return NOTOK;
+ *x = qb;
+
+ return OK;
+}
+
+
+static int string_parse (x, s)
+struct qbuf **x;
+char *s;
+{
+ struct qbuf *qb;
+
+ if (strncmp (s, "0x", 2) == 0) {
+ int len;
+ char *p;
+
+ s += 2;
+ if ((len = strlen (s)) % 3 != 2)
+ return NOTOK;
+ len /= 3, len++;
+ if ((qb = str2qb (NULLCP, len, 1)) == NULL)
+ return NOTOK;
+ p = qb -> qb_forw -> qb_data;
+ while (*s) {
+ int i;
+
+ if (sscanf (s, "%x", &i) != 1) {
+oops: ;
+ qb_free (qb);
+ return NOTOK;
+ }
+ *p++ = i & 0xff;
+
+ s += 2;
+ if (*s && *s++ != ':')
+ goto oops;
+ }
+ }
+ else
+ if ((qb = str2qb (s, strlen (s), 1)) == NULL)
+ return NOTOK;
+
+ *x = qb;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int string_print (x, os)
+struct qbuf *x;
+OS os;
+{
+ register char *cp,
+ *ep;
+ char *p;
+ register struct qbuf *qb;
+
+ p = "0x";
+ for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw)
+ for (ep = (cp = qb -> qb_data) + qb -> qb_len; cp < ep; cp++) {
+ printf ("%s%02x", p, *cp & 0xff);
+ p = ":";
+ }
+}
+
+
+/* ARGSUSED */
+
+static int string_display (x, os)
+struct qbuf *x;
+OS os;
+{
+ register struct qbuf *qb;
+
+ printf ("\"");
+ for (qb = x -> qb_forw; qb != x; qb = qb -> qb_forw)
+ printf ("%*.*s", qb -> qb_len, qb -> qb_len, qb -> qb_data);
+ printf ("\"");
+}
+
+
+static add_string ()
+{
+ (void) add_syntax ("OctetString", string_encode, string_decode, qb_free,
+ string_parse, string_print);
+ (void) add_syntax ("DisplayString", string_encode, string_decode, qb_free,
+ string_parse, string_display);
+ (void) add_syntax ("PhysAddress", string_encode, string_decode, qb_free,
+ string_parse, string_print);
+}
+
+/* \f OBJECT IDENTIFIER */
+
+static int object_encode (x, pe)
+OID x;
+PE *pe;
+{
+ if ((*pe = oid2prim (x)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int object_decode (x, pe)
+OID *x;
+PE pe;
+{
+ OID oid = prim2oid (pe);
+
+ if (oid == NULLOID || (*x = oid_cpy (oid)) == NULLOID)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int object_parse (x, s)
+OID *x;
+char *s;
+{
+ OID oid = text2oid (s);
+
+ if (oid == NULL)
+ return NOTOK;
+ *x = oid;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int object_print (x, os)
+OID x;
+OS os;
+{
+ char *cp,
+ ode[BUFSIZ];
+
+ (void) strcpy (ode, oid2ode (x));
+ printf ("%s", ode);
+ if (strcmp (ode, cp = sprintoid (x)))
+ printf (" (%s)", cp);
+}
+
+
+static add_object ()
+{
+ (void) add_syntax ("ObjectID", object_encode, object_decode, oid_free,
+ object_parse, object_print);
+}
+
+/* \f NULL */
+
+/* ARGSUSED */
+
+static int null_encode (x, pe)
+char *x;
+PE *pe;
+{
+ if ((*pe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int null_decode (x, pe)
+char **x;
+PE pe;
+{
+ if ((*x = (char *) calloc (1, sizeof **x)) == NULL)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int null_free (x)
+char *x;
+{
+ free ((char *) x);
+}
+
+
+static int null_parse (x, s)
+char **x;
+char *s;
+{
+ if (lexequ (s, "NULL"))
+ return NOTOK;
+
+ if ((*x = (char *) calloc (1, sizeof **x)) == NULL)
+ return NOTOK;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int null_print (x, os)
+char *x;
+OS os;
+{
+ printf ("NULL");
+}
+
+
+static add_null ()
+{
+ (void) add_syntax ("NULL", null_encode, null_decode, null_free, null_parse,
+ null_print);
+}
+
+/* \f IpAddress */
+
+static int ipaddr_encode (x, pe)
+struct sockaddr_in *x;
+PE *pe;
+{
+ if ((*pe = str2prim ((char *) &x -> sin_addr, 4, PE_CLASS_APPL, 0))
+ == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int ipaddr_decode (x, pe)
+struct sockaddr_in **x;
+PE pe;
+{
+ struct type_SNMP_IpAddress *ip;
+ struct qbuf *qb;
+ struct sockaddr_in *isock;
+
+ if (decode_SNMP_IpAddress (pe, 1, NULLIP, NULLVP, &ip) == NOTOK)
+ return NOTOK;
+ if (qb_pullup (ip) == NOTOK
+ || (isock = (struct sockaddr_in *) calloc (1, sizeof *isock))
+ == NULL) {
+ free_SNMP_IpAddress (ip);
+ return NOTOK;
+ }
+ if ((qb = ip -> qb_forw) -> qb_len != 4) {
+ free ((char *) isock);
+ free_SNMP_IpAddress (ip);
+ return NOTOK;
+ }
+ isock -> sin_family = AF_INET;
+ bcopy (qb -> qb_data,
+ (char *) &isock -> sin_addr,
+ sizeof isock -> sin_addr);
+
+ *x = isock;
+
+ free_SNMP_IpAddress (ip);
+ return OK;
+}
+
+
+static int ipaddr_free (x)
+struct sockaddr_in *x;
+{
+ free ((char *) x);
+}
+
+
+static int ipaddr_parse (x, s)
+struct sockaddr_in **x;
+char *s;
+{
+ register struct hostent *hp = gethostbystring (s);
+ register struct sockaddr_in *isock;
+
+ if (hp == NULL)
+ return NOTOK;
+
+ if ((isock = (struct sockaddr_in *) calloc (1, sizeof *isock)) == NULL)
+ return NOTOK;
+ isock -> sin_family = AF_INET;
+ inaddr_copy (hp, isock);
+ *x = isock;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int ipaddr_print (x, os)
+struct sockaddr_in *x;
+OS os;
+{
+ printf ("%s", inet_ntoa (x -> sin_addr));
+}
+
+
+static add_ipaddr ()
+{
+ (void) add_syntax ("IpAddress", ipaddr_encode, ipaddr_decode, ipaddr_free,
+ ipaddr_parse, ipaddr_print);
+}
+
+/* \f NetworkAddress */
+
+/* good enough for now (and probably forever)... */
+
+static add_netaddr ()
+{
+ (void) add_syntax ("NetworkAddress", ipaddr_encode, ipaddr_decode,
+ ipaddr_free, ipaddr_parse, ipaddr_print);
+}
+
+/* \f UNSIGNED LONGs */
+
+u_long prim2ulong (pe) /* also used in SNMP-capable gawk... */
+register PE pe;
+{
+ register u_long i;
+ register PElementData dp,
+ ep;
+
+ if (pe -> pe_form != PE_FORM_PRIM || (dp = pe -> pe_prim) == NULLPED)
+ return pe_seterr (pe, PE_ERR_PRIM, 0);
+ if (pe -> pe_len > sizeof (i) + 1)
+ return pe_seterr (pe, PE_ERR_OVER, 0);
+ if (pe -> pe_len == sizeof (i) + 1 && (*dp & 0x7f))
+ return pe_seterr (pe, PE_ERR_OVER, 0);
+ if (*dp & 0x80)
+ return pe_seterr (pe, PE_ERR_SIGNED, 0);
+
+ pe -> pe_errno = PE_ERR_NONE; /* in case result is ZERO-valued */
+ i = 0L;
+ for (ep = dp + pe -> pe_len; dp < ep;)
+ i = (i << 8) | (*dp++ & 0xff);
+
+ return i;
+}
+
+
+static PE ulong2prim (i, class, id)
+register u_long i;
+PElementClass class;
+PElementID id;
+{
+ int extend;
+ register int n;
+ register u_long mask;
+ register PElementData dp;
+ register PE pe;
+
+ if ((pe = pe_alloc (class, PE_FORM_PRIM, id)) == NULLPE)
+ return NULLPE;
+
+ mask = 0xff << (((n = sizeof i) - 1) * 8);
+ while (n > 1 && (i & mask) == 0)
+ mask >>= 8, n--;
+ extend = (i & (0x80 << ((n - 1) * 8))) ? 1 : 0;
+
+ if ((pe -> pe_prim = PEDalloc (n + extend)) == NULLPED) {
+ pe_free (pe);
+ return NULLPE;
+ }
+
+ for (dp = pe -> pe_prim + (pe -> pe_len = n + extend); n-- > 0; i >>= 8)
+ *--dp = i & 0xff;
+ if (extend)
+ *--dp = 0x00;
+
+ return pe;
+}
+
+/* \f Counter */
+
+static int counter_encode (x, pe)
+u_long *x;
+PE *pe;
+{
+ if ((*pe = ulong2prim (*x, PE_CLASS_APPL, 1)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int counter_decode (x, pe)
+u_long **x;
+PE pe;
+{
+ u_long i = prim2ulong (pe);
+
+ if (i == 0 && pe -> pe_errno != PE_ERR_NONE)
+ return NOTOK;
+ if ((*x = (u_long *) malloc (sizeof **x)) == NULL)
+ return NOTOK;
+ **x = i;
+
+ return OK;
+}
+
+
+static int counter_free (x)
+u_long *x;
+{
+ free ((char *) x);
+}
+
+
+static int counter_parse (x, s)
+u_long **x;
+char *s;
+{
+ u_long i;
+
+ if (sscanf (s, "%U", &i) != 1)
+ return NOTOK;
+ if ((*x = (u_long *) malloc (sizeof **x)) == NULL)
+ return NOTOK;
+ **x = i;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int counter_print (x, os)
+u_long *x;
+OS os;
+{
+ printf ("%U", *x);
+}
+
+
+static add_counter ()
+{
+ (void) add_syntax ("Counter", counter_encode, counter_decode, counter_free,
+ counter_parse, counter_print);
+}
+
+/* \f Gauge */
+
+static int gauge_encode (x, pe)
+u_long *x;
+PE *pe;
+{
+ if ((*pe = ulong2prim (*x, PE_CLASS_APPL, 2)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static add_gauge ()
+{
+ (void) add_syntax ("Gauge", gauge_encode, counter_decode, counter_free,
+ counter_parse, counter_print);
+}
+
+/* \f TimeTicks */
+
+static int timeticks_encode (x, pe)
+u_long *x;
+PE *pe;
+{
+ if ((*pe = ulong2prim (*x, PE_CLASS_APPL, 3)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int timeticks_print (x, os)
+u_long *x;
+OS os;
+{
+ u_long d,
+ h,
+ m,
+ s,
+ ds;
+
+ ds = *x;
+ s = ds / 100, ds = ds % 100;
+ m = s / 60, s = s % 60;
+ h = m / 60, m = m % 60;
+ d = h / 24, h = h % 24;
+
+ if (d > 0)
+ printf ("%d days, ", d);
+ if (d > 0 || h > 0)
+ printf ("%d hours, ", h);
+ if (d > 0 || h > 0 || m > 0)
+ printf ("%d minutes, ", m);
+ printf ("%d", s);
+ if (ds > 0)
+ printf (".%02d", ds);
+ printf (" seconds (%U timeticks)", *x);
+}
+
+
+static add_timeticks ()
+{
+ (void) add_syntax ("TimeTicks", timeticks_encode, counter_decode,
+ counter_free, counter_parse, timeticks_print);
+}
+
+/* \f CnlpAddress */
+
+static int clnpaddr_encode (x, pe)
+struct sockaddr_iso *x;
+PE *pe;
+{
+ char buffer[sizeof x -> siso_data + 1];
+
+ buffer[0] = x -> siso_nlen & 0xff;
+ bcopy (x -> siso_data, buffer + 1, (int) x -> siso_nlen);
+
+ if ((*pe = str2prim (buffer, (int) (x -> siso_nlen + 1), PE_CLASS_APPL,
+ 5)) == NULLPE)
+ return NOTOK;
+
+ return OK;
+}
+
+
+static int clnpaddr_decode (x, pe)
+struct sockaddr_iso **x;
+PE pe;
+{
+ int len;
+ struct type_SNMP_ClnpAddress *clnp;
+ struct qbuf *qb;
+ struct sockaddr_iso *isock;
+
+ if (decode_SNMP_ClnpAddress (pe, 1, NULLIP, NULLVP, &clnp) == NOTOK)
+ return NOTOK;
+ if (qb_pullup (clnp) == NOTOK
+ || (isock = (struct sockaddr_iso *) calloc (1, sizeof *isock))
+ == NULL) {
+ free_SNMP_ClnpAddress (clnp);
+ return NOTOK;
+ }
+ qb = clnp -> qb_forw;
+ isock -> siso_family = AF_ISO;
+ if ((len = qb -> qb_data[0] & 0xff) >= qb -> qb_len)
+ len = qb -> qb_len - 1;
+ bcopy (qb -> qb_data + 1, isock -> siso_data,
+ (int) (isock -> siso_nlen = len));
+
+ *x = isock;
+
+ free_SNMP_ClnpAddress (clnp);
+ return OK;
+}
+
+
+static int clnpaddr_free (x)
+struct sockaddr_iso *x;
+{
+ free ((char *) x);
+}
+
+
+static int clnpaddr_parse (x, s)
+struct sockaddr_iso **x;
+char *s;
+{
+ register struct sockaddr_iso *isock;
+
+ if ((isock = (struct sockaddr_iso *) calloc (1, sizeof *isock)) == NULL)
+ return NOTOK;
+ isock -> siso_family = AF_ISO;
+ isock -> siso_nlen = implode ((u_char *) isock -> siso_data, s,
+ strlen (s));
+ *x = isock;
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int clnpaddr_print (x, os)
+struct sockaddr_iso *x;
+OS os;
+{
+ char buffer[sizeof x -> siso_data * 2 + 1];
+
+ buffer[explode (buffer, (u_char *) x -> siso_data, (int) x -> siso_nlen)] =
+ NULL;
+ printf ("NS+%s", buffer);
+}
+
+
+static add_clnpaddr ()
+{
+ (void) add_syntax ("ClnpAddress", clnpaddr_encode, clnpaddr_decode,
+ clnpaddr_free, clnpaddr_parse, clnpaddr_print);
+}
+
+/* \f */
+
+int readsyntax ()
+{
+ add_integer ();
+ add_string ();
+ add_object ();
+ add_null ();
+ add_ipaddr ();
+ add_netaddr ();
+ add_counter ();
+ add_gauge ();
+ add_timeticks ();
+
+ add_clnpaddr ();
+}
+
+/* \f */
+
+int add_syntax (name, f_encode, f_decode, f_free, f_parse, f_print)
+char *name;
+IFP f_encode,
+ f_decode,
+ f_free,
+ f_parse,
+ f_print;
+{
+ int i;
+ register OS os = synlast++;
+
+ if ((i = synlast - syntaxes) >= MAXSYN)
+ return NOTOK;
+
+ bzero ((char *) os, sizeof *os);
+ os -> os_name = name;
+ os -> os_encode = f_encode;
+ os -> os_decode = f_decode;
+ os -> os_free = f_free;
+ os -> os_parse = f_parse;
+ os -> os_print = f_print;
+
+ return i;
+}
+
+/* \f */
+
+OS text2syn (name)
+char *name;
+{
+ register OS os;
+
+ for (os = syntaxes; os < synlast; os++)
+ if (strcmp (os -> os_name, name) == 0)
+ return os;
+
+ return NULLOS;
+}
--- /dev/null
+/* system.c - MIB realization of the System group */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/system.c,v 7.8 91/02/22 09:44:40 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/RCS/system.c,v 7.8 91/02/22 09:44:40 mrose Interim $
+ *
+ * Contributed by NYSERNet Inc. This work was partially supported by the
+ * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+ * Center of the U.S. Air Force Systems Command under contract number
+ * F30602-88-C-0016.
+ *
+ *
+ * $Log: system.c,v $
+ * Revision 7.8 91/02/22 09:44:40 mrose
+ * Interim 6.8
+ *
+ * Revision 7.7 91/01/11 15:35:39 mrose
+ * sets
+ *
+ * Revision 7.6 91/01/07 12:41:16 mrose
+ * update
+ *
+ * Revision 7.5 90/12/18 10:14:11 mrose
+ * update
+ *
+ * Revision 7.4 90/10/23 20:37:24 mrose
+ * update
+ *
+ * Revision 7.3 90/05/14 15:44:29 mrose
+ * touch-up
+ *
+ * Revision 7.2 90/05/14 13:28:18 mrose
+ * system
+ *
+ * Revision 7.1 90/05/13 16:18:32 mrose
+ * views
+ *
+ * Revision 7.0 89/11/23 22:23:33 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+#include "tailor.h"
+
+/* \f */
+
+static int o_sysUpTime (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ struct timeval now;
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+ static int lastq = -1;
+ static integer diff;
+
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
+ || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((new = oid_extend (oid, 1)) == NULLOID)
+ return NOTOK;
+ new -> oid_elements[new -> oid_nelem - 1] = 0;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else
+ return NOTOK;
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (quantum != lastq) {
+ lastq = quantum;
+
+ if (gettimeofday (&now, (struct timezone *) 0) == NOTOK) {
+ advise (LLOG_EXCEPTIONS, "failed", "gettimeofday");
+ return generr (offset);
+ }
+
+ diff = (now.tv_sec - my_boottime.tv_sec) * 100
+ + ((now.tv_usec - my_boottime.tv_usec) / 10000);
+ }
+
+ return o_number (oi, v, (caddr_t) &diff);
+}
+
+/* \f */
+
+static struct sys_pair {
+ char *s_name;
+ char *s_text;
+ IFP s_getfnx;
+ IFP s_setfnx;
+} pairs[] = {
+ "sysDescr", sysDescr, o_generic, NULLIFP,
+ "sysObjectID", sysObjectID, o_generic, NULLIFP,
+ "sysUpTime", NULL, o_sysUpTime, NULLIFP,
+ "sysContact", NULL, o_generic, s_generic,
+#define SYS_NAME 4
+ "sysName", NULL, o_generic, s_generic,
+ "sysLocation", NULL, o_generic, s_generic,
+ "sysServices", "72", o_generic, NULLIFP,
+
+ NULL
+};
+
+
+init_system () {
+ char buffer[BUFSIZ];
+ register OT ot;
+ register struct sys_pair *sp;
+
+ (void) gethostname (buffer, sizeof buffer);
+ pairs[SYS_NAME].s_text = buffer;
+
+ for (sp = pairs; sp -> s_name; sp++)
+ if (ot = text2obj (sp -> s_name)) {
+ ot -> ot_getfnx = sp -> s_getfnx;
+ ot -> ot_setfnx = sp -> s_setfnx;
+
+ if (sp -> s_text)
+ if (ot -> ot_syntax)
+ (void) (*ot -> ot_syntax -> os_parse) ((struct qbuf **)
+ &ot -> ot_info,
+ sp -> s_text);
+ else
+ advise (LLOG_EXCEPTIONS, NULLCP, "%s: no syntax",
+ sp -> s_name);
+ }
+ else
+ advise (LLOG_EXCEPTIONS, NULLCP, "%s: unknown object",
+ sp -> s_name);
+}
--- /dev/null
+/* tcp.c - MIB realization of the TCP group */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/tcp.c,v 7.12 91/02/22 09:44:42 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/RCS/tcp.c,v 7.12 91/02/22 09:44:42 mrose Interim $
+ *
+ * Contributed by NYSERNet Inc. This work was partially supported by the
+ * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+ * Center of the U.S. Air Force Systems Command under contract number
+ * F30602-88-C-0016.
+ *
+ *
+ * $Log: tcp.c,v $
+ * Revision 7.12 91/02/22 09:44:42 mrose
+ * Interim 6.8
+ *
+ * Revision 7.11 91/01/08 12:48:45 mrose
+ * update
+ *
+ * Revision 7.10 90/12/18 10:14:14 mrose
+ * update
+ *
+ * Revision 7.9 90/10/17 14:33:18 mrose
+ * update
+ *
+ * Revision 7.8 90/10/02 09:55:05 mrose
+ * normalize again
+ *
+ * Revision 7.7 90/07/09 14:49:43 mrose
+ * sync
+ *
+ * Revision 7.6 90/06/05 20:47:27 mrose
+ * touch-up
+ *
+ * Revision 7.5 90/04/23 00:08:16 mrose
+ * touch-up
+ *
+ * Revision 7.4 90/04/18 08:52:06 mrose
+ * oid_normalize
+ *
+ * Revision 7.3 90/02/27 18:50:07 mrose
+ * unix stuff
+ *
+ * Revision 7.2 90/01/27 08:22:09 mrose
+ * touch-up
+ *
+ * Revision 7.1 89/12/11 10:40:40 mrose
+ * touch-up
+ *
+ * Revision 7.0 89/11/23 22:23:35 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+
+#include "internet.h"
+#if defined(BSD44) || defined (BSD43)
+#include <sys/param.h>
+#endif
+#include <sys/protosw.h>
+#include <sys/socketvar.h>
+#include <net/route.h>
+#include <netinet/in_systm.h>
+#ifdef BSD44
+#include <netinet/ip.h>
+#endif
+#include <netinet/in_pcb.h>
+#include <netinet/tcp.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/tcp_timer.h>
+#include <netinet/tcp_var.h>
+
+/* \f */
+
+#define RTOA_OTHER 1 /* tcpRtoAlgorithm */
+#define RTOA_VANJ 4 /* .. */
+
+#define MXCN_NONE (-1) /* tcpMaxConn */
+
+
+static struct tcpstat tcpstat;
+
+static int tcpConnections;
+
+/* \f */
+
+#define tcpRtoAlgorithm 0
+#define tcpRtoMin 1
+#define tcpRtoMax 2
+#define tcpMaxConn 3
+#define tcpActiveOpens 4
+#define tcpPassiveOpens 5
+#define tcpAttemptFails 6
+#define tcpEstabResets 7
+#define tcpCurrEstab 8
+#define tcpInSegs 9
+#define tcpOutSegs 10
+#define tcpRetransSegs 11
+#ifndef SUNOS4
+#define tcpInErrs 12
+#else
+#undef tcpInErrs 12
+#endif
+#undef tcpOutRsts 13 /* NOT IMPLEMENTED */
+
+
+static int o_tcp (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register struct tcpstat *tcps = &tcpstat;
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+ static int lastq = -1;
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
+ || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((new = oid_extend (oid, 1)) == NULLOID)
+ return NOTOK;
+ new -> oid_elements[new -> oid_nelem - 1] = 0;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else
+ return NOTOK;
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (ifvar) {
+ case tcpCurrEstab:
+ if (get_connections (type_SNMP_PDUs_get__request) == NOTOK)
+ return generr (offset);
+ break;
+
+ default:
+ if (quantum != lastq) {
+ lastq = quantum;
+
+ if (getkmem (nl + N_TCPSTAT, (caddr_t) tcps, sizeof *tcps)
+ == NOTOK)
+ return generr (offset);
+ }
+ break;
+ }
+
+ switch (ifvar) {
+ case tcpRtoAlgorithm:
+#ifdef TCPTV_REXMTMAX
+ return o_integer (oi, v, RTOA_VANJ);
+#else
+ return o_integer (oi, v, RTOA_OTHER);
+#endif
+
+ case tcpRtoMin:
+ return o_integer (oi, v, TCPTV_MIN * 100); /* milliseconds */
+
+#ifdef TCPTV_REXMTMAX
+ case tcpRtoMax:
+ return o_integer (oi, v, TCPTV_REXMTMAX * 100); /* .. */
+#endif
+
+ case tcpMaxConn:
+ return o_integer (oi, v, MXCN_NONE);
+
+#ifdef TCPTV_REXMTMAX
+ case tcpActiveOpens:
+ return o_integer (oi, v, tcps -> tcps_connattempt);
+
+ case tcpPassiveOpens:
+ return o_integer (oi, v, tcps -> tcps_accepts);
+
+ case tcpAttemptFails:
+ return o_integer (oi, v, tcps -> tcps_conndrops);
+
+ case tcpEstabResets:
+ return o_integer (oi, v, tcps -> tcps_drops);
+#endif
+
+ case tcpCurrEstab:
+ return o_integer (oi, v, tcpConnections);
+
+#ifdef TCPTV_REXMTMAX
+ case tcpInSegs:
+ return o_integer (oi, v, tcps -> tcps_rcvtotal);
+
+ case tcpOutSegs:
+ return o_integer (oi, v, tcps -> tcps_sndtotal
+ - tcps -> tcps_sndrexmitpack);
+
+ case tcpRetransSegs:
+ return o_integer (oi, v, tcps -> tcps_sndrexmitpack);
+#endif
+
+#ifdef tcpInErrs
+ case tcpInErrs:
+#if !defined(BSD44) && !(defined(BSD43) && defined(ultrix))
+ return o_integer (oi, v, tcps -> tcps_badsegs);
+#else
+ return o_integer (oi, v, tcps -> tcps_rcvbadsum
+ + tcps -> tcps_rcvbadoff
+ + tcps -> tcps_rcvshort);
+#endif
+#endif
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+static int tcp_states[TCP_NSTATES];
+
+
+struct tcptab {
+#define TT_SIZE 10 /* object instance */
+ unsigned int tt_instance[TT_SIZE];
+
+ struct inpcb tt_pcb; /* protocol control block */
+
+ struct socket tt_socb; /* socket info */
+
+ struct tcpcb tt_tcpb; /* TCP info */
+
+ struct tcptab *tt_next;
+};
+
+static struct tcptab *tts = NULL;
+
+static int flush_tcp_cache = 0;
+
+
+struct tcptab *get_tcpent ();
+
+/* \f */
+
+#define tcpConnState 0
+#define tcpConnLocalAddress 1
+#define tcpConnLocalPort 2
+#define tcpConnRemAddress 3
+#define tcpConnRemPort 4
+#define unixTcpConnSendQ 5
+#define unixTcpConnRecvQ 6
+
+
+static int o_tcp_conn (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ register struct tcptab *tt;
+ struct sockaddr_in netaddr;
+ register OID oid = oi -> oi_name;
+ OID new;
+ register OT ot = oi -> oi_type;
+
+ if (get_connections (offset) == NOTOK)
+ return generr (offset);
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + TT_SIZE)
+ return int_SNMP_error__status_noSuchName;
+ if ((tt = get_tcpent (oid -> oid_elements + oid -> oid_nelem
+ - TT_SIZE, 0)) == NULL)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0
+ && i < TT_SIZE) {
+ for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i;
+ jp > ip;
+ jp--)
+ if (*jp != 0)
+ break;
+ if (jp == ip)
+ oid -> oid_nelem = ot -> ot_name -> oid_nelem;
+ else {
+ if ((new = oid_normalize (oid, TT_SIZE - i, 65536))
+ == NULLOID)
+ return NOTOK;
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = oid = new;
+ }
+ }
+ else
+ if (i > TT_SIZE)
+ oid -> oid_nelem = ot -> ot_name -> oid_nelem + TT_SIZE;
+
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ if ((tt = tts) == NULL)
+ return NOTOK;
+
+ if ((new = oid_extend (oid, TT_SIZE)) == NULLOID)
+ return NOTOK;
+ ip = new -> oid_elements + new -> oid_nelem - TT_SIZE;
+ jp = tt -> tt_instance;
+ for (i = TT_SIZE; i > 0; i--)
+ *ip++ = *jp++;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else {
+ if ((tt = get_tcpent (ip = oid -> oid_elements
+ + oid -> oid_nelem - TT_SIZE, 1))
+ == NULL)
+ return NOTOK;
+
+ jp = tt -> tt_instance;
+ for (i = TT_SIZE; i > 0; i--)
+ *ip++ = *jp++;
+ }
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (ifvar) {
+ case tcpConnState:
+ if ((i = tt -> tt_tcpb.t_state) < 0
+ || i >= sizeof tcp_states / sizeof tcp_states[0])
+ return generr (offset);
+ return o_integer (oi, v, tcp_states[i]);
+
+ case tcpConnLocalAddress:
+ netaddr.sin_addr = tt -> tt_pcb.inp_laddr; /* struct copy */
+ return o_ipaddr (oi, v, &netaddr);
+
+ case tcpConnLocalPort:
+ return o_integer (oi, v, ntohs (tt -> tt_pcb.inp_lport) & 0xffff);
+
+ case tcpConnRemAddress:
+ netaddr.sin_addr = tt -> tt_pcb.inp_faddr; /* struct copy */
+ return o_ipaddr (oi, v, &netaddr);
+
+ case tcpConnRemPort:
+ return o_integer (oi, v, ntohs (tt -> tt_pcb.inp_fport) & 0xffff);
+
+ case unixTcpConnSendQ:
+ return o_integer (oi, v, tt -> tt_socb.so_snd.sb_cc);
+
+ case unixTcpConnRecvQ:
+ return o_integer (oi, v, tt -> tt_socb.so_rcv.sb_cc);
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+static int tt_compar (a, b)
+struct tcptab **a,
+ **b;
+{
+ return elem_cmp ((*a) -> tt_instance, TT_SIZE,
+ (*b) -> tt_instance, TT_SIZE);
+}
+
+
+static int get_connections (offset)
+int offset;
+{
+ register int i;
+ register unsigned int *cp;
+ register struct tcptab *ts,
+ *tp,
+ **tsp;
+ register struct inpcb *ip;
+ struct inpcb *head,
+ tcb;
+ struct nlist nzs;
+ register struct nlist *nz = &nzs;
+ static int first_time = 1;
+ static int lastq = -1;
+
+ if (quantum == lastq)
+ return OK;
+ if (!flush_tcp_cache
+ && offset == type_SNMP_PDUs_get__next__request
+ && quantum == lastq + 1) { /* XXX: caching! */
+ lastq = quantum;
+ return OK;
+ }
+ lastq = quantum, flush_tcp_cache = 0;
+
+ for (ts = tts; ts; ts = tp) {
+ tp = ts -> tt_next;
+
+ free ((char *) ts);
+ }
+ tts = NULL;
+
+ if (getkmem (nl + N_TCB, (char *) &tcb, sizeof tcb) == NOTOK)
+ return NOTOK;
+ head = (struct inpcb *) nl[N_TCB].n_value;
+
+ tsp = &tts, i = 0;
+ ip = &tcb;
+ while (ip -> inp_next != head) {
+ if ((ts = (struct tcptab *) calloc (1, sizeof *ts)) == NULL)
+ adios (NULLCP, "out of memory");
+ /* no check needed for duplicate connections... */
+ *tsp = ts, tsp = &ts -> tt_next, i++;
+
+ nz -> n_name = "struct inpcb",
+ nz -> n_value = (unsigned long) ip -> inp_next;
+ if (getkmem (nz, (caddr_t) &ts -> tt_pcb, sizeof ts -> tt_pcb)
+ == NOTOK)
+ return NOTOK;
+ ip = &ts -> tt_pcb;
+
+ nz ->n_name = "struct socket",
+ nz -> n_value = (unsigned long) ip -> inp_socket;
+ if (getkmem (nz, (caddr_t) &ts -> tt_socb, sizeof ts -> tt_socb)
+ == NOTOK)
+ return NOTOK;
+
+ nz ->n_name = "struct tcb",
+ nz -> n_value = (unsigned long) ip -> inp_ppcb;
+ if (getkmem (nz, (caddr_t) &ts -> tt_tcpb, sizeof ts -> tt_tcpb)
+ == NOTOK)
+ return NOTOK;
+
+ cp = ts -> tt_instance;
+ cp += ipaddr2oid (cp, &ip -> inp_laddr);
+ *cp++ = ntohs (ip -> inp_lport) & 0xffff;
+ cp += ipaddr2oid (cp, &ip -> inp_faddr);
+ *cp++ = ntohs (ip -> inp_fport) & 0xffff;
+
+ if (debug && first_time) {
+ OIDentifier oids;
+
+ oids.oid_elements = ts -> tt_instance;
+ oids.oid_nelem = TT_SIZE;
+ advise (LLOG_DEBUG, NULLCP,
+ "add connection: %s", sprintoid (&oids));
+ }
+ }
+ first_time = 0;
+
+ if ((tcpConnections = i) > 1) {
+ register struct tcptab **base,
+ **tse;
+
+ if ((base = (struct tcptab **) malloc ((unsigned) (i * sizeof *base)))
+ == NULL)
+ adios (NULLCP, "out of memory");
+
+ tse = base;
+ for (ts = tts; ts; ts = ts -> tt_next)
+ *tse++ = ts;
+
+ qsort ((char *) base, i, sizeof *base, tt_compar);
+
+ tsp = base;
+ ts = tts = *tsp++;
+
+ while (tsp < tse) {
+ ts -> tt_next = *tsp;
+ ts = *tsp++;
+ }
+ ts -> tt_next = NULL;
+
+ free ((char *) base);
+ }
+
+ return OK;
+}
+
+/* \f */
+
+static struct tcptab *get_tcpent (ip, isnext)
+register unsigned int *ip;
+int isnext;
+{
+ register struct tcptab *tt;
+
+ for (tt = tts; tt; tt = tt -> tt_next)
+ switch (elem_cmp (tt -> tt_instance, TT_SIZE, ip, TT_SIZE)) {
+ case 0:
+ if (!isnext)
+ return tt;
+ if ((tt = tt -> tt_next) == NULL)
+ goto out;
+ /* else fall... */
+
+ case 1:
+ return (isnext ? tt : NULL);
+ }
+
+out: ;
+ flush_tcp_cache = 1;
+
+ return NULL;
+}
+
+/* \f */
+
+init_tcp () {
+ register OT ot;
+
+ if (ot = text2obj ("tcpRtoAlgorithm"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpRtoAlgorithm;
+ if (ot = text2obj ("tcpRtoMin"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpRtoMin;
+#ifdef TCPTV_REXMTMAX
+ if (ot = text2obj ("tcpRtoMax"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpRtoMax;
+#endif
+ if (ot = text2obj ("tcpMaxConn"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpMaxConn;
+#ifdef TCPTV_REXMTMAX
+ if (ot = text2obj ("tcpActiveOpens"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpActiveOpens;
+ if (ot = text2obj ("tcpPassiveOpens"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpPassiveOpens;
+ if (ot = text2obj ("tcpAttemptFails"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpAttemptFails;
+ if (ot = text2obj ("tcpEstabResets"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpEstabResets;
+#endif
+ if (ot = text2obj ("tcpCurrEstab"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpCurrEstab;
+#ifdef TCPTV_REXMTMAX
+ if (ot = text2obj ("tcpInSegs"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpInSegs;
+ if (ot = text2obj ("tcpOutSegs"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpOutSegs;
+ if (ot = text2obj ("tcpRetransSegs"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpRetransSegs;
+#endif
+#ifdef tcpInErrs
+ if (ot = text2obj ("tcpInErrs"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpInErrs;
+#endif
+#ifdef tcpOutRsts
+ if (ot = text2obj ("tcpOutRsts"))
+ ot -> ot_getfnx = o_tcp,
+ ot -> ot_info = (caddr_t) tcpOutRsts;
+#endif
+
+ if (ot = text2obj ("tcpConnState"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) tcpConnState;
+ if (ot = text2obj ("tcpConnLocalAddress"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) tcpConnLocalAddress;
+ if (ot = text2obj ("tcpConnLocalPort"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) tcpConnLocalPort;
+ if (ot = text2obj ("tcpConnRemAddress"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) tcpConnRemAddress;
+ if (ot = text2obj ("tcpConnRemPort"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) tcpConnRemPort;
+
+ if (ot = text2obj ("unixTcpConnSendQ"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) unixTcpConnSendQ;
+ if (ot = text2obj ("unixTcpConnRecvQ"))
+ ot -> ot_getfnx = o_tcp_conn,
+ ot -> ot_info = (caddr_t) unixTcpConnRecvQ;
+
+ tcp_states[TCPS_CLOSED] = 1;
+ tcp_states[TCPS_LISTEN] = 2;
+ tcp_states[TCPS_SYN_SENT] = 3;
+ tcp_states[TCPS_SYN_RECEIVED] = 4;
+ tcp_states[TCPS_ESTABLISHED] = 5;
+ tcp_states[TCPS_CLOSE_WAIT] = 8;
+ tcp_states[TCPS_FIN_WAIT_1] = 6;
+ tcp_states[TCPS_CLOSING] = 10;
+ tcp_states[TCPS_LAST_ACK] = 9;
+ tcp_states[TCPS_FIN_WAIT_2] = 7;
+ tcp_states[TCPS_TIME_WAIT] = 11;
+}
--- /dev/null
+-- tokenbus.my - Token Bus MIB
+
+-- $Header: /f/osi/snmp/RCS/tokenbus.my,v 7.2 91/02/22 09:44:43 mrose Interim $
+--
+--
+-- $Log: tokenbus.my,v $
+-- Revision 7.2 91/02/22 09:44:43 mrose
+-- Interim 6.8
+--
+-- Revision 7.1 91/01/11 13:02:46 mrose
+-- update
+--
+-- Revision 7.0 90/09/27 10:46:05 mrose
+-- *** empty log message ***
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+ RFCxxxx-MIB DEFINITIONS ::= BEGIN
+
+ -- IEEE 802.4 Token Bus MIB
+
+ IMPORTS
+ experimental
+ FROM RFC1155-SMI
+ OBJECT-TYPE
+ FROM RFC-oooo;
+
+ -- This MIB Module uses the extended OBJECT-TYPE macro as
+ -- defined in [9].
+
+
+
+ dot4 OBJECT IDENTIFIER ::= { experimental 7 }
+
+ -- All representations of MAC addresses in this MIB Module use,
+ -- as a textual convention (i.e. this convention does not affect
+ -- their encoding), the data type:
+
+ MacAddress ::= OCTET STRING (SIZE (6)) -- a 6 octet address in
+ -- the "canonical" order
+ -- defined by IEEE 802.1a.
+ -- 16-bit addresses, if needed, are represented by setting their
+ -- upper 4 octets to all 0's, i.e., AAFF would be represented
+ -- as 00000000AAFF.
+
+
+ -- This specification follows the 802.4 convention of specifying
+ -- time intervals, which are dependent on the bandwidth of the media,
+ -- in units of octet time. One octet time is the time taken to
+ -- transmit eight bits. Representation of such time intervals
+ -- in this MIB Module use, as a textual convention (i.e. this
+ -- convention does not affect their encoding), the data type:
+
+ OctetTime ::= INTEGER -- the value of a time interval in
+ -- units of octet time.
+
+
+
+
+
+
+
+
+
+
+
+ -- The 802.4 Operational Table
+
+ -- This table contains state and parameter information which is
+ -- specific to 802.4 interfaces. It is mandatory that systems
+ -- having 802.4 interfaces implement this table in addition to the
+ -- generic interfaces table [4,6] and its generic extensions [11].
+
+ dot4Table OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot4Entry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "This table contains Token Bus interface
+ parameters and state variables, one entry
+ per 802.5 interface."
+
+ ::= { dot4 1 }
+
+ dot4Entry OBJECT-TYPE
+ SYNTAX Dot4Entry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A list of Token Bus status and operational
+ parameter values for an 802.4 interface."
+ INDEX { dot4IfIndex }
+ ::= { dot4Table 1 }
+
+ Dot4Entry ::= SEQUENCE {
+ dot4IfIndex
+ INTEGER,
+ dot4Options
+ INTEGER,
+ dot4State
+ INTEGER,
+ dot4Commands
+ INTEGER,
+ dot4MacAddrLen
+ INTEGER,
+ dot4NextStation
+ MacAddress,
+ dot4PreviousStation
+ MacAddress,
+ dot4SlotTime
+ OctetTime,
+
+
+
+
+
+
+
+ dot4LastTokenRotTime
+ OctetTime,
+ dot4HiPriTokenHoldTime
+ OctetTime,
+ dot4TargetRotTimeClass4
+ OctetTime,
+ dot4TargetRotTimeClass2
+ OctetTime,
+ dot4TargetRotTimeClass0
+ OctetTime,
+ dot4TargetRotTimeRingMaint
+ OctetTime,
+ dot4RingMaintTimerInitValue
+ OctetTime,
+ dot4MaxInterSolicitCount
+ INTEGER (16..255),
+ dot4MaxRetries
+ INTEGER (0..7),
+ dot4MinPostSilencePreambLen
+ INTEGER,
+ dot4StandardRevision
+ INTEGER
+ }
+
+
+ dot4IfIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value of this object identifies the 802.4
+ interface for which this entry contains management
+ information. The value of this object for a
+ particular interface has the same value as the
+ ifIndex object, defined in [4,6], for the same
+ interface."
+ ::= { dot4Entry 1 }
+
+ dot4Options OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The optional parts of the 802.4 specification
+ which are in use by this station. The options of
+
+
+
+
+
+
+
+ the 802.4 specification are represented by the
+ following values:
+ 1 - Priority
+ 2 - Request-With-Response
+ The value of this object is given by the sum of
+ the above representations for those options in
+ use on this interface. The value zero indicates
+ that no options are in use."
+ ::= { dot4Entry 2 }
+
+ dot4State OBJECT-TYPE
+ SYNTAX INTEGER {
+ other(1),
+ offline(2),
+ outOfRing(3),
+ enteringRing(4),
+ inRing(5)
+ }
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The current state of the 802.4 interface. The
+ value of other(1) is used if the state is unknown
+ (e.g., due to an error condition)."
+ ::= { dot4Entry 3 }
+
+ dot4Commands OBJECT-TYPE
+ SYNTAX INTEGER {
+ no-op(1),
+ enterRing(2),
+ exitRing(3),
+ reset(4),
+ initialize(5)
+ }
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "Setting this object causes the station to change
+ the state of the interface as indicated by the
+ specified value. An initialize(5) command
+ causes the interface to load its operational
+ parameters from its initialization parameters;
+ the value of dot4InitInRingDesired determines
+ whether the station tries to enter the logical
+ ring immediately.
+
+
+
+
+
+
+
+ Note that the 802.4 specification suggests
+ a station remain Offline after a 'remote Network
+ Management' reset(4), until a 'local Network
+ Management' initialize(5) is performed.
+ Setting this object to a value of no-op(1)
+ has no effect. When read, this object always
+ has the value no-op(1)."
+ ::= { dot4Entry 4 }
+
+ dot4MacAddrLen OBJECT-TYPE
+ SYNTAX INTEGER {
+ sixteenBit(1),
+ forty-eightBit(2)
+ }
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This object indicates the size of MAC addresses
+ interpreted by this station."
+ ::= { dot4Entry 5 }
+
+ dot4NextStation OBJECT-TYPE
+ SYNTAX MacAddress
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The MAC address of this station's successor
+ in the logical ring."
+ ::= { dot4Entry 6 }
+
+ dot4PreviousStation OBJECT-TYPE
+ SYNTAX MacAddress
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The source MAC address of the last token
+ addressed to this station."
+ ::= { dot4Entry 7 }
+
+ dot4SlotTime OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The maximum time any station need wait for an
+
+
+
+
+
+
+
+ immediate MAC-level response from another station.
+ This value must the same in all stations on
+ the 802.4 network."
+ ::= { dot4Entry 8 }
+
+ dot4LastTokenRotTime OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The observed token rotation time for the last
+ token rotation, timed from token arrival to
+ token arrival. A value of zero indicates that
+ the token is not rotating."
+ ::= { dot4Entry 9 }
+
+ dot4HiPriTokenHoldTime OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The maximum duration for which a station can
+ hold the token to transmit frames of access
+ class 6 (if the priority option is implemented),
+ or of any access class (if the priority option
+ is not implemented)."
+ ::= { dot4Entry 10 }
+
+ dot4TargetRotTimeClass4 OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "If the priority scheme is being used, this value
+ specifies a limit on how long a station can
+ transmit frames at access class 4. The limit
+ is measured from the time the station is able
+ to start transmitting frames at this access
+ class on one rotation, to the time it must stop
+ transmitting frames at this access class on the
+ next rotation. If the priority scheme is not
+ being used, this object has the value 0."
+ ::= { dot4Entry 11 }
+
+ dot4TargetRotTimeClass2 OBJECT-TYPE
+
+
+
+
+
+
+
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "If the priority scheme is being used, this value
+ specifies a limit on how long a station can
+ transmit frames at access class 2. The limit
+ is measured from the time the station is able
+ to start transmitting frames at this access
+ class on one rotation, to the time it must stop
+ transmitting frames at this access class on the
+ next rotation. If the priority scheme is not
+ being used, this object has the value 0."
+ ::= { dot4Entry 12 }
+
+ dot4TargetRotTimeClass0 OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "If the priority scheme is being used, this value
+ specifies a limit on how long a station can
+ transmit frames at access class 0. The limit
+ is measured from the time the station is able
+ to start transmitting frames at this access
+ class on one rotation, to the time it must stop
+ transmitting frames at this access class on the
+ next rotation. If the priority scheme is not
+ being used, this object has the value 0."
+ ::= { dot4Entry 13 }
+
+ dot4TargetRotTimeRingMaint OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "A value used to limit the duration of a token
+ rotation. If the duration of a token rotation
+ exceeds this value, the station will not open
+ the response window to solicit for a new
+ successor."
+ ::= { dot4Entry 14 }
+
+ dot4RingMaintTimerInitValue OBJECT-TYPE
+ SYNTAX OctetTime
+
+
+
+
+
+
+
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value to which the dot4TargetRotTimeRingMaint
+ is set, each time the station enters the ring.
+ A large value will cause the station to solicit
+ successors immediately upon entry to the ring;
+ a value of zero will cause the station to defer
+ this solicitation for at least one token rotation."
+ ::= { dot4Entry 15 }
+
+ dot4MaxInterSolicitCount OBJECT-TYPE
+ SYNTAX INTEGER (16..255)
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The maximum number of consecutive token
+ rotations without soliciting for a successor. If
+ this count expires, the station opens the response
+ window to solicit for a successor (providing the
+ duration of the current token rotation has not
+ exceeded dot4TargetRotTimeRingMaint). The least
+ significant two bits of the count are determined
+ randomly by the station on a per-use basis."
+ ::= { dot4Entry 16 }
+
+ dot4MaxRetries OBJECT-TYPE
+ SYNTAX INTEGER (0..7)
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The maximum number of retries of a
+ Request-with-Response (RWR) frame. If the RWR
+ option is not in use, this object has the value 0."
+ ::= { dot4Entry 17 }
+
+ dot4MinPostSilencePreambLen OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The minimum number of octets of preamble on the
+ first frame transmitted by this station after a
+ period of 'transmitted' silence."
+ ::= { dot4Entry 18 }
+
+
+
+
+
+
+
+ dot4StandardRevision OBJECT-TYPE
+ SYNTAX INTEGER {
+ rev2(2)
+ }
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The Revision number of the 802.4 standard
+ implemented by this station."
+ ::= { dot4Entry 19 }
+
+
+ -- 802.4 Initialization Table
+
+ -- This table contains the parameter information used by an 802.4
+ -- interface as the values to be assigned to its operational
+ -- parameters upon initialization. It is mandatory that systems
+ -- having 802.4 interfaces implement this table.
+
+ dot4InitTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot4InitEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "This table contains Token Bus initialization
+ parameters, one entry per 802.4 interface."
+ ::= { dot4 2 }
+
+ dot4InitEntry OBJECT-TYPE
+ SYNTAX Dot4InitEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A list of Token Bus initialization parameters
+ for an 802.4 interface."
+ INDEX { dot4InitIfIndex }
+ ::= { dot4InitTable 1 }
+
+ Dot4InitEntry ::= SEQUENCE {
+ dot4InitIfIndex
+ INTEGER,
+ dot4InitSlotTime
+ OctetTime,
+ dot4InitMaxInterSolicitCount
+ INTEGER (16..255),
+
+
+
+
+
+
+
+ dot4InitMaxRetries
+ INTEGER (0..7),
+ dot4InitHiPriTokenHoldTime
+ OctetTime,
+ dot4InitTargetRotTimeClass4
+ OctetTime,
+ dot4InitTargetRotTimeClass2
+ OctetTime,
+ dot4InitTargetRotTimeClass0
+ OctetTime,
+ dot4InitTargetRotTimeRingMaint
+ OctetTime,
+ dot4InitRingMaintTimerInitValue
+ OctetTime,
+ dot4InitMinPostSilencePreambLen
+ INTEGER,
+ dot4InitInRingDesired
+ INTEGER
+ }
+
+ dot4InitIfIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value of this object identifies the 802.4
+ interface for which this entry contains management
+ information. The value of this object for a
+ particular interface has the same value as the
+ ifIndex object, defined in [4,6], for the same
+ interface."
+ ::= { dot4InitEntry 1 }
+
+ dot4InitSlotTime OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object dot4SlotTime
+ when the station is initialized."
+ ::= { dot4InitEntry 2 }
+
+ dot4InitMaxInterSolicitCount OBJECT-TYPE
+ SYNTAX INTEGER (16..255)
+ ACCESS read-write
+
+
+
+
+
+
+
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4MaxInterSolicitCount when the station
+ is initialized."
+ ::= { dot4InitEntry 3 }
+
+ dot4InitMaxRetries OBJECT-TYPE
+ SYNTAX INTEGER (0..7)
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object dot4MaxRetries
+ when the station is initialized."
+ ::= { dot4InitEntry 4 }
+
+ dot4InitHiPriTokenHoldTime OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4HiPriTokenHoldTime when the station
+ is initialized."
+ ::= { dot4InitEntry 5 }
+
+ dot4InitTargetRotTimeClass4 OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4TargetRotTimeClass4 when the station
+ is initialized."
+ ::= { dot4InitEntry 6 }
+
+ dot4InitTargetRotTimeClass2 OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4TargetRotTimeClass2 when the station
+ is initialized."
+ ::= { dot4InitEntry 7 }
+
+
+
+
+
+
+
+ dot4InitTargetRotTimeClass0 OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4TargetRotTimeClass0 when the station
+ is initialized."
+ ::= { dot4InitEntry 8 }
+
+ dot4InitTargetRotTimeRingMaint OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4TargetRotTimeRingMaint when the station
+ is initialized."
+ ::= { dot4InitEntry 9 }
+
+ dot4InitRingMaintTimerInitValue OBJECT-TYPE
+ SYNTAX OctetTime
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4RingMaintTimerInitValue when the station
+ is initialized."
+ ::= { dot4InitEntry 10 }
+
+ dot4InitMinPostSilencePreambLen OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The value assigned to the object
+ dot4MinPostSilencePreambLen when the station
+ is initialized."
+ ::= { dot4InitEntry 11 }
+
+ dot4InitInRingDesired OBJECT-TYPE
+ SYNTAX INTEGER {
+ inRing(1),
+ outOfRing(2)
+ }
+
+
+
+
+
+
+
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "This object determines whether the station will
+ attempt to enter the logical ring immediately
+ after initialization."
+ ::= { dot4InitEntry 12 }
+
+
+ -- 802.4 Statistics Table
+
+ -- This table contains Token Bus statistics, one entry per 802.4
+ -- interface. It is mandatory that systems having 802.4 interfaces
+ -- implement this table.
+
+ dot4StatsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot4StatsEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A table containing Token Bus statistics.
+ All the statistics are defined using the syntax
+ Counter as 32 bit wrap around counters. Thus, if
+ an interface's hardware chip set maintains these
+ statistics in 16-bit counters, then the agent must
+ read the hardware's counters frequently enough to
+ prevent loss of significance, in order to maintain
+ a 32-bit counter in software."
+ ::= { dot4 3 }
+
+ dot4StatsEntry OBJECT-TYPE
+ SYNTAX Dot4StatsEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "An entry containing the 802.4 statistics for a
+ particular interface."
+ INDEX { dot4StatsIfIndex }
+ ::= { dot4StatsTable 1 }
+
+ Dot4StatsEntry ::= SEQUENCE {
+ dot4StatsIfIndex
+ INTEGER,
+ dot4StatsTokenPasses
+ Counter,
+
+
+
+
+
+
+
+ dot4StatsTokenHeards
+ Counter,
+ dot4StatsNoSuccessors
+ Counter,
+ dot4StatsWhoFollows
+ Counter,
+ dot4StatsTokenPassFails
+ Counter,
+ dot4StatsNonSilences
+ Counter,
+ dot4StatsFcsErrors
+ Counter,
+ dot4StatsEbitErrors
+ Counter,
+ dot4StatsFrameFrags
+ Counter,
+ dot4StatsFrameTooLongs
+ Counter,
+ dot4StatsOverRuns
+ Counter,
+ dot4StatsDupAddresses
+ Counter
+ }
+
+ dot4StatsIfIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value of this object identifies the 802.4
+ interface for which this entry contains management
+ information. The value of this object for a
+ particular interface has the same value as the
+ ifIndex object, defined in [4,6], for the same
+ interface."
+ ::= { dot4StatsEntry 1 }
+
+ dot4StatsTokenPasses OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS optional
+ DESCRIPTION
+ "The number of times this station has passed
+ the token."
+ ::= { dot4StatsEntry 2 }
+
+
+
+
+
+
+
+ dot4StatsTokenHeards OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS optional
+ DESCRIPTION
+ "The number of tokens heard by this station."
+ ::= { dot4StatsEntry 3 }
+
+ dot4StatsNoSuccessors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times the station could not find
+ a successor while believing itself not the only
+ station in the ring. This can signify a faulty
+ transmitter condition in this station."
+ ::= { dot4StatsEntry 4 }
+
+ dot4StatsWhoFollows OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times the station has had to look
+ for a new next station."
+ ::= { dot4StatsEntry 5 }
+
+ dot4StatsTokenPassFails OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times the station failed in
+ passing the token to the next station."
+ ::= { dot4StatsEntry 6 }
+
+ dot4StatsNonSilences OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of occurrences of non-silence
+ followed by silence in which a start delimiter
+ was not detected."
+
+
+
+
+
+
+
+ ::= { dot4StatsEntry 7 }
+
+ dot4StatsFcsErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of frames received with an incorrect
+ FCS and the E-bit reset."
+ ::= { dot4StatsEntry 8 }
+
+ dot4StatsEbitErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of frames the station received with
+ the E-bit set in the end delimiter."
+ ::= { dot4StatsEntry 9 }
+
+ dot4StatsFrameFrags OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of occurrences of receiving a start
+ delimiter followed by another start delimiter,
+ an invalid symbol sequence or silence, without
+ an intervening end delimiter."
+ ::= { dot4StatsEntry 10 }
+
+ dot4StatsFrameTooLongs OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of frames that were received that were
+ larger than the media's MTU."
+ ::= { dot4StatsEntry 11 }
+
+ dot4StatsOverRuns OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+
+
+
+
+
+
+
+ "The number of times a FIFO overrun was detected
+ in the station."
+ ::= { dot4StatsEntry 12 }
+
+ dot4StatsDupAddresses OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times this station detected another
+ station using the same MAC address."
+ ::= { dot4StatsEntry 13 }
+
+
+ -- 802.4 Interface Tests
+
+ dot4Tests OBJECT IDENTIFIER ::= { dot4 5 }
+
+ -- The extensions to the interfaces table proposed in [11]
+ -- define a table object, ifExtnsTestTable, through which a
+ -- network manager can instruct an agent to test an interface
+ -- for various faults. A test to be performed is identified
+ -- (as the value of ifExtnsTestType) via an OBJECT IDENTIFIER.
+
+ -- When a test fails, the object ifExtnsTestCode, defined in [11],
+ -- may contain a media-specific error-code. For 802.4 interfaces,
+ -- the following is defined as the value of ifExtnsTestCode when
+ -- a test fails because the modem could not be initialized:
+
+ dot4Errors OBJECT IDENTIFIER ::= { dot4 4 }
+ dot4ModemInitFailed OBJECT IDENTIFIER ::= { dot4Errors 1 }
+
+ -- The Full-Duplex Loop Back Test is a common test, defined
+ -- in [11] as:
+ --
+ -- testFullDuplexLoopBack
+ --
+ -- Invoking this test on a 802.4 interface causes the interface
+ -- to check the path from memory through the chip set's serial
+ -- interface back to memory, thus checking the proper functioning
+ -- of the transmit and receive machines of the token bus hardware.
+ -- This test may only be invoked when the interface is the Offline
+ -- state.
+
+
+
+
+
+
+
+
+
+ -- The FIFO Path test is defined by:
+
+ testFifoPath OBJECT IDENTIFIER ::= { dot4Tests 1 }
+
+ -- Invoking this test causes the interface to check the path
+ -- from memory to the chip set's FIFO and back to memory. This test
+ -- checks the hosts interface to the token bus hardware. This test
+ -- may only be invoked when the interface is the Offline state.
+
+ -- The External Loopback test is defined by:
+
+ testExternalLoopback OBJECT IDENTIFIER ::= { dot4Tests 2 }
+
+ -- Invoking this test causes the interface to check the path
+ -- from memory through the chip set and out onto the network
+ -- for external (e.g. at the head-end) loopback through the chip
+ -- set to memory. This test checks the host's interface to the
+ -- 802.4 network. This test is liable to cause serious disruption
+ -- if invoked on an operational network.
+
+
+
+ -- 802.4 Hardware Chip Sets
+
+ dot4ChipSets OBJECT IDENTIFIER ::= { dot4 6 }
+
+ -- The extensions to the interfaces table proposed in [11] define
+ -- an object, ifExtnsChipSet, with the syntax of OBJECT IDENTIFIER,
+ -- to identify the hardware chip set in use by an interface. That
+ -- definition specifies just one applicable object identifier:
+ --
+ -- unknownChipSet
+ --
+ -- for use as the value of ifExtnsChipSet when the specific chip
+ -- set is unknown.
+ --
+ -- This MIB defines the following for use as values of ifExtnsChipSet:
+ -- for use as values of ifExtnsChipSet
+
+ -- Motorola 68824 Token Bus Controller
+ chipSetMc68824 OBJECT IDENTIFIER ::= { dot4ChipSets 1 }
+
+ END
--- /dev/null
+-- tokenbus.my - Token Ring MIB
+
+-- $Header: /f/osi/snmp/RCS/tokenring.my,v 7.2 91/02/22 09:44:47 mrose Interim $
+--
+--
+-- $Log: tokenring.my,v $
+-- Revision 7.2 91/02/22 09:44:47 mrose
+-- Interim 6.8
+--
+-- Revision 7.1 91/01/11 13:02:52 mrose
+-- update
+--
+-- Revision 7.0 90/09/28 09:51:21 mrose
+-- *** empty log message ***
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+ RFCxxxx-MIB DEFINITIONS ::= BEGIN
+
+ -- IEEE 802.5 Token Ring MIB
+
+ IMPORTS
+ experimental
+ FROM RFC1155-SMI
+ OBJECT-TYPE
+ FROM RFC-oooo;
+
+ -- This MIB Module uses the extended OBJECT-TYPE macro as
+ -- defined in [9].
+
+
+
+ dot5 OBJECT IDENTIFIER ::= { experimental 4 }
+
+ -- All representations of MAC addresses in this MIB Module use,
+ -- as a textual convention (i.e. this convention does not affect
+ -- their encoding), the data type:
+
+ MacAddress ::= OCTET STRING (SIZE (6)) -- a 6 octet address in
+ -- the "canonical" order
+ -- defined by IEEE 802.1a, i.e., as if it were transmitted least
+ -- significant bit first, even though 802.5 (in contrast to other
+ -- 802.x protocols) requires MAC addresses to be transmitted most
+ -- significant bit first.
+ --
+ -- 16-bit addresses, if needed, are represented by setting their
+ -- upper 4 octets to all 0's, i.e., AAFF would be represented
+ -- as 00000000AAFF.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -- The Interface Table
+
+ -- This table contains state and parameter information which is
+ -- specific to 802.5 interfaces. It is mandatory that systems
+ -- having 802.5 interfaces implement this table in addition to the
+ -- generic interfaces table [4,6] and its generic extensions [11].
+
+ dot5Table OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot5Entry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "This table contains Token Ring interface
+ parameters and state variables, one entry
+ per 802.5 interface."
+ ::= { dot5 1 }
+
+ dot5Entry OBJECT-TYPE
+ SYNTAX Dot5Entry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A list of Token Ring status and parameter
+ values for an 802.5 interface."
+ INDEX { dot5IfIndex }
+ ::= { dot5Table 1 }
+
+ Dot5Entry
+ ::= SEQUENCE {
+ dot5IfIndex
+ INTEGER,
+ dot5Commands
+ INTEGER,
+ dot5RingStatus
+ INTEGER,
+ dot5RingState
+ INTEGER,
+ dot5RingOpenStatus
+ INTEGER,
+ dot5RingSpeed
+ INTEGER,
+ dot5UpStream
+ MacAddress,
+ dot5ActMonParticipate
+ INTEGER,
+
+
+
+
+
+
+
+ dot5Functional
+ MacAddress
+ }
+
+ dot5IfIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value of this object identifies the
+ 802.5 interface for which this entry contains
+ management information. The value of this
+ object for a particular interface has the same
+ value as the ifIndex object, defined in [4,6],
+ for the same interface."
+ ::= { dot5Entry 1 }
+
+ dot5Commands OBJECT-TYPE
+ SYNTAX INTEGER {
+ no-op(1),
+ open(2),
+ reset(3),
+ close(4)
+ }
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "When this object is set to the value of open(2),
+ the station should go into the open state. The
+ progress and success of the open is given by the
+ values of the objects dot5RingState and
+ dot5RingOpenStatus.
+ When this object is set to the value of
+ reset(3), then the station should do a reset.
+ On a reset, all MIB counters should retain their
+ values, if possible. Other side affects are
+ dependent on the hardware chip set.
+ When this object is set to the value of
+ close(4), the station should go into the stopped
+ state by removing itself from the ring.
+ Setting this object to a value of no-op(1)
+ has no effect.
+ When read, this object always has a value
+ of no-op(1)."
+ ::= { dot5Entry 2 }
+
+
+
+
+
+
+
+ dot5RingStatus OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The current interface status which can be used
+ to diagnose fluctuating problems that can occur
+ on token rings, after a station has successfully
+ been added to the ring.
+ Before an open is completed, this object has
+ the value for the 'no status' condition. The
+ dot5RingState and dot5RingOpenStatus objects
+ provide for debugging problems when the station
+ can not even enter the ring.
+ The object's value is a sum of values, one
+ for each currently applicable condition. The
+ following values are defined for various
+ conditions:
+
+ 0 = No Problems detected
+ 32 = Ring Recovery
+ 64 = Single Station
+ 256 = Remove Received
+ 512 = reserved
+ 1024 = Auto-Removal Error
+ 2048 = Lobe Wire Fault
+ 4096 = Transmit Beacon
+ 8192 = Soft Error
+ 16384 = Hard Error
+ 32768 = Signal Loss
+ 131072 = no status, open not completed."
+ ::= { dot5Entry 3 }
+
+ dot5RingState OBJECT-TYPE
+ SYNTAX INTEGER {
+ opened(1),
+ closed(2),
+ opening(3),
+ closing(4),
+ openFailure(5),
+ ringFailure(6)
+ }
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+
+
+
+
+
+
+
+ "The current interface state with respect to
+ entering or leaving the ring."
+ ::= { dot5Entry 4 }
+
+ dot5RingOpenStatus OBJECT-TYPE
+ SYNTAX INTEGER {
+ noOpen(1), -- no open attempted
+ badParam(2),
+ lobeFailed(3),
+ signalLoss(4),
+ insertionTimeout(5),
+ ringFailed(6),
+ beaconing(7),
+ duplicateMAC(8),
+ requestFailed(9),
+ removeReceived(10),
+ open(11) -- last open successful
+ }
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This object indicates the success, or the
+ reason for failure, of the station's most
+ recent attempt to enter the ring."
+ ::= { dot5Entry 5 }
+
+ dot5RingSpeed OBJECT-TYPE
+ SYNTAX INTEGER {
+ unknown(1),
+ oneMegabit(2),
+ fourMegabit(3),
+ sixteenMegabit(4)
+ }
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The ring's bandwidth."
+ ::= { dot5Entry 6 }
+
+ dot5UpStream OBJECT-TYPE
+ SYNTAX MacAddress
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The MAC-address of the up stream neighbor
+
+
+
+
+
+
+
+ station in the ring."
+ ::= { dot5Entry 7 }
+
+ dot5ActMonParticipate OBJECT-TYPE
+ SYNTAX INTEGER {
+ true(1),
+ false(2)
+ }
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "If this object has a value of true(1) then
+ this interface will participate in the active
+ monitor selection process. If the value is
+ false(2) then it will not. Setting this
+ object might not have an effect until the
+ next time the interface is opened."
+ ::= { dot5Entry 8 }
+
+ dot5Functional OBJECT-TYPE
+ SYNTAX MacAddress
+ ACCESS read-write
+ STATUS mandatory
+ DESCRIPTION
+ "The bit mask of all Token Ring functional
+ addresses for which this interface will
+ accept frames."
+ ::= { dot5Entry 9 }
+
+
+
+ -- The Statistics Table
+
+ -- This table contains statistics and error counter which are
+ -- specific to 802.5 interfaces. It is mandatory that systems
+ -- having 802.5 interfaces implement this table.
+
+ dot5StatsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot5StatsEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A table containing Token Ring statistics,
+ one entry per 802.5 interface.
+ All the statistics are defined using the
+
+
+
+
+
+
+
+ syntax Counter as 32-bit wrap around counters.
+ Thus, if an interface's hardware maintains these
+ statistics in 16-bit counters, then the agent
+ must read the hardware's counters frequently
+ enough to prevent loss of significance, in
+ order to maintain 32-bit counters in software."
+ ::= { dot5 2 }
+
+ dot5StatsEntry OBJECT-TYPE
+ SYNTAX Dot5StatsEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "An entry contains the 802.5 statistics for a
+ particular interface."
+ INDEX { dot5StatsIfIndex }
+ ::= { dot5StatsTable 1 }
+
+ Dot5StatsEntry
+ ::= SEQUENCE {
+ dot5StatsIfIndex
+ INTEGER,
+ dot5StatsLineErrors
+ Counter,
+ dot5StatsBurstErrors
+ Counter,
+ dot5StatsACErrors
+ Counter,
+ dot5StatsAbortTransErrors
+ Counter,
+ dot5StatsInternalErrors
+ Counter,
+ dot5StatsLostFrameErrors
+ Counter,
+ dot5StatsReceiveCongestions
+ Counter,
+ dot5StatsFrameCopiedErrors
+ Counter,
+ dot5StatsTokenErrors
+ Counter,
+ dot5StatsSoftErrors
+ Counter,
+ dot5StatsHardErrors
+ Counter,
+ dot5StatsSignalLoss
+
+
+
+
+
+
+
+ Counter,
+ dot5StatsTransmitBeacons
+ Counter,
+ dot5StatsRecoverys
+ Counter,
+ dot5StatsLobeWires
+ Counter,
+ dot5StatsRemoves
+ Counter,
+ dot5StatsSingles
+ Counter,
+ dot5StatsFreqErrors
+ Counter
+ }
+
+ dot5StatsIfIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value of this object identifies the
+ 802.5 interface for which this entry contains
+ management information. The value of this
+ object for a particular interface has the
+ same value as the ifIndex object, defined
+ in [4,6], for the same interface."
+ ::= { dot5StatsEntry 1 }
+
+ dot5StatsLineErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a frame or
+ token is copied or repeated by a station, the
+ E bit is zero in the frame or token and one of
+ the following conditions exists: 1) there is a
+ non-data bit (J or K bit) between the SD and
+ the ED of the frame or token, or 2) there is an
+ FCS error in the frame."
+ ::= { dot5StatsEntry 2 }
+
+ dot5StatsBurstErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+
+
+
+
+
+
+
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ detects the absence of transitions for five
+ half-bit timers (burst-five error)."
+ ::= { dot5StatsEntry 3 }
+
+ dot5StatsACErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ receives an AMP or SMP frame in which A is
+ equal to C is equal to 0, and then receives
+ another SMP frame with A is equal to C is
+ equal to 0 without first receiving an AMP
+ frame. It denotes a station that cannot set
+ the AC bits properly."
+ ::= { dot5StatsEntry 4 }
+
+ dot5StatsAbortTransErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ transmits an abort delimiter while transmitting."
+ ::= { dot5StatsEntry 5 }
+
+ dot5StatsInternalErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ recognizes an internal error."
+ ::= { dot5StatsEntry 6 }
+
+ dot5StatsLostFrameErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+
+
+
+
+
+
+
+ is transmitting and its TRR timer expires.
+ This condition denotes a condition where a
+ transmitting station in strip mode does not
+ receive the trailer of the frame before the
+ TRR timer goes off."
+ ::= { dot5StatsEntry 7 }
+
+ dot5StatsReceiveCongestions OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ recognizes a frame addressed to its specific
+ address, but has no available buffer space
+ indicating that the station is congested."
+ ::= { dot5StatsEntry 8 }
+
+ dot5StatsFrameCopiedErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ recognizes a frame addressed to its specific
+ address and detects that the FS field A bits
+ are set to 1 indicating a possible line hit
+ or duplicate address."
+ ::= { dot5StatsEntry 9 }
+
+ dot5StatsTokenErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "This counter is incremented when a station
+ acting as the active monitor recognizes an
+ error condition that needs a token transmitted."
+ ::= { dot5StatsEntry 10 }
+
+ dot5StatsSoftErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+
+
+
+
+
+
+
+ "The number of Soft Errors the interface has
+ detected. It directly corresponds to the number
+ of Report Error MAC frames that this interface
+ has transmitted. Soft Errors are those which are
+ recoverable by the MAC layer protocols."
+ ::= { dot5StatsEntry 11 }
+
+ dot5StatsHardErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times this interface has
+ detected an immediately recoverable fatal error.
+ It denotes the number of times this interface
+ is either transmitting or receiving beacon
+ MAC frames."
+ ::= { dot5StatsEntry 12 }
+
+ dot5StatsSignalLoss OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times this interface has
+ detected the loss of signal condition from
+ the ring."
+ ::= { dot5StatsEntry 13 }
+
+ dot5StatsTransmitBeacons OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times this interface has
+ transmitted a beacon frame."
+ ::= { dot5StatsEntry 14 }
+
+ dot5StatsRecoverys OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of Claim Token MAC frames
+ received or transmitted after the interface
+
+
+
+
+
+
+
+ has received a Ring Purge MAC frame. This
+ counter signifies the number of times the
+ ring has been purged and is being recovered
+ back into a normal operating state."
+ ::= { dot5StatsEntry 15 }
+
+ dot5StatsLobeWires OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times the interface has
+ detected an open or short circuit in the
+ lobe data path. The adapter will be closed
+ and dot5RingState will signify this condition."
+ ::= { dot5StatsEntry 16 }
+
+ dot5StatsRemoves OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times the interface has received
+ a Remove Ring Station MAC frame request. When
+ this frame is received the interface will enter
+ the close state and dot5RingState will signify
+ this condition."
+ ::= { dot5StatsEntry 17 }
+
+ dot5StatsSingles OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The number of times the interface has sensed
+ that it is the only station on the ring. This
+ will happen if the interface is the first one
+ up on a ring, or if there is a hardware problem."
+ ::= { dot5StatsEntry 18 }
+
+ dot5StatsFreqErrors OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS optional
+ DESCRIPTION
+
+
+
+
+
+
+
+ "The number of times the interface has detected
+ that the frequency of the incoming signal differs
+ from the expected frequency by more than that
+ ispecified by the IEEE 802.5 standard, see
+ chapter 7 in [10]."
+ ::= { dot5StatsEntry 19 }
+
+
+ -- The Timer Table
+
+ -- This group contains the values of the timers defined in [10]
+ -- for 802.5 interfaces. It is optional that systems having 802.5
+ -- interfaces implement this group.
+
+ dot5TimerTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot5TimerEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "This table contains Token Ring interface
+ timer values, one entry per 802.5 interface."
+ ::= { dot5 5 }
+
+ dot5TimerEntry OBJECT-TYPE
+ SYNTAX Dot5TimerEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ DESCRIPTION
+ "A list of Token Ring timer values for an 802.5
+ interface."
+ INDEX { dot5TimerIfIndex }
+ ::= { dot5TimerTable 1 }
+
+ Dot5TimerEntry
+ ::= SEQUENCE {
+ dot5TimerIfIndex
+ INTEGER,
+ dot5TimerReturnRepeat
+ INTEGER,
+ dot5TimerHolding
+ INTEGER,
+ dot5TimerQueuePDU
+ INTEGER,
+ dot5TimerValidTransmit
+ INTEGER,
+
+
+
+
+
+
+
+ dot5TimerNoToken
+ INTEGER,
+ dot5TimerActiveMon
+ INTEGER,
+ dot5TimerStandbyMon
+ INTEGER,
+ dot5TimerErrorReport
+ INTEGER,
+ dot5TimerBeaconTransmit
+ INTEGER,
+ dot5TimerBeaconReceive
+ INTEGER
+ }
+
+ dot5TimerIfIndex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The value of this object identifies the
+ 802.5 interface for which this entry contains
+ timer values. The value of this object for a
+ particular interface has the same value as the
+ ifIndex object, defined in [4,6], for the same
+ interface."
+ ::= { dot5TimerEntry 1 }
+
+ dot5TimerReturnRepeat OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value used to ensure the
+ interface will return to Repeat State, in
+ units of 100 micro-seconds. The value should
+ be greater than the maximum ring latency.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 2 }
+
+ dot5TimerHolding OBJECT-TYPE
+ SYNTAX INTEGER
+
+
+
+
+
+
+
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "Maximum period of time a station is
+ permitted to transmit frames after capturing
+ a token, in units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 3 }
+
+ dot5TimerQueuePDU OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value for enqueuing of an SMP
+ PDU after reception of an AMP or SMP frame in
+ which the A and C bits were equal to 0, in
+ units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 4 }
+
+ dot5TimerValidTransmit OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value used by the active monitor
+ to detect the absence of valid transmissions,
+ in units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 5 }
+
+ dot5TimerNoToken OBJECT-TYPE
+
+
+
+
+
+
+
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value used to recover from
+ various-related error situations [9]. If N is
+ the maximum number of stations on the ring,
+ the value of this timer is normally:
+ dot5TimerReturnRepeat + N*dot5TimerHolding.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 6 }
+
+ dot5TimerActiveMon OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value used by the active monitor
+ to stimulate the enqueuing of an AMP PDU for
+ transmission, in units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 7 }
+
+ dot5TimerStandbyMon OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value used by the stand-by
+ monitors to ensure that there is an active
+ monitor on the ring and to detect a continuous
+ stream of tokens, in units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+
+
+
+
+
+
+
+ ::= { dot5TimerEntry 8 }
+
+ dot5TimerErrorReport OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value which determines how often a
+ station shall send a Report Error MAC frame to
+ report its error counters, in units of 100
+ micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 9 }
+
+ dot5TimerBeaconTransmit OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value which determines how long a
+ station shall remain in the state of transmitting
+ Beacon frames before entering the Bypass state,
+ in units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 10 }
+
+ dot5TimerBeaconReceive OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ DESCRIPTION
+ "The time-out value which determines how long a
+ station shall receive Beacon frames from its
+ downstream neighbor before entering the Bypass
+ state, in units of 100 micro-seconds.
+ Implementors are encouraged to provide
+ read-write access to this object if that is
+
+
+
+
+
+
+
+ possible/useful in their system, but giving
+ due consideration to the dangers of write-able
+ timers."
+ ::= { dot5TimerEntry 11 }
+
+
+ -- 802.5 Interface Tests
+
+ dot5Tests OBJECT IDENTIFIER ::= { dot5 3 }
+
+ -- The extensions to the interfaces table proposed in [11]
+ -- define a table object, ifExtnsTestTable, through which a
+ -- network manager can instruct an agent to test an interface
+ -- for various faults. A test to be performed is identified
+ -- (as the value of ifExtnsTestType) via an OBJECT IDENTIFIER.
+ --
+ -- The Full-Duplex Loop Back Test is a common test, defined
+ -- in [11] as:
+ --
+ -- testFullDuplexLoopBack
+ --
+ -- Invoking this test on a 802.5 interface causes the interface
+ -- to check the path from memory through the chip set's internal
+ -- logic and back to memory, thus checking the proper functioning
+ -- of the systems's interface to the chip set.
+
+
+ -- The Insert Function test is defined by:
+
+ testInsertFunc OBJECT IDENTIFIER ::= { dot5Tests 1 }
+
+ -- Invoking this test causes the station to test the insert ring
+ -- logic of the hardware if the station's lobe media cable is
+ -- connected to a wiring concentrator. Note that this command
+ -- inserts the station into the network, and thus, could cause
+ -- problems if the station is connected to a operational network.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ -- 802.5 Hardware Chip Sets
+
+ dot5ChipSets OBJECT IDENTIFIER ::= { dot5 4 }
+
+ -- The extensions to the interfaces table proposed in [11] define
+ -- an object, ifExtnsChipSet, with the syntax of OBJECT IDENTIFIER,
+ -- to identify the hardware chip set in use by an interface. That
+ -- definition specifies just one applicable object identifier:
+ --
+ -- unknownChipSet
+ --
+ -- for use as the value of ifExtnsChipSet when the specific chip
+ -- set is unknown.
+ --
+ -- This MIB defines the following for use as values of ifExtnsChipSet:
+
+ -- IBM 16/4 Mb/s
+ chipSetIBM16 OBJECT IDENTIFIER ::= { dot5ChipSets 1 }
+
+ -- TI 4Mb/s
+ chipSetTItms380 OBJECT IDENTIFIER ::= { dot5ChipSets 2 }
+
+ -- TI 16/4 Mb/s
+ chipSetTItms380c16 OBJECT IDENTIFIER ::= { dot5ChipSets 3 }
+
+ END
--- /dev/null
+/* udp.c - MIB realization of the UDP group */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/udp.c,v 7.7 91/02/22 09:44:50 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/RCS/udp.c,v 7.7 91/02/22 09:44:50 mrose Interim $
+ *
+ * Contributed by NYSERNet Inc. This work was partially supported by the
+ * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+ * Center of the U.S. Air Force Systems Command under contract number
+ * F30602-88-C-0016.
+ *
+ *
+ * $Log: udp.c,v $
+ * Revision 7.7 91/02/22 09:44:50 mrose
+ * Interim 6.8
+ *
+ * Revision 7.6 91/01/08 12:48:51 mrose
+ * update
+ *
+ * Revision 7.5 90/12/18 10:14:19 mrose
+ * update
+ *
+ * Revision 7.4 90/10/02 09:55:03 mrose
+ * normalize again
+ *
+ * Revision 7.3 90/04/23 00:08:20 mrose
+ * touch-up
+ *
+ * Revision 7.2 90/04/18 08:52:09 mrose
+ * oid_normalize
+ *
+ * Revision 7.1 90/02/27 18:50:10 mrose
+ * unix stuff
+ *
+ * Revision 7.0 89/11/23 22:23:38 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+
+#include "internet.h"
+#ifdef BSD44
+#include <sys/param.h>
+#endif
+#include <net/route.h>
+#include <sys/socketvar.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/in_pcb.h>
+#include <netinet/ip_var.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+/* \f */
+
+static struct udpstat udpstat;
+
+/* \f */
+
+#ifdef BSD44
+#define udpInDatagrams 1
+#define udpNoPorts 2
+#endif
+#define udpInErrors 3
+#ifdef BSD44
+#define udpOutDatagrams 4
+#endif
+
+
+static int o_udp (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register struct udpstat *udps = &udpstat;
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+ static int lastq = -1;
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
+ || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((new = oid_extend (oid, 1)) == NULLOID)
+ return NOTOK;
+ new -> oid_elements[new -> oid_nelem - 1] = 0;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else
+ return NOTOK;
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (quantum != lastq) {
+ lastq = quantum;
+
+ if (getkmem (nl + N_UDPSTAT, (caddr_t) udps, sizeof *udps) == NOTOK)
+ return generr (offset);
+ }
+
+ switch (ifvar) {
+#ifdef udpInDatagrams
+ case udpInDatagrams:
+ return o_integer (oi, v, udps -> udps_ipackets);
+#endif
+
+#ifdef udpNoPorts
+ case udpNoPorts:
+ return o_integer (oi, v, udps -> udps_noport);
+#endif
+
+ case udpInErrors:
+ return o_integer (oi, v, udps -> udps_hdrops
+ + udps -> udps_badsum
+ + udps -> udps_badlen);
+
+#ifdef udpOutDatagrams
+ case udpOutDatagrams:
+ return o_integer (oi, v, udps -> udps_opackets);
+#endif
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+struct udptab {
+#define UT_SIZE 5 /* object instance */
+ unsigned int ut_instance[UT_SIZE];
+
+ struct inpcb ut_pcb; /* protocol control block */
+
+ struct socket ut_socb; /* socket info */
+
+ struct udptab *ut_next;
+};
+
+static struct udptab *uts = NULL;
+
+static int flush_udp_cache = 0;
+
+
+struct udptab *get_udpent ();
+
+/* \f */
+
+#define udpLocalAddress 0
+#define udpLocalPort 1
+#define unixUdpRemAddress 2
+#define unixUdpRemPort 3
+#define unixUdpSendQ 4
+#define unixUdpRecvQ 5
+
+
+static int o_udp_listen (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ register struct udptab *ut;
+ struct sockaddr_in netaddr;
+ register OID oid = oi -> oi_name;
+ OID new;
+ register OT ot = oi -> oi_type;
+
+ if (get_listeners (offset) == NOTOK)
+ return generr (offset);
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + UT_SIZE)
+ return int_SNMP_error__status_noSuchName;
+ if ((ut = get_udpent (oid -> oid_elements + oid -> oid_nelem
+ - UT_SIZE, 0)) == NULL)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if ((i = oid -> oid_nelem - ot -> ot_name -> oid_nelem) != 0
+ && i < UT_SIZE) {
+ for (jp = (ip = oid -> oid_elements + ot -> ot_name -> oid_nelem - 1) + i;
+ jp > ip;
+ jp--)
+ if (*jp != 0)
+ break;
+ if (jp == ip)
+ oid -> oid_nelem = ot -> ot_name -> oid_nelem;
+ else {
+ if ((new = oid_normalize (oid, UT_SIZE - i, 65536))
+ == NULLOID)
+ return NOTOK;
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = oid = new;
+ }
+ }
+ else
+ if (i > UT_SIZE)
+ oid -> oid_nelem = ot -> ot_name -> oid_nelem + UT_SIZE;
+
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ if ((ut = uts) == NULL)
+ return NOTOK;
+
+ if ((new = oid_extend (oid, UT_SIZE)) == NULLOID)
+ return NOTOK;
+ ip = new -> oid_elements + new -> oid_nelem - UT_SIZE;
+ jp = ut -> ut_instance;
+ for (i = UT_SIZE; i > 0; i--)
+ *ip++ = *jp++;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else {
+ if ((ut = get_udpent (ip = oid -> oid_elements
+ + oid -> oid_nelem - UT_SIZE, 1))
+ == NULL)
+ return NOTOK;
+
+ jp = ut -> ut_instance;
+ for (i = UT_SIZE; i > 0; i--)
+ *ip++ = *jp++;
+ }
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (ifvar) {
+ case udpLocalAddress:
+ netaddr.sin_addr = ut -> ut_pcb.inp_laddr; /* struct copy */
+ return o_ipaddr (oi, v, &netaddr);
+
+ case udpLocalPort:
+ return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_lport) & 0xffff);
+
+ case unixUdpRemAddress:
+ netaddr.sin_addr = ut -> ut_pcb.inp_faddr; /* struct copy */
+ return o_ipaddr (oi, v, &netaddr);
+
+ case unixUdpRemPort:
+ return o_integer (oi, v, ntohs (ut -> ut_pcb.inp_fport) & 0xffff);
+
+ case unixUdpSendQ:
+ return o_integer (oi, v, ut -> ut_socb.so_snd.sb_cc);
+
+ case unixUdpRecvQ:
+ return o_integer (oi, v, ut -> ut_socb.so_rcv.sb_cc);
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+static int ut_compar (a, b)
+struct udptab **a,
+ **b;
+{
+ return elem_cmp ((*a) -> ut_instance, UT_SIZE,
+ (*b) -> ut_instance, UT_SIZE);
+}
+
+
+static int get_listeners (offset)
+int offset;
+{
+ register int i;
+ register unsigned int *cp;
+ register struct udptab *us,
+ *up,
+ **usp;
+ register struct inpcb *ip;
+ struct inpcb *head,
+ udb,
+ zdb;
+ struct nlist nzs;
+ register struct nlist *nz = &nzs;
+ static int first_time = 1;
+ static int lastq = -1;
+
+ if (quantum == lastq)
+ return OK;
+ if (!flush_udp_cache
+ && offset == type_SNMP_PDUs_get__next__request
+ && quantum == lastq + 1) { /* XXX: caching! */
+ lastq = quantum;
+ return OK;
+ }
+ lastq = quantum, flush_udp_cache = 0;
+
+ for (us = uts; us; us = up) {
+ up = us -> ut_next;
+
+ free ((char *) us);
+ }
+ uts = NULL;
+
+ if (getkmem (nl + N_UDB, (char *) &udb, sizeof udb) == NOTOK)
+ return NOTOK;
+ head = (struct inpcb *) nl[N_UDB].n_value;
+
+ usp = &uts, i = 0;
+ ip = &udb;
+ while (ip -> inp_next != head) {
+ register struct udptab *uz;
+ OIDentifier oids;
+
+ if ((us = (struct udptab *) calloc (1, sizeof *us)) == NULL)
+ adios (NULLCP, "out of memory");
+
+ nz -> n_name = "struct inpcb",
+ nz -> n_value = (unsigned long) ip -> inp_next;
+ if (getkmem (nz, (caddr_t) &us -> ut_pcb, sizeof us -> ut_pcb)
+ == NOTOK)
+ return NOTOK;
+ ip = &us -> ut_pcb;
+
+ nz ->n_name = "struct socket",
+ nz -> n_value = (unsigned long) ip -> inp_socket;
+ if (getkmem (nz, (caddr_t) &us -> ut_socb, sizeof us -> ut_socb)
+ == NOTOK)
+ return NOTOK;
+
+ cp = us -> ut_instance;
+ cp += ipaddr2oid (cp, &ip -> inp_laddr);
+ *cp++ = ntohs (ip -> inp_lport) & 0xffff;
+
+ for (uz = uts; uz; uz = uz -> ut_next)
+ if (elem_cmp (uz -> ut_instance, UT_SIZE,
+ us -> ut_instance, UT_SIZE) == 0)
+ break;
+ if (uz) {
+ if (first_time) {
+ oids.oid_elements = us -> ut_instance;
+ oids.oid_nelem = UT_SIZE;
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "duplicate listeners: %s", sprintoid (&oids));
+ }
+
+ *(ip = &zdb) = us -> ut_pcb; /* struct copy */
+ free ((char *) us);
+ continue;
+ }
+ *usp = us, usp = &us -> ut_next, i++;
+
+ if (debug && first_time) {
+ oids.oid_elements = us -> ut_instance;
+ oids.oid_nelem = UT_SIZE;
+ advise (LLOG_DEBUG, NULLCP,
+ "add listener: %s", sprintoid (&oids));
+ }
+ }
+ first_time = 0;
+
+ if (i > 1) {
+ register struct udptab **base,
+ **use;
+
+ if ((base = (struct udptab **) malloc ((unsigned) (i * sizeof *base)))
+ == NULL)
+ adios (NULLCP, "out of memory");
+
+ use = base;
+ for (us = uts; us; us = us -> ut_next)
+ *use++ = us;
+
+ qsort ((char *) base, i, sizeof *base, ut_compar);
+
+ usp = base;
+ us = uts = *usp++;
+
+ while (usp < use) {
+ us -> ut_next = *usp;
+ us = *usp++;
+ }
+ us -> ut_next = NULL;
+
+ free ((char *) base);
+ }
+
+ return OK;
+}
+
+/* \f */
+
+static struct udptab *get_udpent (ip, isnext)
+register unsigned int *ip;
+int isnext;
+{
+ register struct udptab *ut;
+
+ for (ut = uts; ut; ut = ut -> ut_next)
+ switch (elem_cmp (ut -> ut_instance, UT_SIZE, ip, UT_SIZE)) {
+ case 0:
+ if (!isnext)
+ return ut;
+ if ((ut = ut -> ut_next) == NULL)
+ goto out;
+ /* else fall... */
+
+ case 1:
+ return (isnext ? ut : NULL);
+ }
+
+out: ;
+ flush_udp_cache = 1;
+
+ return NULL;
+}
+
+/* \f */
+
+init_udp () {
+ register OT ot;
+
+#ifdef udpInDatagrams
+ if (ot = text2obj ("udpInDatagrams"))
+ ot -> ot_getfnx = o_udp,
+ ot -> ot_info = (caddr_t) udpInDatagrams;
+#endif
+#ifdef udpNoPorts
+ if (ot = text2obj ("udpNoPorts"))
+ ot -> ot_getfnx = o_udp,
+ ot -> ot_info = (caddr_t) udpNoPorts;
+#endif
+ if (ot = text2obj ("udpInErrors"))
+ ot -> ot_getfnx = o_udp,
+ ot -> ot_info = (caddr_t) udpInErrors;
+#ifdef udpOutDatagrams
+ if (ot = text2obj ("udpOutDatagrams"))
+ ot -> ot_getfnx = o_udp,
+ ot -> ot_info = (caddr_t) udpOutDatagrams;
+#endif
+
+ if (ot = text2obj ("udpLocalAddress"))
+ ot -> ot_getfnx = o_udp_listen,
+ ot -> ot_info = (caddr_t) udpLocalAddress;
+ if (ot = text2obj ("udpLocalPort"))
+ ot -> ot_getfnx = o_udp_listen,
+ ot -> ot_info = (caddr_t) udpLocalPort;
+
+ if (ot = text2obj ("unixUdpRemAddress"))
+ ot -> ot_getfnx = o_udp_listen,
+ ot -> ot_info = (caddr_t) unixUdpRemAddress;
+ if (ot = text2obj ("unixUdpRemPort"))
+ ot -> ot_getfnx = o_udp_listen,
+ ot -> ot_info = (caddr_t) unixUdpRemPort;
+ if (ot = text2obj ("unixUdpSendQ"))
+ ot -> ot_getfnx = o_udp_listen,
+ ot -> ot_info = (caddr_t) unixUdpSendQ;
+ if (ot = text2obj ("unixUdpRecvQ"))
+ ot -> ot_getfnx = o_udp_listen,
+ ot -> ot_info = (caddr_t) unixUdpRecvQ;
+}
--- /dev/null
+UNIX-MIB DEFINITIONS ::= BEGIN
+
+-- Title: BSD UNIX MIB
+-- Date: January 31, 1991
+-- By: Marshall T. Rose/PSI <mrose@psi.com>
+-- for Keith Sklower/UCB <sklower@okeeffe.berkeley.edu>
+
+
+IMPORTS
+ enterprises, OBJECT-TYPE, Counter, IpAddress, ObjectName
+ FROM RFC1065-SMI
+ DisplayString
+ FROM RFC1158-MIB;
+
+
+unix OBJECT IDENTIFIER ::= { enterprises 4 }
+
+
+-- the agents group
+
+agents OBJECT IDENTIFIER ::= { unix 1 }
+
+-- original "4BSD/ISODE SNMP" { agents 1 }
+
+-- versions of the "4BSD/ISODE SNMP" agent are now under { agents 2 }
+fourBSD-isode OBJECT IDENTIFIER ::={ agents 2 }
+-- fourBSD-isode.1: add SMUX
+-- fourBSD-isode.2: add views
+
+
+
+-- the mbuf group
+
+mbuf OBJECT IDENTIFIER ::= { unix 2 }
+
+mbufS OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 1 }
+
+mbufClusters OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 2 }
+
+mbufFreeClusters OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 3 }
+
+mbufDrops OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 4 }
+
+mbufWaits OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 5 }
+
+mbufDrains OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 6 }
+
+mbufFrees OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbuf 7 }
+
+mbufTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF MbufEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { mbuf 8 }
+
+mbufEntry OBJECT-TYPE
+ SYNTAX MbufEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { mbufType }
+ ::= { mbufTable 1 }
+
+MbufEntry ::= SEQUENCE {
+ mbufType
+ INTEGER,
+ mbufAllocates
+ INTEGER
+ }
+
+mbufType OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbufEntry 1 }
+
+mbufAllocates OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { mbufEntry 2 }
+
+
+
+-- the SMUX peer group
+
+peers OBJECT IDENTIFIER ::= { unix 3 }
+
+-- versions of the unixd program are under { peers 1 }
+unixd OBJECT IDENTIFIER ::= { peers 1}
+-- the current version is unixd.1
+
+
+
+-- the SMUX protocol group
+
+smux OBJECT IDENTIFIER ::= { unix 4 }
+
+smuxPeerTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SmuxPeerEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { smux 1 }
+
+smuxPeerEntry OBJECT-TYPE
+ SYNTAX SmuxPeerEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { smuxPindex }
+ ::= { smuxPeerTable 1}
+
+SmuxPeerEntry ::= SEQUENCE {
+ smuxPindex
+ INTEGER,
+ smuxPidentity
+ OBJECT IDENTIFIER,
+ smuxPdescription
+ DisplayString,
+ smuxPstatus
+ INTEGER
+}
+
+smuxPindex OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxPeerEntry 1 }
+
+smuxPidentity OBJECT-TYPE
+ SYNTAX ObjectName
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxPeerEntry 2 }
+
+smuxPdescription OBJECT-TYPE
+ SYNTAX DisplayString
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxPeerEntry 3 }
+
+smuxPstatus OBJECT-TYPE
+ SYNTAX INTEGER { valid(1), invalid(2), connecting(3) }
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxPeerEntry 4 }
+
+smuxTreeTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF SmuxTreeEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { smux 2 }
+
+smuxTreeEntry OBJECT-TYPE
+ SYNTAX SmuxTreeEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { smuxTsubtree, smuxTpriority }
+ ::= { smuxTreeTable 1}
+
+SmuxTreeEntry ::= SEQUENCE {
+ smuxTsubtree
+ ObjectName,
+ smuxTpriority
+ INTEGER,
+ smuxTindex
+ INTEGER,
+ smuxTstatus
+ INTEGER
+}
+
+smuxTsubtree OBJECT-TYPE
+ SYNTAX ObjectName
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxTreeEntry 1 }
+
+smuxTpriority OBJECT-TYPE
+ SYNTAX INTEGER (0..2147483647)
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxTreeEntry 2 }
+
+smuxTindex OBJECT-TYPE
+ SYNTAX INTEGER (0..2147483647)
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxTreeEntry 3 }
+
+smuxTstatus OBJECT-TYPE
+ SYNTAX INTEGER { valid(1), invalid(2) }
+ ACCESS read-write
+ STATUS mandatory
+ ::= { smuxTreeEntry 4 }
+
+
+-- the NETSTAT group
+
+netstat OBJECT IDENTIFIER ::= { unix 5 }
+
+unixNetstat OBJECT-TYPE
+ SYNTAX INTEGER { enabled(1), disabled(2) }
+ ACCESS read-only
+ STATUS mandatory
+ ::= { netstat 1 }
+
+-- the UNIX TCP connections table
+
+unixTcpConnTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF UnixTcpConnEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { netstat 2 }
+
+unixTcpConnEntry OBJECT-TYPE
+ SYNTAX UnixTcpConnEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { tcpConnLocalAddress, tcpConnLocalPort, tcpConnRemAddress, tcpConnRemPort }
+ ::= { unixTcpConnTable 1 }
+
+UnixTcpConnEntry ::= SEQUENCE {
+ unixTcpConnSendQ
+ INTEGER,
+ unixTcpConnRecvQ
+ INTEGER
+}
+
+unixTcpConnSendQ OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixTcpConnEntry 1 }
+
+unixTcpConnRecvQ OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixTcpConnEntry 2 }
+
+
+-- the UNIX UDP listener table
+
+unixUdpTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF UnixUdpEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { netstat 3 }
+
+unixUdpEntry OBJECT-TYPE
+ SYNTAX UnixUdpEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { udpLocalAddress, udpLocalPort }
+ ::= { unixUdpTable 1 }
+
+UnixUdpEntry ::= SEQUENCE {
+ unixUdpRemAddress
+ IpAddress,
+ unixUdpRemPort
+ INTEGER (0..65535),
+ unixUdpSendQ
+ INTEGER,
+ unixUdpRecvQ
+ INTEGER
+}
+
+unixUdpRemAddress OBJECT-TYPE
+ SYNTAX IpAddress
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixUdpEntry 1 }
+
+unixUdpRemPort OBJECT-TYPE
+ SYNTAX INTEGER (0..65535)
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixUdpEntry 2 }
+
+unixUdpSendQ OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixUdpEntry 3 }
+
+unixUdpRecvQ OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixUdpEntry 4 }
+
+-- the UNIX IP Routing table
+
+unixIpRoutingTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF UnixIpRouteEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { netstat 4 }
+
+unixIpRouteEntry OBJECT-TYPE
+ SYNTAX UnixIpRouteEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { ipRouteDest }
+ ::= { unixIpRoutingTable 1 }
+
+UnixIpRouteEntry ::= SEQUENCE {
+ unixIpRouteFlags
+ INTEGER,
+ unixIpRouteRefCnt
+ INTEGER,
+ unixIpRouteUses
+ Counter
+}
+
+unixIpRouteFlags OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixIpRouteEntry 1 }
+
+unixIpRouteRefCnt OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixIpRouteEntry 2 }
+
+unixIpRouteUses OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixIpRouteEntry 3 }
+
+-- miscellaneous UNIX routing statistics
+
+unixRouteBadRedirects OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { netstat 5 }
+
+unixRouteCreatedByRedirects OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { netstat 6 }
+
+unixRouteModifiedByRedirects OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { netstat 7 }
+
+unixRouteLookupFails OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { netstat 8 }
+
+unixRouteWildcardUses OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { netstat 9 }
+
+-- the UNIX CLNP Routing table
+
+unixClnpRoutingTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF UnixClnpRouteEntry
+ ACCESS not-accessible
+ STATUS mandatory
+ ::= { netstat 10 }
+
+unixClnpRouteEntry OBJECT-TYPE
+ SYNTAX UnixClnpRouteEntry
+ ACCESS not-accessible
+ STATUS mandatory
+-- INDEX { clnpRouteDest }
+ ::= { unixClnpRoutingTable 1 }
+
+UnixClnpRouteEntry ::= SEQUENCE {
+ unixClnpRouteFlags
+ INTEGER,
+ unixClnpRouteRefCnt
+ INTEGER,
+ unixClnpRouteUses
+ Counter
+}
+
+unixClnpRouteFlags OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixClnpRouteEntry 1 }
+
+unixClnpRouteRefCnt OBJECT-TYPE
+ SYNTAX INTEGER
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixClnpRouteEntry 2 }
+
+unixClnpRouteUses OBJECT-TYPE
+ SYNTAX Counter
+ ACCESS read-only
+ STATUS mandatory
+ ::= { unixClnpRouteEntry 3 }
+
+END
--- /dev/null
+.TH UNIXD 8C "17 Feb 1990"
+.\" $Header: /f/osi/snmp/RCS/unixd.8c,v 7.4 91/02/22 09:44:54 mrose Interim $
+.\"
+.\" Contributed by NYSERNet Inc. This work was partially supported by the
+.\" U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+.\" Center of the U.S. Air Force Systems Command under contract number
+.\" F30602-88-C-0016.
+.\"
+.\"
+.\" $Log: unixd.8c,v $
+.\" Revision 7.4 91/02/22 09:44:54 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.3 90/10/18 11:34:10 mrose
+.\" psi
+.\"
+.\" Revision 7.2 90/08/29 15:04:17 mrose
+.\" doc
+.\"
+.\" Revision 7.1 90/02/17 17:19:00 mrose
+.\" touch-up
+.\"
+.\" Revision 7.0 90/02/17 14:40:54 mrose
+.\" *** empty log message ***
+.\"
+.SH NAME
+unixd \- daemon for UNIX MIB
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDsmux.unixd
+\%[-d]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIunixd\fR daemon is a SMUX peer to the SNMP agent, \fIsnmpd\fR\0(8c).
+At present,
+it implements the \fImbuf\fR subtree of the UNIX MIB.
+.SH FILES
+.nf
+.ta \w'\*(EDunixd.log 'u
+\*(EDunixd.defs MIB definitions
+.re
+.fi
+.SH "NOTE WELL"
+The names of the various in \fBunixd.defs\fR are case sensitive.
+This was necessary to improve the efficiency of the hashing algorithm
+used for object lookup.
+.SH "SEE ALSO"
+snmpd(8c)
+.SH AUTHOR
+Marshall T. Rose,
+Performance Systems International
+.PP
+This work was partially supported by the
+U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+Center of the U.S. Air Force Systems Command under contract number
+F30602-88-C-0016.
+.PP
+Although this package is distributed with the ISODE,
+it is not an OSI program, per se.
+Inasmuch as the continued survival of the Internet hinges on all nodes
+becoming network manageable,
+this package was developed using the ISODE and is being freely
+distributed with releases of Berkeley UNIX.
--- /dev/null
+/* values.c - encode values */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/values.c,v 7.8 91/02/22 09:44:57 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/RCS/values.c,v 7.8 91/02/22 09:44:57 mrose Interim $
+ *
+ * Contributed by NYSERNet Inc. This work was partially supported by the
+ * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
+ * Center of the U.S. Air Force Systems Command under contract number
+ * F30602-88-C-0016.
+ *
+ *
+ * $Log: values.c,v $
+ * Revision 7.8 91/02/22 09:44:57 mrose
+ * Interim 6.8
+ *
+ * Revision 7.7 91/01/11 15:35:44 mrose
+ * sets
+ *
+ * Revision 7.6 90/12/18 10:14:25 mrose
+ * update
+ *
+ * Revision 7.5 90/10/29 18:39:14 mrose
+ * updates
+ *
+ * Revision 7.4 90/10/23 20:37:26 mrose
+ * update
+ *
+ * Revision 7.3 90/07/09 14:49:51 mrose
+ * sync
+ *
+ * Revision 7.2 90/04/18 08:52:12 mrose
+ * oid_normalize
+ *
+ * Revision 7.1 90/02/19 15:39:11 mrose
+ * one more time
+ *
+ * Revision 7.0 90/02/17 10:36:50 mrose
+ * *** empty log message ***
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include "SNMP-types.h"
+#include "objects.h"
+#include "logger.h"
+
+/* \f */
+
+#define ADVISE if (o_advise) (*o_advise)
+
+IFP o_advise = NULLIFP;
+
+/* \f */
+
+int o_generic (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+ register OS os = ot -> ot_syntax;
+
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
+ || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((new = oid_extend (oid, 1)) == NULLOID)
+ return NOTOK;
+ new -> oid_elements[new -> oid_nelem - 1] = 0;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else
+ return NOTOK;
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (os == NULLOS) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no syntax defined for object \"%s\"", ot -> ot_text);
+
+ return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
+ : int_SNMP_error__status_genErr);
+ }
+ if (ot -> ot_info == NULL) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no value defined for object \"%s\"", ot -> ot_text);
+
+ return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
+ : int_SNMP_error__status_noSuchName);
+ }
+
+ if (v -> value)
+ free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+ if ((*os -> os_encode) (ot -> ot_info, &v -> value) == NOTOK) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "encoding error for variable \"%s\"",
+ oid2ode (oi -> oi_name));
+
+ return (offset == type_SNMP_PDUs_get__next__request ? NOTOK
+ : int_SNMP_error__status_genErr);
+ }
+
+ return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int s_generic (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+ register OS os = ot -> ot_syntax;
+
+ switch (offset) {
+ case type_SNMP_PDUs_set__request:
+ case type_SNMP_PDUs_commit:
+ case type_SNMP_PDUs_rollback:
+ if (oid -> oid_nelem != ot -> ot_name -> oid_nelem + 1
+ || oid -> oid_elements[oid -> oid_nelem - 1] != 0)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (os == NULLOS) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no syntax defined for object \"%s\"", ot -> ot_text);
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (offset) {
+ case type_SNMP_PDUs_set__request:
+ if (ot -> ot_save)
+ (*os -> os_free) (ot -> ot_save), ot -> ot_save = NULL;
+ if ((*os -> os_decode) (&ot -> ot_save, v -> value) == NOTOK)
+ return int_SNMP_error__status_badValue;
+ break;
+
+ case type_SNMP_PDUs_commit:
+ if (ot -> ot_info)
+ (*os -> os_free) (ot -> ot_info);
+ ot -> ot_info = ot -> ot_save, ot -> ot_save = NULL;
+ break;
+
+ case type_SNMP_PDUs_rollback:
+ if (ot -> ot_save)
+ (*os -> os_free) (ot -> ot_save), ot -> ot_save = NULL;
+ break;
+ }
+
+ return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int o_longword (oi, v, number)
+OI oi;
+struct type_SNMP_VarBind *v;
+integer number; /* actual param: often a constant */
+{
+ return o_number (oi, v, (caddr_t) &number);
+}
+
+
+int o_number (oi, v, number)
+OI oi;
+register struct type_SNMP_VarBind *v;
+caddr_t number;
+{
+ int result;
+ register OT ot = oi -> oi_type;
+ register OS os = ot -> ot_syntax;
+
+ if (os == NULLOS) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no syntax defined for object \"%s\"", ot -> ot_text);
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (v -> value)
+ free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+ result = (*os -> os_encode) (number, &v -> value);
+
+ if (result == NOTOK) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "encoding error for variable \"%s\"",
+ oid2ode (oi -> oi_name));
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int o_string (oi, v, base, len)
+OI oi;
+register struct type_SNMP_VarBind *v;
+char *base;
+int len;
+{
+ int result;
+ struct qbuf *value;
+ register OT ot = oi -> oi_type;
+ register OS os = ot -> ot_syntax;
+
+ if (os == NULLOS) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no syntax defined for object \"%s\"", ot -> ot_text);
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ if ((value = str2qb (base, len, 1)) == NULL) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP, "out of memory");
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (v -> value)
+ free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+ result = (*os -> os_encode) (value, &v -> value);
+ qb_free (value);
+
+ if (result == NOTOK) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "encoding error for variable \"%s\"",
+ oid2ode (oi -> oi_name));
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int o_qbstring (oi, v, value)
+OI oi;
+register struct type_SNMP_VarBind *v;
+struct qbuf *value;
+{
+ int result;
+ register OT ot = oi -> oi_type;
+ register OS os = ot -> ot_syntax;
+
+ if (os == NULLOS) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no syntax defined for object \"%s\"", ot -> ot_text);
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (v -> value)
+ free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+ result = (*os -> os_encode) (value, &v -> value);
+
+ if (result == NOTOK) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "encoding error for variable \"%s\"",
+ oid2ode (oi -> oi_name));
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int o_specific (oi, v, value)
+OI oi;
+register struct type_SNMP_VarBind *v;
+caddr_t value;
+{
+ int result;
+ register OT ot = oi -> oi_type;
+ register OS os = ot -> ot_syntax;
+
+ if (os == NULLOS) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "no syntax defined for object \"%s\"", ot -> ot_text);
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ if (v -> value)
+ free_SNMP_ObjectSyntax (v -> value), v -> value = NULL;
+ result = (*os -> os_encode) (value, &v -> value);
+
+ if (result == NOTOK) {
+ ADVISE (LLOG_EXCEPTIONS, NULLCP,
+ "encoding error for variable \"%s\"",
+ oid2ode (oi -> oi_name));
+
+ return int_SNMP_error__status_genErr;
+ }
+
+ return int_SNMP_error__status_noError;
+}
+
+/* \f */
+
+int mediaddr2oid (ip, addr, len, islen)
+register unsigned int *ip;
+register u_char *addr;
+int len,
+ islen;
+{
+ register int i;
+
+ if (islen)
+ *ip++ = len & 0xff;
+
+ for (i = len; i > 0; i--)
+ *ip++ = *addr++ & 0xff;
+
+ return (len + (islen ? 1 : 0));
+}
+
+/* \f */
+
+OID oid_extend (q, howmuch)
+register OID q;
+int howmuch;
+{
+ register unsigned int i,
+ *ip,
+ *jp;
+ OID oid;
+
+ if (q == NULLOID)
+ return NULLOID;
+ if ((i = q -> oid_nelem) < 1)
+ return NULLOID;
+ if ((oid = (OID) malloc (sizeof *oid)) == NULLOID)
+ return NULLOID;
+
+ if ((ip = (unsigned int *)
+ calloc ((unsigned) (i + howmuch + 1), sizeof *ip))
+ == NULL) {
+ free ((char *) oid);
+ return NULLOID;
+ }
+
+ oid -> oid_elements = ip, oid -> oid_nelem = i + howmuch;
+
+ for (i = 0, jp = q -> oid_elements; i < oid -> oid_nelem; i++, jp++)
+ *ip++ = *jp;
+
+ return oid;
+}
+
+/* \f */
+
+OID oid_normalize (q, howmuch, bigvalue)
+register OID q;
+int howmuch,
+ bigvalue;
+{
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ OID oid;
+
+ if ((oid = oid_extend (q, howmuch)) == NULL)
+ return NULLOID;
+
+ for (jp = (ip = oid -> oid_elements + q -> oid_nelem) - 1;
+ jp >= oid -> oid_elements;
+ jp--)
+ if (*jp > 0) {
+ *jp -= 1;
+ break;
+ }
+ for (i = howmuch; i > 0; i--)
+ *ip++ = (unsigned int) bigvalue;
+
+ return oid;
+}
--- /dev/null
+/* view-g.c - VIEW group */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/snmp/RCS/view-g.c,v 7.2 91/02/22 09:44:59 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/snmp/RCS/view-g.c,v 7.2 91/02/22 09:44:59 mrose Interim $
+ *
+ *
+ * $Log: view-g.c,v $
+ * Revision 7.2 91/02/22 09:44:59 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/12/18 10:14:28 mrose
+ * update
+ *
+ * Revision 7.0 90/12/17 22:07:58 mrose
+ * *** empty log message ***
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include "mib.h"
+#include "view-g.h"
+#include "tailor.h"
+
+/* \f VIEW GROUP */
+
+#define viewPrimName 0
+#define viewPrimTDomain 1
+#define viewPrimTAddr 2
+#define viewPrimUser 3
+#define viewPrimCommunity 4
+#define viewPrimType 5
+
+#define P_VALID 1 /* viewPrimType */
+
+
+static int viewmask = 0x1;
+static OID localAgent = NULLOID;
+static OID rfc1157Domain = NULLOID;
+
+struct view *get_prent ();
+
+
+static int o_viewPrim (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ register struct view *vu;
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
+ return int_SNMP_error__status_noSuchName;
+ if ((vu = get_prent (oid -> oid_elements
+ + ot -> ot_name -> oid_nelem,
+ oid -> oid_nelem
+ - ot -> ot_name -> oid_nelem, 0)) == NULL)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((vu = VHead -> v_forw) == VHead)
+ return NOTOK;
+
+ if ((new = oid_extend (oid, vu -> v_insize)) == NULLOID)
+ return NOTOK;
+ ip = new -> oid_elements + new -> oid_nelem - vu -> v_insize;
+ jp = vu -> v_instance;
+ for (i = vu -> v_insize; i > 0; i--)
+ *ip++ = *jp++;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else {
+ int j;
+
+ if ((vu = get_prent (oid -> oid_elements
+ + ot -> ot_name -> oid_nelem,
+ j = oid -> oid_nelem
+ - ot -> ot_name -> oid_nelem, 1))
+ == NULL)
+ return NOTOK;
+
+ if ((i = j - vu -> v_insize) < 0) {
+ OID new;
+
+ if ((new = oid_extend (oid, -i)) == NULLOID)
+ return NOTOK;
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+
+ oid = new;
+ }
+ else
+ if (i > 0)
+ oid -> oid_nelem -= i;
+
+ ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
+ jp = vu -> v_instance;
+ for (i = vu -> v_insize; i > 0; i--)
+ *ip++ = *jp++;
+ }
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (ifvar) {
+ case viewPrimName:
+ return o_specific (oi, v, (caddr_t) vu -> v_name);
+
+ case viewPrimTDomain:
+ return o_specific (oi, v,
+ (caddr_t) (vu -> v_community ? rfc1157Domain
+ : localAgent));
+
+ case viewPrimTAddr:
+#ifdef TCP
+ if (vu -> v_community) {
+ struct sockaddr_in *sin = (struct sockaddr_in *) &vu -> v_sa;
+
+ return o_string (oi, v, (char *) &sin -> sin_addr, 4);
+ }
+ else
+#endif
+ return o_string (oi, v, NULLCP, 0);
+
+ case viewPrimUser:
+ case viewPrimCommunity:
+ if (vu -> v_community)
+ return o_qbstring (oi, v, vu -> v_community);
+ else
+ return o_string (oi, v, NULLCP, 0);
+
+ case viewPrimType:
+ return o_integer (oi, v, P_VALID);
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+static struct view *get_prent (ip, len, isnext)
+register unsigned int *ip;
+int len;
+int isnext;
+{
+ register struct view *v;
+
+ for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
+ switch (elem_cmp (v -> v_instance, v -> v_insize, ip, len)) {
+ case 0:
+ if (!isnext)
+ return v;
+ if ((v = v -> v_forw) == VHead)
+ return NULL;
+ /* else fall... */
+
+ case 1:
+ return (isnext ? v : NULL);
+ }
+
+ return NULL;
+}
+
+/* \f */
+
+#define viewAclView 0
+#define viewAclCommunity 1
+#define viewAclUser 2
+#define viewAclPrivileges 3
+#define viewAclType 4
+
+#define A_VALID 1 /* viewAclType */
+
+
+static struct community *CLex = NULL;
+
+struct community *get_acent ();
+
+
+static int o_viewAcl (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ register struct community *c;
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
+ return int_SNMP_error__status_noSuchName;
+ if ((c = get_acent (oid -> oid_elements
+ + ot -> ot_name -> oid_nelem,
+ oid -> oid_nelem
+ - ot -> ot_name -> oid_nelem, 0)) == NULL)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((c = CLex) == NULL)
+ return NOTOK;
+
+ if ((new = oid_extend (oid, c -> c_insize)) == NULLOID)
+ return NOTOK;
+ ip = new -> oid_elements + new -> oid_nelem - c -> c_insize;
+ jp = c -> c_instance;
+ for (i = c -> c_insize; i > 0; i--)
+ *ip++ = *jp++;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else {
+ int j;
+
+ if ((c = get_acent (oid -> oid_elements
+ + ot -> ot_name -> oid_nelem,
+ j = oid -> oid_nelem
+ - ot -> ot_name -> oid_nelem, 1))
+ == NULL)
+ return NOTOK;
+
+ if ((i = j - c -> c_insize) < 0) {
+ OID new;
+
+ if ((new = oid_extend (oid, -i)) == NULLOID)
+ return NOTOK;
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+
+ oid = new;
+ }
+ else
+ if (i > 0)
+ oid -> oid_nelem -= i;
+
+ ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
+ jp = c -> c_instance;
+ for (i = c -> c_insize; i > 0; i--)
+ *ip++ = *jp++;
+ }
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (ifvar) {
+ case viewAclView:
+ return o_specific (oi, v, (caddr_t) c -> c_view -> v_name);
+
+ case viewAclCommunity:
+ case viewAclUser:
+ return o_string (oi, v, c -> c_name, strlen (c -> c_name));
+
+ case viewAclPrivileges:
+ return o_integer (oi, v,
+ ((c -> c_permission & OT_RDONLY) ? 3 : 0)
+ + ((c -> c_permission & OT_WRONLY) ? 8 : 0)
+ + ((c -> c_permission & OT_YYY) ? 4 : 0));
+
+ case viewAclType:
+ return o_integer (oi, v, A_VALID);
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+static struct community *get_acent (ip, len, isnext)
+register unsigned int *ip;
+int len;
+int isnext;
+{
+ register struct community *c;
+
+ for (c = CLex; c; c = c -> c_next)
+ switch (elem_cmp (c -> c_instance, c -> c_insize, ip, len)) {
+ case 0:
+ return (isnext ? c -> c_next : c);
+
+ case 1:
+ return (isnext ? c : NULL);
+ }
+
+ return NULL;
+}
+
+/* \f */
+
+#define viewTrapView 0
+#define viewTrapGenerics 1
+#define viewTrapSpecifics 2
+#define viewTrapType 3
+
+#define T_VALID 1 /* viewTrapType */
+
+
+static OID trapview = NULLOID;
+
+struct trap *get_trent ();
+
+
+static int o_viewTrap (oi, v, offset)
+OI oi;
+register struct type_SNMP_VarBind *v;
+int offset;
+{
+ int ifvar;
+ register int i;
+ register unsigned int *ip,
+ *jp;
+ register struct trap *t;
+ register OID oid = oi -> oi_name;
+ register OT ot = oi -> oi_type;
+
+ ifvar = (int) ot -> ot_info;
+ switch (offset) {
+ case type_SNMP_PDUs_get__request:
+ if (oid -> oid_nelem <= ot -> ot_name -> oid_nelem)
+ return int_SNMP_error__status_noSuchName;
+ if ((t = get_trent (oid -> oid_elements
+ + ot -> ot_name -> oid_nelem,
+ oid -> oid_nelem
+ - ot -> ot_name -> oid_nelem, 0)) == NULL)
+ return int_SNMP_error__status_noSuchName;
+ break;
+
+ case type_SNMP_PDUs_get__next__request:
+ if (oid -> oid_nelem == ot -> ot_name -> oid_nelem) {
+ OID new;
+
+ if ((t = UHead -> t_forw) == UHead)
+ return NOTOK;
+
+ if ((new = oid_extend (oid, t -> t_insize)) == NULLOID)
+ return NOTOK;
+ ip = new -> oid_elements + new -> oid_nelem - t -> t_insize;
+ jp = t -> t_instance;
+ for (i = t -> t_insize; i > 0; i--)
+ *ip++ = *jp++;
+
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+ }
+ else {
+ int j;
+
+ if ((t = get_trent (oid -> oid_elements
+ + ot -> ot_name -> oid_nelem,
+ j = oid -> oid_nelem
+ - ot -> ot_name -> oid_nelem, 1))
+ == NULL)
+ return NOTOK;
+
+ if ((i = j - t -> t_insize) < 0) {
+ OID new;
+
+ if ((new = oid_extend (oid, -i)) == NULLOID)
+ return NOTOK;
+ if (v -> name)
+ free_SNMP_ObjectName (v -> name);
+ v -> name = new;
+
+ oid = new;
+ }
+ else
+ if (i > 0)
+ oid -> oid_nelem -= i;
+
+ ip = oid -> oid_elements + ot -> ot_name -> oid_nelem;
+ jp = t -> t_instance;
+ for (i = t -> t_insize; i > 0; i--)
+ *ip++ = *jp++;
+ }
+ break;
+
+ default:
+ return int_SNMP_error__status_genErr;
+ }
+
+ switch (ifvar) {
+ case viewTrapView:
+ return o_specific (oi, v, (caddr_t) t -> t_view -> v_name);
+
+ case viewTrapGenerics:
+ {
+ char c = t -> t_generics & 0xff;
+
+ return o_string (oi, v, &c, sizeof c);
+ }
+
+ case viewTrapSpecifics:
+ return o_string (oi, v, NULLCP, 0);
+
+ case viewTrapType:
+ return o_integer (oi, v, T_VALID);
+
+ default:
+ return int_SNMP_error__status_noSuchName;
+ }
+}
+
+/* \f */
+
+static struct trap *get_trent (ip, len, isnext)
+register unsigned int *ip;
+int len;
+int isnext;
+{
+ register struct trap *t;
+
+ for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
+ switch (elem_cmp (t -> t_instance, t -> t_insize, ip, len)) {
+ case 0:
+ if (!isnext)
+ return t;
+ if ((t = t -> t_forw) == UHead)
+ return NULL;
+ /* else fall... */
+
+ case 1:
+ return (isnext ? t : NULL);
+ }
+
+ return NULL;
+}
+
+/* \f */
+
+static int view_compar (a, b)
+struct view **a,
+ **b;
+{
+ return elem_cmp ((*a) -> v_instance, (*a) -> v_insize,
+ (*b) -> v_instance, (*b) -> v_insize);
+}
+
+static int comm_compar (a, b)
+struct community **a,
+ **b;
+{
+ return elem_cmp ((*a) -> c_instance, (*a) -> c_insize,
+ (*b) -> c_instance, (*b) -> c_insize);
+}
+
+static int trap_compar (a, b)
+struct trap **a,
+ **b;
+{
+ return elem_cmp ((*a) -> t_instance, (*a) -> t_insize,
+ (*b) -> t_instance, (*b) -> t_insize);
+}
+
+/* \f */
+
+static struct wired {
+ char *w_args1;
+ char *w_args2;
+} wired[] = {
+ "defViewWholeRW", NULL,
+ "defViewWholeRO", NULL,
+ "defViewStandardRW", "mgmt",
+ "defViewStandardRO", "mgmt",
+
+ NULL
+};
+
+/* \f */
+
+init_view () {
+ char buffer[BUFSIZ],
+ *vec[4];
+ register OT ot;
+ register struct wired *w;
+
+ CHead -> c_forw = CHead -> c_back = CHead;
+ UHead -> t_forw = UHead -> t_back = UHead;
+ VHead -> v_forw = VHead -> v_back = VHead;
+
+ vec[0] = "view";
+ for (w = wired; w -> w_args1; w++) {
+ vec[1] = w -> w_args1;
+ if (vec[2] = w -> w_args2)
+ vec[3] = NULL;
+
+ if (f_view (vec) == NOTOK)
+ adios (NULLCP, "you lose");
+ }
+
+ (void) strcpy (buffer, "defViewTrapDest.0");
+ if ((trapview = text2oid (buffer)) == NULLOID)
+ adios (NULLCP, "unknown OID \"defViewTrapDest.0\" for traps");
+ trapview -> oid_nelem--;
+
+ if ((localAgent = text2oid ("localAgent")) == NULLOID)
+ adios (NULLCP, "unknown OID \"localAgent\"");
+ if ((rfc1157Domain = text2oid ("rfc1157Domain")) == NULLOID)
+ adios (NULLCP, "unknown OID \"rfc1157Domain\"");
+
+ if (ot = text2obj ("viewPrimName"))
+ ot -> ot_getfnx = o_viewPrim,
+ ot -> ot_info = (caddr_t) viewPrimName;
+ if (ot = text2obj ("viewPrimTDomain"))
+ ot -> ot_getfnx = o_viewPrim,
+ ot -> ot_info = (caddr_t) viewPrimTDomain;
+ if (ot = text2obj ("viewPrimTAddr"))
+ ot -> ot_getfnx = o_viewPrim,
+ ot -> ot_info = (caddr_t) viewPrimTAddr;
+ if (ot = text2obj ("viewPrimUser"))
+ ot -> ot_getfnx = o_viewPrim,
+ ot -> ot_info = (caddr_t) viewPrimUser;
+ if (ot = text2obj ("viewPrimCommunity"))
+ ot -> ot_getfnx = o_viewPrim,
+ ot -> ot_info = (caddr_t) viewPrimCommunity;
+ if (ot = text2obj ("viewPrimType"))
+ ot -> ot_getfnx = o_viewPrim,
+ ot -> ot_info = (caddr_t) viewPrimType;
+
+ if (ot = text2obj ("viewAclView"))
+ ot -> ot_getfnx = o_viewAcl,
+ ot -> ot_info = (caddr_t) viewAclView;
+ if (ot = text2obj ("viewAclCommunity"))
+ ot -> ot_getfnx = o_viewAcl,
+ ot -> ot_info = (caddr_t) viewAclCommunity;
+ if (ot = text2obj ("viewAclUser"))
+ ot -> ot_getfnx = o_viewAcl,
+ ot -> ot_info = (caddr_t) viewAclUser;
+ if (ot = text2obj ("viewAclPrivileges"))
+ ot -> ot_getfnx = o_viewAcl,
+ ot -> ot_info = (caddr_t) viewAclPrivileges;
+ if (ot = text2obj ("viewAclType"))
+ ot -> ot_getfnx = o_viewAcl,
+ ot -> ot_info = (caddr_t) viewAclType;
+
+ if (ot = text2obj ("viewTrapView"))
+ ot -> ot_getfnx = o_viewTrap,
+ ot -> ot_info = (caddr_t) viewTrapView;
+ if (ot = text2obj ("viewTrapGenerics"))
+ ot -> ot_getfnx = o_viewTrap,
+ ot -> ot_info = (caddr_t) viewTrapGenerics;
+ if (ot = text2obj ("viewTrapSpecifics"))
+ ot -> ot_getfnx = o_viewTrap,
+ ot -> ot_info = (caddr_t) viewTrapSpecifics;
+ if (ot = text2obj ("viewTrapType"))
+ ot -> ot_getfnx = o_viewTrap,
+ ot -> ot_info = (caddr_t) viewTrapType;
+}
+
+/* \f */
+
+fin_view ()
+{
+ register int i;
+ char *vec[3];
+ register struct community *c;
+ register struct view *v;
+ register struct trap *t;
+
+ if (CHead -> c_forw == CHead) {
+ vec[0] = "community";
+ vec[1] = "public";
+ vec[2] = NULL;
+
+ (void) f_community (vec);
+ }
+
+ for (c = CHead -> c_forw; c != CHead; c = c -> c_forw) {
+ for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
+ if (oid_cmp (v -> v_name, c -> c_vu) == 0) {
+ c -> c_view = v;
+ break;
+ }
+ if (v == VHead)
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "no such view as %s for community \"%s\"",
+ sprintoid (c -> c_vu), c -> c_name);
+ }
+
+ i = 0;
+ for (v = VHead -> v_forw; v != VHead; v = v -> v_forw)
+ i++;
+ if (i > 0) {
+ register struct view **base,
+ **bp,
+ **ep;
+
+ if ((base = (struct view **) malloc ((unsigned) (i * sizeof *base)))
+ == NULL)
+ adios (NULLCP, "out of memory");
+ ep = base;
+ for (v = VHead -> v_forw; v != VHead; v = v -> v_forw) {
+ register int j;
+ register unsigned int *ip,
+ *jp;
+ OID oid = v -> v_name;
+
+ v -> v_insize = 1 + (j = oid -> oid_nelem);
+ if ((v -> v_instance =
+ (unsigned int *) calloc ((unsigned) v -> v_insize,
+ sizeof *v -> v_instance)) == NULL)
+ adios (NULLCP, "out of memory");
+ v -> v_instance[0] = oid -> oid_nelem;
+ for (ip = v -> v_instance + 1, jp = oid -> oid_elements;
+ j > 0;
+ j--)
+ *ip++ = *jp++;
+
+ remque (*ep++ = v);
+ }
+ VHead -> v_forw = VHead -> v_back = VHead;
+
+ if (i > 1)
+ qsort ((char *) base, i, sizeof *base, view_compar);
+
+ bp = base;
+ while (bp < ep)
+ insque (*bp++, VHead -> v_back);
+
+ free ((char *) base);
+ }
+
+ i = 0;
+ for (c = CHead -> c_forw; c != CHead; c = c -> c_forw)
+ i++;
+ if (i > 0) {
+ int j;
+ register struct community **base,
+ **bp,
+ **ep;
+
+ if ((base = (struct community **)
+ malloc ((unsigned) (i * sizeof *base))) == NULL)
+ adios (NULLCP, "out of memory");
+ ep = base;
+ for (c = CHead -> c_forw; c != CHead; c = c -> c_forw) {
+ register char *cp,
+ *dp;
+ register unsigned int *ip;
+
+ switch (c -> c_addr.na_stack) {
+ case NA_TCP:
+ j = 4;
+ break;
+
+ case NA_X25:
+ j = c -> c_addr.na_dtelen;
+ break;
+
+ case NA_NSAP:
+ j = c -> c_addr.na_addrlen;
+ break;
+
+ default:
+ j = 0;
+ break;
+ }
+
+ c -> c_insize = 1 + strlen (c -> c_name) + 1 + j;
+ if ((c -> c_instance =
+ (unsigned int *) calloc ((unsigned) c -> c_insize,
+ sizeof *c -> c_instance)) == NULL)
+ adios (NULLCP, "out of memory");
+ ip = c -> c_instance;
+
+ *ip++ = strlen (c -> c_name);
+ for (cp = c -> c_name; *cp; cp++)
+ *ip++ = *cp & 0xff;
+
+ *ip++ = j;
+ switch (c -> c_addr.na_stack) {
+ case NA_TCP:
+ (void) sscanf (c -> c_addr.na_domain, "%u.%u.%u.%u",
+ ip, ip + 1, ip + 2, ip + 3);
+ break;
+
+ case NA_X25:
+ dp = (cp = c -> c_addr.na_dte) + c -> c_addr.na_dtelen;
+ goto stuff_it;
+
+ case NA_NSAP:
+ dp = (cp = c -> c_addr.na_address) + c ->c_addr.na_addrlen;
+stuff_it: ;
+ while (cp < dp)
+ *ip++ = *cp++ & 0xff;
+ break;
+
+ default:
+ break;
+ }
+
+ *ep++ = c;
+ }
+
+ if (i > 1)
+ qsort ((char *) base, i, sizeof *base, comm_compar);
+
+ bp = base;
+ c = CLex = *bp++;
+ while (bp < ep) {
+ c -> c_next = *bp;
+ c = *bp++;
+ }
+ c -> c_next = NULL;
+
+ free ((char *) base);
+ }
+ else
+ CLex = NULL;
+
+ i = 0;
+ for (t = UHead -> t_forw; t != UHead; t = t -> t_forw)
+ i++;
+ if (i > 0) {
+ register struct trap **base,
+ **bp,
+ **ep;
+
+ if ((base = (struct trap **) malloc ((unsigned) (i * sizeof *base)))
+ == NULL)
+ adios (NULLCP, "out of memory");
+ ep = base;
+ for (t = UHead -> t_forw; t != UHead; t = t -> t_forw) {
+ register int j;
+ register unsigned int *ip,
+ *jp;
+ OID oid = t -> t_view -> v_name;
+
+ t -> t_insize = 1 + (j = oid -> oid_nelem);
+ if ((t -> t_instance =
+ (unsigned int *) calloc ((unsigned) t -> t_insize,
+ sizeof *t -> t_instance)) == NULL)
+ adios (NULLCP, "out of memory");
+ t -> t_instance[0] = oid -> oid_nelem;
+ for (ip = t -> t_instance + 1, jp = oid -> oid_elements;
+ j > 0;
+ j--)
+ *ip++ = *jp++;
+
+ remque (*ep++ = t);
+ }
+ UHead -> t_forw = UHead -> t_back = UHead;
+
+ if (i > 1)
+ qsort ((char *) base, i, sizeof *base, trap_compar);
+
+ bp = base;
+ while (bp < ep)
+ insque (*bp++, UHead -> t_back);
+
+ free ((char *) base);
+ }
+}
+
+/* \f */
+
+int f_community (vec)
+char **vec;
+{
+ register struct community *c;
+ register struct NSAPaddr *na;
+
+ vec++;
+
+ if ((c = (struct community *) calloc (1, sizeof *c)) == NULL
+ || (c -> c_name = strdup (*vec)) == NULL)
+ adios (NULLCP, "out of memory");
+ vec++;
+
+ na = &c -> c_addr;
+ if (*vec) {
+ if (str2sa (*vec, na, (struct sockaddr *) NULL, 0) == NOTOK)
+ adios (NULLCP, "unknown address \"%s\" for community \"%s\"",
+ *vec, c -> c_name);
+
+ vec++;
+ }
+ else {
+ na -> na_stack = NA_TCP;
+ na -> na_community = ts_comm_tcp_default;
+ (void) strcpy (na -> na_domain, "0.0.0.0");
+ }
+
+ if (*vec) {
+ if (lexequ (*vec, "readOnly") == 0)
+ c -> c_permission = OT_RDONLY;
+ else
+ if (lexequ (*vec, "readWrite") == 0)
+ c -> c_permission = OT_RDWRITE;
+ else
+ if (lexequ (*vec, "writeOnly") == 0)
+ c -> c_permission = OT_WRONLY;
+ else
+ if (lexequ (*vec, "none")) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "invalid access mode \"%s\"", *vec);
+ goto you_lose;
+ }
+
+ vec++;
+ }
+ else
+ c -> c_permission = OT_RDONLY;
+
+ if (*vec) {
+ char buffer[BUFSIZ];
+
+ (void) strcpy (buffer, *vec);
+ if ((c -> c_vu = text2oid (buffer)) == NULLOID) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+ goto you_lose;
+ }
+
+ if (*++vec)
+ goto you_lose;
+ }
+ else
+ if ((c -> c_vu = text2oid ("defViewWholeRO")) == NULL) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"defViewWholeRO\"");
+ goto you_lose;
+ }
+
+ insque (c, CHead -> c_back);
+
+ return OK;
+
+you_lose: ;
+ free (c -> c_name);
+ free ((char *) c);
+
+ return NOTOK;
+}
+
+/* \f */
+
+int f_proxy (vec)
+char **vec;
+{
+ char buffer[BUFSIZ];
+ register struct community *c;
+ register struct view *v,
+ *u;
+ register struct NSAPaddr *na;
+
+ if ((v = (struct view *) calloc (1, sizeof *v)) == NULL)
+ adios (NULLCP, "out of memory");
+ v -> v_subtree.s_forw = v -> v_subtree.s_back = &v -> v_subtree;
+ if ((c = (struct community *) calloc (1, sizeof *c)) == NULL)
+ adios (NULLCP, "out of memory");
+ c -> c_permission = OT_YYY;
+ vec++;
+
+ (void) strcpy (buffer, *vec);
+ if ((v -> v_name = text2oid (buffer)) == NULL) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+ goto you_lose;
+ }
+ c -> c_vu = v -> v_name;
+ if (trapview && inSubtree (trapview, v -> v_name)) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "view \"%s\" is for traps", *vec);
+ goto you_lose;
+ }
+ for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
+ if (oid_cmp (u -> v_name, v -> v_name) == 0) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "duplicate view \"%s\"", *vec);
+ goto you_lose;
+ }
+ vec++;
+
+ if (lexequ (*vec, "rfc1157")) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unsupported proxy domain \"%s\"",
+ *vec);
+ goto you_lose;
+ }
+ vec++;
+
+ na = &c -> c_addr;
+ if (*vec) {
+ if (str2sa (*vec, na, &v -> v_sa, 1) == NOTOK)
+ adios (NULLCP, "unknown address \"%s\" for proxy %s",
+ *vec, oid2ode (v -> v_name));
+
+ vec++;
+ }
+ else
+ goto you_lose;
+
+ if (*vec) {
+ if ((v -> v_community = str2qb (*vec, strlen (*vec), 1)) == NULL)
+ adios (NULLCP, "out of memory");
+ if ((c -> c_name = strdup (*vec)) == NULL)
+ adios (NULLCP, "out of memory");
+
+ if (*++vec)
+ goto you_lose;
+ }
+ else
+ goto you_lose;
+
+ insque (v, VHead -> v_back);
+ insque (c, CHead -> c_back);
+
+ return OK;
+
+you_lose: ;
+ if (c -> c_name)
+ free (c -> c_name);
+ free ((char *) c);
+ if (v -> v_name)
+ oid_free (v -> v_name);
+ if (v -> v_community)
+ qb_free (v -> v_community);
+ free ((char *) v);
+
+ return NOTOK;
+}
+
+/* \f */
+
+int f_trap (vec)
+char **vec;
+{
+ register struct trap *t;
+ register struct view *v;
+ struct NSAPaddr nas;
+ register struct NSAPaddr *na = &nas;
+ static int trapno = 1;
+
+ vec++;
+
+ if ((t = (struct trap *) calloc (1, sizeof *t)) == NULL
+ || (t -> t_name = strdup (*vec)) == NULL)
+ adios (NULLCP, "out of memory");
+ v = t -> t_view = &t -> t_vu;
+ v -> v_subtree.s_forw = v -> v_subtree.s_back = &v -> v_subtree;
+ t -> t_generics = 0xfe;
+ vec++;
+
+ trapview -> oid_elements[trapview -> oid_nelem++] = trapno;
+ v -> v_name = oid_cpy (trapview);
+ trapview -> oid_nelem--;
+ if (v -> v_name == NULLOID)
+ adios (NULLCP, "out of memory");
+
+ if ((v -> v_community = str2qb (t -> t_name, strlen (t -> t_name), 1))
+ == NULL)
+ adios (NULLCP, "out of memory");
+
+ bzero ((char *) na, sizeof *na);
+ if (*vec) {
+ if (str2sa (*vec, na, &v -> v_sa, 0) == NOTOK)
+ adios (NULLCP, "unknown address \"%s\" for trap sink \"%s\"",
+ *vec, t -> t_name);
+
+ vec++;
+ }
+ else
+ goto you_lose;
+
+ if (*vec) {
+ char buffer[BUFSIZ];
+ OID name;
+ register struct view *u;
+
+ (void) strcpy (buffer, *vec);
+ if ((name = text2oid (buffer)) == NULL) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+ goto you_lose;
+ }
+ oid_free (v -> v_name);
+ v -> v_name = name;
+
+ for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
+ if (oid_cmp (u -> v_name, v -> v_name) == 0) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "duplicate view \"%s\" for trap sink \"%s\"",
+ *vec, t -> t_name);
+ goto you_lose;
+ }
+
+ vec++;
+ }
+ else
+ trapno++;
+
+ if (*vec) {
+ if (sscanf (*vec, "%lx", &t -> t_generics) != 1)
+ goto you_lose;
+
+ if (*++vec)
+ goto you_lose;
+ }
+
+ insque (t, UHead -> t_back);
+ insque (v, VHead -> v_back);
+
+ return OK;
+
+you_lose: ;
+ oid_free (v -> v_name);
+ qb_free (v -> v_community);
+ free (t -> t_name);
+ free ((char *) t);
+
+ return NOTOK;
+}
+
+/* \f */
+
+int f_view (vec)
+char **vec;
+{
+ char buffer[BUFSIZ];
+ register struct subtree *s,
+ *x,
+ *y;
+ register struct view *v,
+ *u;
+
+ if (viewmask == 0) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "too many views starting with \"%s\"", *vec);
+ return NOTOK;
+ }
+
+ if ((v = (struct view *) calloc (1, sizeof *v)) == NULL)
+ adios (NULLCP, "out of memory");
+ s = &v -> v_subtree;
+ v -> v_subtree.s_forw = v -> v_subtree.s_back = s;
+ vec++;
+
+ (void) strcpy (buffer, *vec);
+ if ((v -> v_name = text2oid (buffer)) == NULL) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+ goto you_lose;
+ }
+ if (trapview && inSubtree (trapview, v -> v_name)) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "view \"%s\" is for traps", *vec);
+ goto you_lose;
+ }
+ for (u = VHead -> v_forw; u != VHead; u = u -> v_forw)
+ if (oid_cmp (u -> v_name, v -> v_name) == 0) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "duplicate view \"%s\"", *vec);
+ goto you_lose;
+ }
+
+ for (vec++; *vec; vec++) {
+ register struct subtree *z;
+ OID name;
+
+ (void) strcpy (buffer, *vec);
+ if ((name = text2oid (buffer)) == NULLOID) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unknown OID \"%s\"", *vec);
+ goto you_lose;
+ }
+
+ for (x = s -> s_forw; x != s; x = y) {
+ register int i,
+ j;
+ y = x -> s_forw;
+
+ if (bcmp ((char *) x -> s_subtree -> oid_elements,
+ (char *) name -> oid_elements,
+ ((i = x -> s_subtree -> oid_nelem)
+ <= (j = name -> oid_nelem) ? i : j)
+ * sizeof name -> oid_elements[0]) == 0) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "%s %s %s",
+ *vec,
+ i <= j ? "already under" : "superceding",
+ oid2ode (x -> s_subtree));
+ if (i <= j)
+ goto another;
+
+ remque (x);
+ oid_free (x -> s_subtree);
+ free ((char *) x);
+ }
+ }
+
+ if ((z = (struct subtree *) calloc (1, sizeof *z)) == NULL)
+ adios (NULLCP, "out of memory");
+ z -> s_subtree = name;
+
+ insque (z, s -> s_back);
+another: ;
+ }
+
+ v -> v_mask = viewmask;
+ viewmask <<= 1;
+ insque (v, VHead -> v_back);
+
+ return OK;
+
+you_lose: ;
+ for (x = s -> s_forw; x != s; x = y) {
+ y = x -> s_forw;
+
+ remque (x);
+ oid_free (x -> s_subtree);
+ free ((char *) x);
+ }
+ if (v -> v_name)
+ oid_free (v -> v_name);
+ free ((char *) v);
+
+ return NOTOK;
+}
+
+/* \f */
+
+extern int tcpservice;
+extern int udport;
+extern int traport;
+
+
+static int str2sa (s, na, sock, proxy)
+char *s;
+struct NSAPaddr *na;
+struct sockaddr *sock;
+int proxy;
+{
+#ifdef TCP
+ register struct hostent *hp;
+#endif
+ struct TSAPaddr *ta;
+
+#ifdef TCP
+ if (hp = gethostbystring (s)) {
+ struct sockaddr_in sin;
+
+ na -> na_stack = NA_TCP;
+ na -> na_community = ts_comm_tcp_default;
+ inaddr_copy (hp, &sin);
+ (void) strncpy (na -> na_domain, inet_ntoa (sin.sin_addr),
+ sizeof na -> na_domain - 1);
+ }
+ else
+#endif
+ if ((ta = str2taddr (s)) && ta -> ta_naddr > 0) {
+ *na = ta -> ta_addrs[0]; /* struct copy */
+ }
+ else
+ return NOTOK;
+
+ if (sock == NULL)
+ return OK;
+
+ switch (na -> na_stack) {
+#ifdef TCP
+ case NA_TCP:
+ if (!tcpservice)
+ goto you_lose;
+ {
+ struct sockaddr_in sin;
+
+ sin.sin_port = na -> na_port ? na -> na_port
+ : proxy ? udport : traport;
+
+ if ((hp = gethostbystring (na -> na_domain)) == NULL)
+ return NOTOK;
+
+ sin.sin_family = hp -> h_addrtype;
+ inaddr_copy (hp, &sin);
+
+ *((struct sockaddr_in *) sock) = sin; /* struct copy */
+ }
+ break;
+#endif
+
+ default:
+you_lose: ;
+ advise (LLOG_EXCEPTIONS, NULLCP, "address type unsupported");
+ return NOTOK;
+ }
+
+ return OK;
+}
--- /dev/null
+/* view-g.h - VIEW group */
+
+/*
+ * $Header: /f/osi/snmp/RCS/view-g.h,v 7.3 91/02/22 09:45:02 mrose Interim $
+ *
+ *
+ * $Log: view-g.h,v $
+ * Revision 7.3 91/02/22 09:45:02 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/12/18 10:14:35 mrose
+ * update
+ *
+ * Revision 7.1 90/12/17 22:19:34 mrose
+ * touch-up
+ *
+ * Revision 7.0 90/12/17 22:08:01 mrose
+ * *** empty log message ***
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "isoaddrs.h"
+#include "internet.h"
+#include "psap.h"
+
+/* \f VIEWS */
+
+#define inSubtree(tree,object) \
+ ((tree) -> oid_nelem <= (object) -> oid_nelem \
+ && bcmp ((char *) (tree) -> oid_elements, \
+ (char *) (object) -> oid_elements, \
+ (tree) -> oid_nelem \
+ * sizeof ((tree) -> oid_elements[0])) == 0)
+
+struct subtree {
+ struct subtree *s_forw; /* doubly-linked list */
+ struct subtree *s_back; /* doubly-linked list */
+
+ OID s_subtree; /* subtree */
+};
+
+
+struct view {
+ struct view *v_forw; /* doubly-linked list */
+ struct view *v_back; /* .. */
+
+ OID v_name; /* view name */
+ u_long v_mask; /* view mask */
+
+ struct subtree v_subtree; /* list of subtrees */
+
+ struct qbuf *v_community; /* for proxy, traps... */
+ struct sockaddr v_sa;
+
+ unsigned int *v_instance; /* object instance */
+ int v_insize; /* .. */
+};
+
+extern struct view *VHead;
+
+/* \f COMMUNITIES */
+
+struct community {
+ struct community *c_forw; /* doubly-linked list */
+ struct community *c_back; /* .. */
+
+ char *c_name; /* community name */
+ struct NSAPaddr c_addr; /* network address */
+
+ int c_permission; /* same as ot_access */
+#define OT_YYY 0x08
+
+ OID c_vu; /* associated view */
+ struct view *c_view; /* .. */
+
+ unsigned int *c_instance; /* object instance */
+ int c_insize; /* .. */
+ struct community *c_next; /* next in lexi-order */
+};
+
+extern struct community *CHead;
+
+/* \f TRAPS */
+
+struct trap {
+ struct trap *t_forw; /* doubly-linked list */
+ struct trap *t_back; /* .. */
+
+ char *t_name; /* trap name */
+
+ struct view t_vu; /* associated view */
+ struct view *t_view; /* .. */
+
+ u_long t_generics; /* generic traps enabled */
+
+ unsigned int *t_instance; /* object instance */
+ int t_insize; /* .. */
+};
+
+extern struct trap *UHead;
--- /dev/null
+###############################################################################
+# Instructions to Make, for compilation of ISODE SSAP processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/ssap/RCS/Makefile,v 7.3 91/02/22 09:45:31 mrose Interim $
+#
+#
+# $Log: Makefile,v $
+# Revision 7.3 91/02/22 09:45:31 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/12/23 18:43:14 mrose
+# update
+#
+# Revision 7.1 90/07/09 14:50:07 mrose
+# sync
+#
+# Revision 7.0 89/11/23 22:25:16 mrose
+# Release 6.0
+#
+###############################################################################
+
+###############################################################################
+#
+# NOTICE
+#
+# Acquisition, use, and distribution of this module and related
+# materials are subject to the restrictions of a license agreement.
+# Consult the Preface in the User's Manual for the full terms of
+# this agreement.
+#
+###############################################################################
+
+
+LIBES = libssap.a $(TOPDIR)libcompat.a
+LLIBS = $(TOPDIR)llib-ltsap $(TOPDIR)llib-lcompat
+HFILES = $(HDIR)spkt.h $(HDIR)ssap.h $(HDIR)tsap.h $(HDIR)isoaddrs.h \
+ $(HDIR)general.h $(HDIR)manifest.h $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all: libssap
+inst-all: # inst-libssap manuals
+install: inst-all clean
+lint: l-libssap
+
+
+################################################################
+# libssap
+################################################################
+
+CFILES = ssaprovider.c ssaperror.c \
+ str2spkt.c text2spkt.c tsdu2spkt.c \
+ ssapexec.c ssaprespond.c ssapinitiate.c ssapexpd.c \
+ ssaptyped.c ssapcapd1.c ssapcapd2.c ssaptoken.c \
+ ssapactivity.c ssapmajor1.c ssapmajor2.c ssapminor1.c \
+ ssapminor2.c ssapresync1.c ssapresync2.c ssapabort.c \
+ ssapreport.c ssaprelease1.c ssaprelease2.c ssapwrite.c \
+ ssapactchk.c ssapselect.c ssaplose.c
+OFILES = ssaprovider.o ssaperror.o \
+ str2spkt.o text2spkt.o tsdu2spkt.o \
+ ssapexec.o ssaprespond.o ssapinitiate.o ssapexpd.o \
+ ssaptyped.o ssapcapd1.o ssapcapd2.o ssaptoken.o \
+ ssapactivity.o ssapmajor1.o ssapmajor2.o ssapminor1.o \
+ ssapminor2.o ssapresync1.o ssapresync2.o ssapabort.o \
+ ssapreport.o ssaprelease1.o ssaprelease2.o ssapwrite.o \
+ ssapactchk.o ssapselect.o ssaplose.o \
+ $(OSTRINGS)
+
+inst-libssap: $(LIBDIR)libssap.a $(LINTDIR)llib-lssap
+
+$(LIBDIR)libssap.a: libssap.a
+ -rm -f $@
+ cp libssap.a $@
+ @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+ -@ls -gls $@
+ -@echo ""
+
+$(LINTDIR)llib-lssap: llib-lssap
+ -cp $@ zllib-lssap
+ -rm -f $@
+ sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+ < llib-lssap | \
+ sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+ @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+ -@ls -gls $@ $@.ln
+ -@echo ""
+
+libssap: libssap.a
+
+libssap.a: ssapvrsn.o
+ -rm -f $@
+ @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \
+ ssapvrsn.o
+ -@rm -f $(TOPDIR)libssap.a $(TOPDIR)llib-lssap
+ -@$(LN) libssap.a $(TOPDIR)libssap.a
+ -@$(LN) llib-lssap $(TOPDIR)llib-lssap
+ -@ls -l $@
+ -@echo "SSAP library built normally"
+
+ssapvrsn.c: $(OFILES)
+ @$(UTILDIR)version.sh ssap > $@
+
+l-libssap:; $(LINT) $(LFLAGS) $(CFILES) ssapvrsn.c $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+ssaprovider.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssaperror.o: $(HFILES)
+str2spkt.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+text2spkt.o: $(HFILES) $(HDIR)logger.h
+tsdu2spkt.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssapexec.o: $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h $(HDIR)logger.h
+ssaprespond.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssapinitiate.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ssapexpd.o: $(HFILES)
+ssaptyped.o: $(HFILES)
+ssapcapd1.o: $(HFILES)
+ssapcapd2.o: $(HFILES)
+ssaptoken.o: $(HFILES)
+ssapactivity.o: $(HFILES)
+ssapabort.o: $(HFILES)
+ssapreport.o: $(HFILES)
+ssapmajor1.o: $(HFILES)
+ssapmajor2.o: $(HFILES)
+ssapminor1.o: $(HFILES)
+ssapminor2.o: $(HFILES)
+ssapresync1.o: $(HFILES)
+ssapresync2.o: $(HFILES)
+ssaprelease1.o: $(HFILES)
+ssaprelease2.o: $(HFILES)
+ssapwrite.o: $(HFILES)
+ssapactchk.o: $(HFILES)
+ssapselect.o: $(HFILES)
+ssaplose.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS = libssap.3n
+
+manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+ -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:; rm -f *.o *.a z* _* core ssapvrsn.c
+
+grind:; iprint Makefile
+ tgrind -lc $(CFILES) ssapvrsn.c llib-lssap
+ @echo $(MANUALS) | \
+ tr " " "\012" | \
+ sed -e "s%.*%itroff -man &%" | \
+ sh -ve
+
--- /dev/null
+.TH LIBSSAP 3N "31 May 1988"
+.\" $Header: /f/osi/ssap/RCS/libssap.3n,v 7.1 91/02/22 09:45:35 mrose Interim $
+.\"
+.\"
+.\" $Log: libssap.3n,v $
+.\" Revision 7.1 91/02/22 09:45:35 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:25:17 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+libssap \- Session Services library
+.SH SYNOPSIS
+.B "#include <isode/ssap.h>"
+.sp
+\fIcc\fR\0...\0\fB\-lssap\fR
+.SH DESCRIPTION
+The \fIlibssap\fR library contains a set of routines which implement
+session services.
+In essence,
+they implement an Session Service Access Point (SSAP) interface for user
+applications.
+This manual page describes only the interface to the Basic Combined Subset
+(BCS) of session;
+consult the \fIUser's Manual\fR for the full details on the entire SSAP
+interface.
+.PP
+Although the ISO model is symmetric,
+this implementation is based on a client/server paradigm and hence asymmetric.
+The information herein is skeletal:
+consult the \fIUser's Manual\fR for actual examples of how ISO servers and
+clients are coded and interact with the \fIlibssap\fR library.
+.SH ADDRESSES
+SSAP addresses are represented by the \fBSSAPaddr\fR structure.
+This contains a transport address,
+and a session-selector as found in the \fIisoservices\fR\0(5)
+database.
+.PP
+SSAP references,
+represented by the \fBSSAPref\fR structure,
+consist of three attributes:
+the user reference, the common reference, and the additional reference.
+These are preserved by the SSAP but otherwise ignored.
+.SH "SERVER INITIALIZATION"
+A program providing an ISO service is usually invoked under \fItsapd\fR\0(8c),
+with the argument vector listed in the ISODE services database.
+The server's very first action is to re\-capture the SSAP state as
+recorded by \fItsapd\fR.
+This is accomplished by calling \fBSInit\fR.
+Information returned by this call is equivalent to the parameters passed by a
+S\-CONNECTION.INDICATION event.
+If the call is successful,
+the program can then examine the argument vector that was passed via
+\fIexecvp\fR
+(it's important to call \fBSInit\fR prior to reading \fBargc\fR and
+\fBargv\fR).
+If the call to \fBSInit\fR is not successful,
+information returned by the call indicates the reason for failure.
+.PP
+After examining the information provided by \fBSInit\fR
+(and possibly the argument vector),
+the server should either accept or reject the connection.
+If accepting, the \fBSConnResponse\fR routine is called with the parameter
+\fBresult\fR set to
+.sp
+.in +.5i
+.nf
+.ta \w'SC_NOTSPECIFIED 'u
+SC_ACCEPT connection accepted
+.re
+.fi
+.in -.5i
+.sp
+(which corresponds to the accepting S\-CONNECT.RESPONSE action).
+If the call is successful,
+the interaction is henceforth symmetric.
+If un\-successful,
+information returned by the call indicates the reason for failure.
+If rejecting, the \fBSConnResponse\fR routine is also called,
+but with the parameter \fBresult\fR set to one of:
+.sp
+.in +.5i
+.nf
+.ta \w'SC_NOTSPECIFIED 'u
+SC_NOTSPECIFIED reason not specified
+SC_CONGESTION temporary congestion
+SC_REJECTED rejected
+.re
+.fi
+.in -.5i
+.sp
+(which corresponds to the refusing S\-CONNECT.RESPONSE action),
+and the program may exit.
+.SH "CLIENT INITIALIZATION"
+A program requesting an ISO service calls \fBSConnRequest\fR
+(which corresponds to the S\-CONNECT.REQUEST action).
+If successful (depending on the responder's choice of \fBresult\fR),
+the interaction is henceforth symmetric.
+If un\-successful,
+information returned by the call indicates the reason for failure.
+.SH SESSION\-DESCRIPTORS
+Once a connection has been established via a successful return from
+\fBSConnResponse\fR (for servers) or \fBSConnRequest\fR (for clients),
+a connection is referenced by a small integer
+(returned in a structure passed to these calls) called a
+\fIsession\-descriptor\fR.
+The session\-descriptor appears as an argument to the peer routines described
+below.
+.PP
+By default,
+events associated with a session\-descriptor are synchronous in nature:
+activity in the network won't generate an INDICATION event without program
+first asking to be told of any activity.
+To mark a session\-descriptor as asynchronous,
+a call to \fBSSetIndications\fR is made with the addresses of an integer
+function to handle these events:
+.sp
+.in +.5i
+.nf
+.ta \w'\fIroutine\fR 'u
+\fIroutine\fR \fIevents\fR
+\fBfunc1\fR data
+\fBfunc2\fR tokens
+\fBfunc3\fR synchronization
+\fBfunc4\fR activities
+\fBfunc5\fR reports
+\fBfunc6\fR release
+\fBfunc7\fR aborts
+.re
+.fi
+.in -.5i
+.sp
+Upon a successful return from \fBSSetIndications\fR,
+these functions will be called as appropriate in this fashion:
+.sp
+.in +.5i
+.B "(*func1) (sd, sx);"
+.sp
+.B "(*func2) (sd, st);"
+.sp
+.B "(*func3) (sd, sn);"
+.sp
+.B "(*func4) (sd, sv);"
+.sp
+.B "(*func5) (sd, sp);"
+.sp
+.B "(*func6) (sd, sf);"
+.sp
+.B "(*func7) (sd, sa);"
+.in -.5i
+.sp
+where \fBsd\fR is the session\-descriptor,
+\fBsx\fR is a pointer to a \fBSSAPdata\fR structure,
+\fBst\fR is a pointer to a \fBSSAPtoken\fR structure,
+\fBsn\fR is a pointer to a \fBSSAPsync\fR structure,
+\fBsv\fR is a pointer to a \fBSSAPactivity\fR structure,
+\fBsp\fR is a pointer to a \fBSSAPreport\fR structure,
+\fBsf\fR is a pointer to a \fBSSAPfinish\fR structure,
+and \fBsa\fR is a pointer to a \fBSSAPabort\fR structure.
+Any value returned by these functions is ignored.
+.PP
+Note well: the \fB\-lssap\fR library uses the \fB\-ltsap\fR library to
+provide this interface.
+The latter library uses the SIGEMT signal to provide this service.
+Programs loaded with \fB\-ltsap\fR that use asynchronous session\-descriptors
+should NOT use SIGEMT for other purposes.
+.PP
+For synchronous multiplexing of several connections,
+the routine \fBSSelectMask\fR
+updates a file\-descriptor mask and counter for use with \fIselect\fR\0(2).
+.SH PEER
+A fatal failure (consult the \fIUser's Manual\fR)
+on return from any of these routines is equivalent to a
+S\-P\-ABORT.INDICATION.
+.sp
+.in +.5i
+.nf
+.ta \w'\fBSUAbortRequest\fR 'u
+\fIroutine\fR \fIaction\fR
+\fBSDataRequest\fR S\-DATA.REQUEST
+\fBSExpdRequest\fR S\-EXPEDITED\-DATA.REQUEST
+\fBSReadRequest\fR S\-READ.REQUEST (synchronous read)
+\fBSGTokenRequest\fR S\-TOKEN\-GIVE.REQUEST
+\fBSPTokenRequest\fR S\-TOKEN\-PLEASE.REQUEST
+\fBSRelRequest\fR S\-RELEASE.REQUEST
+\fBSRelResponse\fR S\-RELEASE.RESPONSE
+\fBSUAabortRequest\fR S\-U\-ABORT.REQUEST
+.re
+.fi
+.in -.5i
+.sp
+Note that the \fBSReadRequest\fR routine returns data from the peer by
+allocating memory.
+It should be freed before the structure is re\-used.
+.PP
+Also note that session utilizes a graceful closing mechanism.
+Upon receipt of a S\-RELEASE\-INDICATION event,
+the peer must immediately respond with an S\-RELEASE\-RESPONSE.
+Depending on the setting of the session requirements (described next),
+the peer may indicate refusal in the response.
+.PP
+Finally,
+the routine \fBSErrString\fR takes a failure code from a \fBSSAPabort\fR
+structure and returns a null\-terminated diagnostic string.
+Also,
+the routine \fBSLocalHostName\fR returns a null\-terminated string denoting
+the name of the localhost;
+.SH "SESSION REQUIREMENTS"
+During the connection\-establishment phase,
+the session\-users and session\-providers negotiate the characteristics of
+the connection.
+In particular,
+they negotiate the \*(lqsession requirements\*(rq.
+These requirements describe functional aspects of the connection,
+and are always negotiated downwards.
+primitives.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices 'u
+\*(EDisoservices ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoservices(5), tsapd(8c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO 8326:
+\fIInformation Processing Systems \-\- Open Systems Interconnection~---~
+Connection Oriented Session Service Definition\fR,
+.br
+CCITT Recommendation X.215:
+\fISession Service Definition for Open Systems Interconnection (OSI) for
+CCITT Applications\fR
+.SH DIAGNOSTICS
+All routines return the manifest constant \fBNOTOK\fR (\-1) on error.
+In addition,
+those routines which take a pointer to a \fBSSAPindication\fR structure
+fill\-in the structure as appropriate.
+.SH AUTHORS
+Marshall T. Rose
+.br
+Dwight E. Cass,
+Northrop Research and Technology Center
+.SH BUGS
+Do not confuse session\-descriptors with file\-descriptors.
+Unlike file\-descriptors which are implemented by the kernel,
+session\-descriptors do not work across \fIfork\fRs and \fIexec\fRs.
--- /dev/null
+/* llib-lssap - lint library for -lssap */
+
+/*
+ * $Header: /f/osi/ssap/RCS/llib-lssap,v 7.2 91/02/22 09:45:37 mrose Interim $
+ *
+ *
+ * $Log: llib-lssap,v $
+ * Revision 7.2 91/02/22 09:45:37 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 91/01/10 04:11:27 mrose
+ * foo
+ *
+ * Revision 7.0 89/11/23 22:25:18 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include "ssap.h"
+
+/* \f */
+
+/* SERVER only */
+
+int SExec (ts, si, hook, setperms)
+struct TSAPstart *ts;
+struct SSAPindication *si;
+IFP hook,
+ setperms;
+{
+ return SExec (ts, si, hook, setperms);
+}
+
+
+/* S-CONNECT.INDICATION */
+
+int SInit (vecp, vec, ss, si)
+int vecp;
+char **vec;
+struct SSAPstart *ss;
+struct SSAPindication *si;
+{
+ return SInit (vecp, vec, ss, si);
+}
+
+
+/* S-CONNECT.RESPONSE */
+
+int SConnResponse (sd, ref, responding, result, requirements, settings,
+ isn, data, cc, si)
+int sd;
+struct SSAPref *ref;
+struct SSAPaddr *responding;
+int result,
+ requirements,
+ settings,
+ cc;
+long isn;
+char *data;
+struct SSAPindication *si;
+{
+ return SConnResponse (sd, ref, responding, result, requirements, settings,
+ isn, data, cc, si);
+}
+
+
+/* S-(ASYN-)CONNECT.REQUEST */
+
+int SAsynConnRequest (ref, calling, called, requirements, settings, isn,
+ data, cc, qos, sc, si, async)
+struct SSAPref *ref;
+struct SSAPaddr *calling,
+ *called;
+int requirements,
+ settings,
+ cc,
+ async;
+long isn;
+char *data;
+struct QOStype *qos;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ return SAsynConnRequest (ref, calling, called, requirements, settings, isn,
+ data, cc, qos, sc, si, async);
+}
+
+
+/* S-ASYN-RETRY.REQUEST (pseudo) */
+
+int SAsynRetryRequest (sd, sc, si)
+int sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ return SAsynRetryRequest (sd, sc, si);
+}
+
+
+/* S-ASYN-NEXT.REQUEST (pseudo) */
+
+int SAsynNextRequest (sd, sc, si)
+int sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ return SAsynNextRequest (sd, sc, si);
+}
+
+
+/* S-DATA.REQUEST */
+
+int SDataRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SDataRequest (sd, data, cc, si);
+}
+
+
+/* S-SEND.REQUEST (segmented) */
+
+int SSendRequest (sd, data, cc, begin, end, si)
+int sd;
+char *data;
+int cc,
+ begin,
+ end;
+struct SSAPindication *si;
+{
+ return SSendRequest (sd, data, cc, begin, end, si);
+}
+
+
+/* S-WRITE.REQUEST (pseudo, write user data vectors) */
+
+int SWriteRequest (sd, typed, uv, si)
+int sd;
+int typed;
+struct udvec *uv;
+struct SSAPindication *si;
+{
+ return SWriteRequest (sd, typed, uv, si);
+}
+
+
+/* S-EXPEDITED-DATA.REQUEST */
+
+int SExpdRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SExpdRequest (sd, data, cc, si);
+}
+
+
+/* S-TYPED-DATA.REQUEST */
+
+int STypedRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return STypedRequest (sd, data, cc, si);
+}
+
+
+/* S-CAPABILITY-DATA.REQUEST */
+
+int SCapdRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SCapdRequest (sd, data, cc, si);
+}
+
+
+/* S-CAPABILITY-DATA.RESPONSE */
+
+int SCapdResponse (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SCapdResponse (sd, data, cc, si);
+}
+
+
+/* S-READ.REQUEST (pseudo; synchronous read) */
+
+int SReadRequest (sd, sx, secs, si)
+int sd;
+struct SSAPdata *sx;
+int secs;
+struct SSAPindication *si;
+{
+ return SReadRequest (sd, sx, secs, si);
+}
+
+
+/* S-TOKEN-GIVE.REQUEST */
+
+int SGTokenRequest (sd, tokens, si)
+int sd;
+int tokens;
+struct SSAPindication *si;
+{
+ return SGTokenRequest (sd, tokens, si);
+}
+
+
+/* S-TOKEN-PLEASE.REQUEST */
+
+int SPTokenRequest (sd, tokens, data, cc, si)
+int sd;
+int tokens,
+ cc;
+char *data;
+struct SSAPindication *si;
+{
+ return SPTokenRequest (sd, tokens, data, cc, si);
+}
+
+
+/* S-CONTROL-GIVE.REQUEST */
+
+int SGControlRequest (sd, si)
+int sd;
+struct SSAPindication *si;
+{
+ return SGControlRequest (sd, si);
+}
+
+
+/* S-MAJOR-SYNC.REQUEST */
+
+int SMajSyncRequest (sd, ssn, data, cc, si)
+int sd;
+long *ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SMajSyncRequest (sd, ssn, data, cc, si);
+}
+
+
+/* S-MAJOR-SYNC.RESPONSE */
+
+int SMajSyncResponse (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SMajSyncResponse (sd, data, cc, si);
+}
+
+
+/* S-MINOR-SYNC.REQUEST */
+
+int SMinSyncRequest (sd, type, ssn, data, cc, si)
+int sd;
+int type;
+long *ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SMinSyncRequest (sd, type, ssn, data, cc, si);
+}
+
+
+/* S-MINOR-SYNC.RESPONSE */
+
+int SMinSyncResponse (sd, ssn, data, cc, si)
+int sd;
+long ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SMinSyncResponse (sd, ssn, data, cc, si);
+}
+
+
+/* S-RESYNCHRONIZE.REQUEST */
+
+int SReSyncRequest (sd, type, ssn, settings, data, cc, si)
+int sd;
+int type,
+ settings;
+long ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SReSyncRequest (sd, type, ssn, settings, data, cc, si);
+}
+
+
+/* S-RESYNCHRONIZE.RESPONSE */
+
+int SReSyncResponse (sd, ssn, settings, data, cc, si)
+int sd;
+int settings;
+long ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SReSyncResponse (sd, ssn, settings, data, cc, si);
+}
+
+
+/* S-ACTIVITY-START.REQUEST */
+
+int SActStartRequest (sd, id, data, cc, si)
+int sd;
+struct SSAPactid *id;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SActStartRequest (sd, id, data, cc, si);
+}
+
+/* S-ACTIVITY-RESUME.REQUEST */
+
+int SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si)
+int sd;
+struct SSAPactid *id,
+ *oid;
+long ssn;
+struct SSAPref *ref;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si);
+}
+
+/* S-ACTIVITY-INTERRUPT.REQUEST */
+
+int SActIntrRequest (sd, reason, si)
+int sd;
+int reason;
+struct SSAPindication *si;
+{
+ return SActIntrRequest (sd, reason, si);
+}
+
+/* S-ACTIVITY-INTERRUPT.RESPONSE */
+
+int SActIntrResponse (sd, si)
+int sd;
+struct SSAPindication *si;
+{
+ return SActIntrResponse (sd, si);
+}
+
+/* S-ACTIVITY-DISCARD.REQUEST */
+
+int SActDiscRequest (sd, reason, si)
+int sd;
+int reason;
+struct SSAPindication *si;
+{
+ return SActDiscRequest (sd, reason, si);
+}
+
+/* S-ACTIVITY-DISCARD.RESPONSE */
+
+int SActDiscResponse (sd, si)
+int sd;
+struct SSAPindication *si;
+{
+ return SActDiscResponse (sd, si);
+}
+
+/* S-ACTIVITY-END.REQUEST */
+
+int SActEndRequest (sd, ssn, data, cc, si)
+int sd;
+long *ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SActEndRequest (sd, ssn, data, cc, si);
+}
+
+/* S-ACTIVITY-END.RESPONSE */
+
+int SActEndResponse (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SActEndResponse (sd, data, cc, si);
+}
+
+/* S-U-ABORT.REQUEST */
+
+int SUAbortRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SUAbortRequest (sd, data, cc, si);
+}
+
+
+/* S-U-EXCEPTION-REPORT.REQUEST */
+
+int SUReportRequest (sd, reason, data, cc, si)
+int sd;
+int reason;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SUReportRequest (sd, reason, data, cc, si);
+}
+
+/* S-RELEASE.REQUEST */
+
+int SRelRequest (sd, data, cc, secs, sr, si)
+int sd;
+char *data;
+int cc;
+int secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+ return SRelRequest (sd, data, cc, secs, sr, si);
+}
+
+
+/* S-RELEASE-RETRY.REQUEST (pseudo) */
+
+int SRelRetryRequest (sd, secs, sr, si)
+int sd;
+int secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+ return SRelRetryRequest (sd, secs, sr, si);
+}
+
+
+/* S-RELEASE.RESPONSE */
+
+int SRelResponse (sd, result, data, cc, si)
+int sd;
+int result,
+ cc;
+char *data;
+struct SSAPindication *si;
+{
+ return SRelResponse (sd, result, data, cc, si);
+}
+
+
+/* define vectors for INDICATION events */
+
+int SSetIndications (sd, data, tokens, sync, activity, report, finish,
+ abort, si)
+int sd;
+IFP data,
+ tokens,
+ sync,
+ activity,
+ report,
+ finish,
+ abort;
+struct SSAPindication *si;
+{
+ return SSetIndications (sd, data, tokens, sync, activity, report, finish,
+ abort, si);
+}
+
+
+/* map session descriptors for select() */
+
+int SSelectMask (sd, mask, nfds, si)
+int sd;
+fd_set *mask;
+int *nfds;
+struct SSAPindication *si;
+{
+ return SSelectMask (sd, mask, nfds, si);
+}
+
+
+/* return SSAP error code in string form */
+
+char *SErrString (c)
+int c;
+{
+ return SErrString (c);
+}
--- /dev/null
+: run this script through /bin/sh
+M=/bin/make
+if [ -f /usr/bin/make ]; then
+ M=/usr/bin/make
+fi
+
+exec $M MODULE=ssap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"}
--- /dev/null
+/* ssapabort.c - SPM: user abort */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapabort.c,v 7.2 91/02/22 09:45:39 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapabort.c,v 7.2 91/02/22 09:45:39 mrose Interim $
+ *
+ *
+ * $Log: ssapabort.c,v $
+ * Revision 7.2 91/02/22 09:45:39 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/11/21 11:31:41 mrose
+ * sun
+ *
+ * Revision 7.0 89/11/23 22:25:20 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f S-U-ABORT.REQUEST */
+
+int SUAbortRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ if ((sb = findsblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
+ }
+ toomuchP (sb, data, cc, SA_SIZE, "abort");
+
+ result = SUAbortRequestAux (sb, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SUAbortRequestAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ int result;
+ register struct ssapkt *s;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ sb -> sb_flags &= ~(SB_ED | SB_EDACK | SB_ERACK);
+
+ if ((sb -> sb_flags & SB_EXPD)
+ && sb -> sb_version >= SB_VRSN2
+ && cc > 9) {
+ register struct ssapkt *p;
+
+ if (p = newspkt (SPDU_PR)) {
+ p -> s_mask |= SMASK_PR_TYPE;
+ p -> s_pr_type = PR_AB;
+ result = spkt2sd (p, sb -> sb_fd, 1, si);
+ freespkt (p);
+ if (result == NOTOK)
+ goto out1;
+ }
+ }
+
+ if ((s = newspkt (SPDU_AB)) == NULL) {
+ result = ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out1;
+ }
+
+ s -> s_mask |= SMASK_SPDU_AB | SMASK_AB_DISC;
+ s -> s_ab_disconnect = AB_DISC_RELEASE | AB_DISC_USER;
+
+ if (cc > 0) {
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+ result = spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD ? 1 : 0, si);
+ s -> s_mask &= ~SMASK_UDATA_PGI;
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ freespkt (s);
+ if (result == NOTOK)
+ goto out1;
+
+ if (ses_ab_timer >= 0)
+ switch (TReadRequest (sb -> sb_fd, tx, ses_ab_timer, td)) {
+ case OK:
+ default: /* should be an ABORT ACCEPT, but who cares? */
+ TXFREE (tx);
+ break;
+
+ case NOTOK:
+ if (td -> td_reason != DR_TIMER)
+ sb -> sb_fd = NOTOK;
+ break;
+ }
+ result = OK;
+
+out1: ;
+ freesblk (sb);
+
+ return result;
+}
--- /dev/null
+/* ssapactchk.c - SPM: check activity constraints */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapactchk.c,v 7.1 91/02/22 09:45:40 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapactchk.c,v 7.1 91/02/22 09:45:40 mrose Interim $
+ *
+ *
+ * $Log: ssapactchk.c,v $
+ * Revision 7.1 91/02/22 09:45:40 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:21 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+
+/* \f */
+
+int SDoActivityAux (sb, si, act, rls)
+register struct ssapblk *sb;
+register struct SSAPindication *si;
+int act,
+ rls;
+{
+ if (act) {
+ if (!(sb -> sb_requirements & SR_ACT_EXISTS))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "activity management service unavailable");
+
+ if (sb -> sb_flags & SB_Vact)
+ return ssaplose (si, SC_OPERATION, NULLCP, "activity in progress");
+ }
+ else
+ if (!(sb -> sb_requirements & SR_MAJ_EXISTS))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "major synchronize service unavailable");
+
+ if ((sb -> sb_requirements & SR_DAT_EXISTS)
+ && !(sb -> sb_owned & ST_DAT_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "data token not owned by you");
+
+ if ((sb -> sb_requirements & SR_MIN_EXISTS)
+ && !(sb -> sb_owned & ST_MIN_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "minorsync not owned by you");
+
+ if (act) {
+ if (!(sb -> sb_owned & ST_ACT_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "activity token not owned by you");
+ }
+ else
+ if (!(sb -> sb_owned & ST_MAJ_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "majorsync token not owned by you");
+
+ if (rls)
+ if ((sb -> sb_requirements & SR_RLS_EXISTS)
+ && !(sb -> sb_owned & ST_RLS_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "release token not owned by you");
+
+ return OK;
+}
--- /dev/null
+/* ssapactitivity.c - SPM: activities */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapactivity.c,v 7.1 91/02/22 09:45:42 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapactivity.c,v 7.1 91/02/22 09:45:42 mrose Interim $
+ *
+ *
+ * $Log: ssapactivity.c,v $
+ * Revision 7.1 91/02/22 09:45:42 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:22 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-CONTROL-GIVE.REQUEST */
+
+int SGControlRequest (sd, si)
+int sd;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+
+ result = SGControlRequestAux (sb, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SGControlRequestAux (sb, si)
+register struct ssapblk *sb;
+register struct SSAPindication *si;
+{
+ int result;
+ register struct ssapkt *s;
+
+ if (SDoActivityAux (sb, si, 1, 1) == NOTOK)
+ return NOTOK;
+
+ if (sb -> sb_flags & SB_GTC)
+ return ssaplose (si, SC_OPERATION, NULLCP, "give control in progress");
+
+ if ((s = newspkt (SPDU_GTC)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+ if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_owned = 0;
+ sb -> sb_flags |= SB_GTC;
+ }
+ freespkt (s);
+
+ return result;
+}
+
+/* \f S-ACTIVITY-START.REQUEST */
+
+int SActStartRequest (sd, id, data, cc, si)
+int sd;
+struct SSAPactid *id;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (id);
+ idmuchP (id);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SV_SIZE, "activity start");
+
+ result = SActStartRequestAux (sb, id, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SActStartRequestAux (sb, id, data, cc, si)
+register struct ssapblk *sb;
+struct SSAPactid *id;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (SDoActivityAux (sb, si, 1, 0) == NOTOK)
+ return NOTOK;
+
+ if ((result = SWriteRequestAux (sb, SPDU_AS, data, cc, 0, 0L, 0, id,
+ NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_V_A = sb -> sb_V_M = sb -> sb_V_R = 1;
+ sb -> sb_flags |= SB_Vact;
+ }
+
+ return result;
+}
+
+/* \f S-ACTIVITY-RESUME.REQUEST */
+
+int SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si)
+int sd;
+struct SSAPactid *id,
+ *oid;
+long ssn;
+struct SSAPref *ref;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (id);
+ idmuchP (id);
+ missingP (oid);
+ idmuchP (oid);
+ if (SERIAL_MIN > ssn || ssn > SERIAL_MAX)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid serial number");
+#ifdef notdef
+ missingP (ref);
+#endif
+ if (ref)
+ refmuchP (ref)
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SV_SIZE, "activity resume");
+
+ result = SActResumeRequestAux (sb, id, oid, ssn, ref, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SActResumeRequestAux (sb, id, oid, ssn, ref, data, cc, si)
+register struct ssapblk *sb;
+struct SSAPactid *id,
+ *oid;
+long ssn;
+struct SSAPref *ref;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (SDoActivityAux (sb, si, 1, 0) == NOTOK)
+ return NOTOK;
+
+ if ((result = SWriteRequestAux (sb, SPDU_AR, data, cc, 0, ssn, 0, id,
+ oid, ref, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_V_A = sb -> sb_V_M = ssn + 1;
+ sb -> sb_V_R = 1;
+ sb -> sb_flags |= SB_Vact;
+ }
+
+ return result;
+}
+
+/* \f S-ACTIVITY-INTERRUPT.REQUEST */
+
+int SActIntrRequest (sd, reason, si)
+int sd;
+int reason;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ if (!(SP_OK (reason)))
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid reason");
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapXsig (sb, sd);
+ if (sb -> sb_flags & SB_MAP) {
+ (void) sigsetmask (smask);
+ return ssaplose (si, SC_OPERATION, NULLCP, "majorsync in progress");
+ }
+
+ result = SActIntrRequestAux (sb, reason, SPDU_AI, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SActIntrRequestAux (sb, reason, type, si)
+register struct ssapblk *sb;
+int reason,
+ type;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_ACTIVITY))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "activity management service unavailable");
+ if (!(sb -> sb_owned & ST_ACT_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "activity token not owned by you");
+ if (!(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no activity in progress");
+ if ((sb -> sb_flags & SB_RA)
+ && SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+ type == SPDU_AI ? SYNC_INTR : SYNC_DISC, 0L,
+ sb -> sb_rs, sb -> sb_rsn) == NOTOK)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "resync in progress takes precedence");
+
+ if ((result = SWriteRequestAux (sb, type, NULLCP, 0, reason, 0L, 0,
+ NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_flags |= SB_AI, sb -> sb_flags &= ~(SB_RA | SB_EDACK | SB_ERACK);
+ sb -> sb_rs = type == SPDU_AI ? SYNC_INTR : SYNC_DISC;
+ }
+
+ return result;
+}
+
+/* \f S-ACTIVITY-INTERRUPT.RESPONSE */
+
+int SActIntrResponse (sd, si)
+int sd;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapAsig (sb, sd);
+
+ result = SActIntrResponseAux (sb, SPDU_AIA, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SActIntrResponseAux (sb, type, si)
+register struct ssapblk *sb;
+int type;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_ACTIVITY))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "activity management service unavailable");
+ if (!(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no activity in progress");
+ if (!(sb -> sb_flags & SB_AIA))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no activity interrupt/discard in progress");
+
+ if ((result = SWriteRequestAux (sb, type, NULLCP, 0, 0, 0L, 0,
+ NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_flags &= ~(SB_AIA | SB_Vact);
+ sb -> sb_owned = 0;
+ }
+
+ return result;
+}
+
+/* \f S-ACTIVITY-DISCARD.REQUEST */
+
+int SActDiscRequest (sd, reason, si)
+int sd;
+int reason;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ if (!(SP_OK (reason)))
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid reason");
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapXsig (sb, sd);
+ if (sb -> sb_flags & SB_MAP) {
+ (void) sigsetmask (smask);
+ return ssaplose (si, SC_OPERATION, NULLCP, "majorsync in progress");
+ }
+
+ result = SActIntrRequestAux (sb, reason, SPDU_AD, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f S-ACTIVITY-DISCARD.RESPONSE */
+
+int SActDiscResponse (sd, si)
+int sd;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapAsig (sb, sd);
+
+ result = SActIntrResponseAux (sb, SPDU_ADA, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f S-ACTIVITY-END.REQUEST */
+
+int SActEndRequest (sd, ssn, data, cc, si)
+int sd;
+long *ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (ssn);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SV_SIZE, "activity end");
+
+ result = SMajSyncRequestAux (sb, ssn, data, cc, 0, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f S-ACTIVITY-END.RESPONSE */
+
+int SActEndResponse (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SV_SIZE, "activity end");
+
+ result = SMajSyncResponseAux (sb, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
--- /dev/null
+/* ssapcapd1.c - SPM: write capability data */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapcapd1.c,v 7.1 91/02/22 09:45:43 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapcapd1.c,v 7.1 91/02/22 09:45:43 mrose Interim $
+ *
+ *
+ * $Log: ssapcapd1.c,v $
+ * Revision 7.1 91/02/22 09:45:43 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:23 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-CAPABILITY-DATA.REQUEST */
+
+int SCapdRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SX_CDSIZE, "capability");
+
+ result = SCapdRequestAux (sb, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SCapdRequestAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_CAPABILITY))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "capability data exchange service unavailable");
+ if (SDoActivityAux (sb, si, 1, 0) == NOTOK)
+ return NOTOK;
+ if (sb -> sb_flags & SB_CD)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "capability data request in progress");
+ sb -> sb_flags |= SB_CD;
+
+ if ((result = SWriteRequestAux (sb, SPDU_CD, data, cc, 0, 0L, 0, NULLSD,
+ NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+
+ return result;
+}
--- /dev/null
+/* ssapcapd2.c - SPM: read capability data */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapcapd2.c,v 7.1 91/02/22 09:45:44 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapcapd2.c,v 7.1 91/02/22 09:45:44 mrose Interim $
+ *
+ *
+ * $Log: ssapcapd2.c,v $
+ * Revision 7.1 91/02/22 09:45:44 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:24 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-CAPABILITY-DATA.RESPONSE */
+
+int SCapdResponse (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SX_CDASIZE, "capability");
+
+ result = SCapdResponseAux (sb, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SCapdResponseAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_CAPABILITY))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "capability data exchange service unavailable");
+ if (!(sb -> sb_flags & SB_CDA))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no capability data response in progress");
+
+ if ((result = SWriteRequestAux (sb, SPDU_CDA, data, cc, 0, 0L, 0, NULLSD,
+ NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else
+ sb -> sb_flags &= ~SB_CDA;
+
+ return result;
+}
--- /dev/null
+/* ssaperror.c - return SSAP error code in string form */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaperror.c,v 7.2 91/02/22 09:45:45 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaperror.c,v 7.2 91/02/22 09:45:45 mrose Interim $
+ *
+ *
+ * $Log: ssaperror.c,v $
+ * Revision 7.2 91/02/22 09:45:45 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 91/01/11 07:09:17 mrose
+ * jpo
+ *
+ * Revision 7.0 89/11/23 22:25:25 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "ssap.h"
+
+/* \f */
+
+static char *reject_err0[] = {
+ "Reason not specified",
+ "Temporary congestion",
+ "Rejected"
+};
+
+static int reject_err0_cnt = sizeof reject_err0 / sizeof reject_err0[0];
+
+
+static char *reject_err8[] = {
+ "unknown error code 0x80",
+ "SSAP identifier unknown",
+ "SS-user not attached to SSAP",
+ "Congestion at SSAP",
+ "Proposed protocol versions not supported",
+ "Address unknown",
+ "Connect request refused on this network connection",
+ "Transport disconnect",
+ "Provider-initiated abort",
+ "Protocol error",
+ "Invalid parameter",
+ "Invalid operation",
+ "Timer expired",
+ "Indications waiting"
+};
+
+static int reject_err8_cnt = sizeof reject_err8 / sizeof reject_err8[0];
+
+
+/* \f */
+
+char *SErrString(code)
+register int code;
+{
+ register int fcode;
+ static char buffer[50];
+
+ code &= 0xff;
+ if (code & SC_BASE) {
+ if ((fcode = code & ~SC_BASE) < reject_err8_cnt)
+ return reject_err8[fcode];
+ }
+ else
+ if (code < reject_err0_cnt)
+ return reject_err0[code];
+
+ (void) sprintf (buffer, "unknown error code 0x%x", code);
+ return buffer;
+}
--- /dev/null
+/* ssapexec.c - SPM: exec */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapexec.c,v 7.1 91/02/22 09:45:46 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapexec.c,v 7.1 91/02/22 09:45:46 mrose Interim $
+ *
+ *
+ * $Log: ssapexec.c,v $
+ * Revision 7.1 91/02/22 09:45:46 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:26 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+/* \f SERVER only */
+
+int SExec (ts, si, hook, setperms)
+struct TSAPstart *ts;
+struct SSAPindication *si;
+IFP hook,
+ setperms;
+{
+ int sd;
+ char *cp;
+ register struct isoservent *is;
+ register struct ssapkt *s;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if (TReadRequest (sd = ts -> ts_sd, tx, NOTOK, td) == NOTOK)
+ return ts2sslose (si, "TReadRequest", td);
+
+ s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, NULLIP);
+ TXFREE (tx);
+
+ if (s == NULL || s -> s_errno != SC_ACCEPT) {
+ (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST) | SC_REFUSE,
+ NULLCP, NULLCP);
+ goto out1;
+ }
+
+ switch (s -> s_code) {
+ case SPDU_CN:
+ if ((s -> s_mask & SMASK_CN_VRSN)
+ && !(s -> s_cn_version & SB_ALLVRSNS)) {
+ (void) spktlose (sd, si, SC_VERSION | SC_REFUSE, NULLCP,
+ "version mismatch: expecting 0x%x, got 0x%x",
+ SB_ALLVRSNS, s -> s_cn_version);
+ break;
+ }
+
+ if ((s -> s_mask & SMASK_CN_CALLED) && s -> s_calledlen > 0) {
+ if ((is = getisoserventbyselector ("ssap", s -> s_called,
+ s -> s_calledlen)) == NULL) {
+ char buffer[BUFSIZ];
+
+ buffer[explode (buffer, (u_char *) s -> s_called,
+ s -> s_calledlen)] = NULL;
+ (void) spktlose (sd, si, SC_SSAPID | SC_REFUSE, NULLCP,
+ "ISO service ssap/%s not found", buffer);
+ break;
+ }
+ }
+ else
+ if ((is = getisoserventbyname ("presentation", "ssap"))
+ == NULL) {
+ (void) spktlose (sd, si, SC_SSUSER | SC_REFUSE, NULLCP,
+ "default presentation service not found");
+ break;
+ }
+
+ if (TSaveState (sd, is -> is_tail, td) == NOTOK) {
+ (void) spktlose (sd, si, SC_CONGEST | SC_REFUSE, NULLCP,
+ NULLCP);
+ break;
+ }
+ cp = *is -> is_tail++;
+ if ((*is -> is_tail++ = spkt2str (s)) == NULL) {
+ (void) spktlose (sd, si, SC_CONGEST | SC_REFUSE, NULLCP,
+ NULLCP);
+ break;
+ }
+ *is -> is_tail = NULL;
+
+ switch (hook ? (*hook) (is, si) : OK) {
+ case NOTOK:
+ return NOTOK;
+
+ case DONE:
+ return OK;
+
+ case OK:
+ default:
+ if (setperms)
+ (void) (*setperms) (is);
+ (void) execv (*is -> is_vec, is -> is_vec);
+ SLOG (ssap_log, LLOG_FATAL, *is -> is_vec,
+ ("unable to exec"));
+ (void) TRestoreState (cp, ts, td);
+ (void) spktlose (ts -> ts_sd, si, SC_CONGEST | SC_REFUSE,
+ *is -> is_vec, "unable to exec");
+ break;
+ }
+ break;
+
+ default:
+ (void) spktlose (sd, si, SC_PROTOCOL | SC_REFUSE, NULLCP,
+ "session protocol mangled: expecting 0x%x, got 0x%x",
+ SPDU_CN, s -> s_code);
+ break;
+ }
+
+out1: ;
+ freespkt (s);
+
+ return NOTOK;
+}
--- /dev/null
+/* ssapexpd.c - SPM: write expedited data */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapexpd.c,v 7.1 91/02/22 09:45:47 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapexpd.c,v 7.1 91/02/22 09:45:47 mrose Interim $
+ *
+ *
+ * $Log: ssapexpd.c,v $
+ * Revision 7.1 91/02/22 09:45:47 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:27 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-EXPEDITED-DATA.REQUEST */
+
+int SExpdRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (data);
+ if (cc > SX_EXSIZE)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "too much expedited user data, %d octets", cc);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+
+ result = SExpdRequestAux (sb, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SExpdRequestAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ int result;
+ register struct ssapkt *s;
+
+ if (!(sb -> sb_requirements & SR_EXPEDITED))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "expedited data service unavailable");
+
+ if ((s = newspkt (SPDU_EX)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+ s -> s_udata = data, s -> s_ulen = cc;
+ result = spkt2sd (s, sb -> sb_fd, 1, si);
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ freespkt (s);
+
+ if (result == NOTOK)
+ freesblk (sb);
+
+ return result;
+}
--- /dev/null
+/* ssapinitiate.c - SPM: initiator */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.3 91/02/22 09:45:48 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapinitiate.c,v 7.3 91/02/22 09:45:48 mrose Interim $
+ *
+ *
+ * $Log: ssapinitiate.c,v $
+ * Revision 7.3 91/02/22 09:45:48 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/01/27 10:27:27 mrose
+ * touch-up
+ *
+ * Revision 7.1 89/11/27 10:30:40 mrose
+ * sync
+ *
+ * Revision 7.0 89/11/23 22:25:27 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f S-(ASYN-)CONNECT.REQUEST */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ switch (settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE << shift: \
+ case ST_RESP_VALUE << shift: \
+ case ST_CALL_VALUE << shift: \
+ break; \
+ \
+ default: \
+ return ssaplose (si, SC_PARAMETER, NULLCP, \
+ "improper choice of %s token setting", type); \
+ } \
+}
+
+/* \f */
+
+int SAsynConnRequest (ref, calling, called, requirements, settings, isn,
+ data, cc, qos, sc, si, async)
+struct SSAPref *ref;
+struct SSAPaddr *calling,
+ *called;
+int requirements,
+ settings,
+ cc,
+ async;
+long isn;
+char *data;
+struct QOStype *qos;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+
+ isodetailor (NULLCP, 0);
+
+ missingP (ref);
+ refmuchP (ref);
+ if (ref -> sr_vlen)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
+#ifdef notdef
+ missingP (calling);
+#endif
+ missingP (called);
+
+ if (requirements & ~SR_MYREQUIRE)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "requirements settings not supported");
+ if ((requirements & SR_EXCEPTIONS)
+ && !(requirements & SR_HALFDUPLEX))
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "exception service requires half-duplex service");
+
+ dotokens ();
+
+ if (requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
+ if (!(requirements & SR_ACTIVITY) || isn != SERIAL_NONE)
+ if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "bad choice for initial serial number");
+ }
+ else
+ if (isn != SERIAL_NONE)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "initial serial number invalid given requirements");
+
+ if (data == NULL)
+ cc = 0;
+ else
+ if (cc > CONNECT_MAX)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "too much initial user data, %d octets", cc);
+
+#ifdef notdef
+ missingP (qos);
+#endif
+ missingP (sc);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ result = SConnRequestAux (ref, calling, called, requirements, settings,
+ isn, data, cc, qos, sc, si, async);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+#undef dotoken
+
+/* \f */
+
+static int SConnRequestAux (ref, calling, called, requirements, settings, isn,
+ data, cc, qos, sc, si, async)
+struct SSAPref *ref;
+struct SSAPaddr *calling,
+ *called;
+int requirements,
+ settings,
+ cc,
+ async;
+long isn;
+char *data;
+struct QOStype *qos;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ int result;
+ register struct ssapkt *s;
+ register struct ssapblk *sb;
+ struct TSAPconnect tcs;
+ register struct TSAPconnect *tc = &tcs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if ((sb = newsblk ()) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ if (!async || qos == NULLQOS || qos -> qos_maxtime <= 0)
+ sb -> sb_maxtime = NOTOK;
+ else
+ sb -> sb_maxtime = qos -> qos_maxtime;
+
+ if ((s = newspkt (SPDU_CN)) == NULL) {
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out1;
+ }
+
+#ifdef notdef
+ if (called -> sa_selectlen > 0) {
+ if (calling == NULLSA) {
+ static struct SSAPaddr sas;
+
+ calling = &sas;
+ bzero ((char *) calling, sizeof *calling);
+ }
+
+ if (calling -> sa_selectlen == 0) {
+ calling -> sa_port =
+ htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
+ calling -> sa_selectlen = sizeof calling -> sa_port;
+ }
+ }
+#endif
+
+ if (calling) {
+ if (calling -> sa_selectlen > 0) {
+ s -> s_mask |= SMASK_CN_CALLING;
+ bcopy (calling -> sa_selector, s -> s_calling,
+ s -> s_callinglen = calling -> sa_selectlen);
+ }
+ sb -> sb_initiating = *calling; /* struct copy */
+ }
+
+ if (called -> sa_selectlen > 0) {
+ s -> s_mask |= SMASK_CN_CALLED;
+ bcopy (called -> sa_selector, s -> s_called,
+ s -> s_calledlen = called -> sa_selectlen);
+ }
+ sb -> sb_responding = *called; /* struct copy */
+
+ sb -> sb_requirements = requirements;
+ sb -> sb_settings = settings;
+
+ if ((result = TAsynConnRequest (calling ? &calling -> sa_addr : NULLTA,
+ &called -> sa_addr,
+ (qos ? qos -> qos_extended : 0)
+ || ((requirements & SR_EXPEDITED) ? 1 : 0),
+ NULLCP, 0, qos, tc, td, async)) == NOTOK) {
+ (void) ts2sslose (si, "TAsynConnRequest", td);
+
+ bzero ((char *) sc, sizeof *sc);
+ sc -> sc_sd = NOTOK;
+ sc -> sc_result = si -> si_abort.sa_reason;
+
+ result = DONE;
+ goto out2;
+ }
+
+ sb -> sb_fd = tc -> tc_sd;
+ if (qos && qos -> qos_sversion < 0) {
+ sb -> sb_version = SB_VRSN1;
+ sb -> sb_vrsnmask = SB_ALLVRSNS;
+ }
+ else
+ sb -> sb_vrsnmask = 1 << (sb -> sb_version =
+ (cc > SS_SIZE
+ || (qos && qos -> qos_sversion > 1))
+ ? SB_VRSN2 : SB_VRSN1);
+
+ s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
+ s -> s_cn_reference = *ref; /* struct copy */
+ s -> s_options = CR_OPT_NULL;
+ s -> s_cn_version = sb -> sb_vrsnmask;
+
+ if (isn != SERIAL_NONE) {
+ s -> s_mask |= SMASK_CN_ISN;
+ s -> s_isn = isn;
+ }
+
+ if (cc > 0) { /* XXX: user musn't touch! */
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ sb -> sb_retry = s;
+ if (async) {
+ switch (result) {
+ case CONNECTING_1:
+ case CONNECTING_2:
+ sc -> sc_sd = sb -> sb_fd;
+ return result;
+ }
+ }
+ if ((result = SAsynRetryAux (sb, tc, sc, si)) == DONE && !async)
+ result = OK;
+ return result;
+
+out2: ;
+ freespkt (s);
+out1: ;
+ freesblk (sb);
+
+ return result;
+}
+
+/* \f S-ASYN-RETRY.REQUEST (pseudo) */
+
+int SAsynRetryRequest (sd, sc, si)
+int sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+ struct TSAPconnect tcs;
+ register struct TSAPconnect *tc = &tcs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ missingP (sc);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ if ((sb = findsblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "invalid session descriptor");
+ }
+ if (sb -> sb_flags & SB_CONN) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "session descriptor connected");
+ }
+
+ switch (result = TAsynRetryRequest (sb -> sb_fd, tc, td)) {
+ case NOTOK:
+ (void) ts2sslose (si, "TAsynRetryRequest", td);
+ sb -> sb_fd = NOTOK;
+
+ bzero ((char *) sc, sizeof *sc);
+ sc -> sc_sd = NOTOK;
+ sc -> sc_result = si -> si_abort.sa_reason;
+
+ result = DONE;
+ freesblk (sb);
+ break;
+
+ case CONNECTING_1:
+ case CONNECTING_2:
+ break;
+
+ case DONE:
+ result = SAsynRetryAux (sb, tc, sc, si);
+ break;
+ }
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f S-ASYN-NEXT.REQUEST (pseudo) */
+
+int SAsynNextRequest (sd, sc, si)
+int sd;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+ struct TSAPconnect tcs;
+ register struct TSAPconnect *tc = &tcs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ missingP (sc);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ if ((sb = findsblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "invalid session descriptor");
+ }
+ if (sb -> sb_flags & SB_CONN) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "session descriptor connected");
+ }
+
+ switch (result = TAsynNextRequest (sb -> sb_fd, tc, td)) {
+ case NOTOK:
+ (void) ts2sslose (si, "TAsynRetryRequest", td);
+ sb -> sb_fd = NOTOK;
+
+ bzero ((char *) sc, sizeof *sc);
+ sc -> sc_sd = NOTOK;
+ sc -> sc_result = si -> si_abort.sa_reason;
+
+ result = DONE;
+ freesblk (sb);
+ break;
+
+ case CONNECTING_1:
+ case CONNECTING_2:
+ break;
+
+ case DONE:
+ result = SAsynRetryAux (sb, tc, sc, si);
+ break;
+ }
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) { \
+ switch (sb -> sb_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ if (!(s -> s_mask & SMASK_CN_SET)) \
+ s -> s_settings = ST_INIT_VALUE << shift; \
+ switch (s -> s_settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE << shift: \
+ default: \
+ sb -> sb_owned |= bit; \
+ sc -> sc_settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ sc -> sc_settings |= ST_RESP_VALUE << shift; \
+ break; \
+ } \
+ break; \
+ \
+ case ST_INIT_VALUE << shift: \
+ sb -> sb_owned |= bit; \
+ sc -> sc_settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ sc -> sc_settings |= ST_RESP_VALUE << shift; \
+ break; \
+ } \
+ \
+ if ((s -> s_mask & SMASK_AC_TOKEN) && (s -> s_ac_token & bit)) \
+ sc -> sc_please |= bit; \
+ } \
+}
+
+/* \f */
+
+static int SAsynRetryAux (sb, tc, sc, si)
+register struct ssapblk *sb;
+struct TSAPconnect *tc;
+struct SSAPconnect *sc;
+struct SSAPindication *si;
+{
+ int len,
+ result;
+ register struct ssapkt *s;
+
+ s = sb -> sb_retry;
+ sb -> sb_retry = NULL;
+
+ sb -> sb_responding.sa_addr = tc -> tc_responding; /* struct copy */
+ if (tc -> tc_expedited)
+ sb -> sb_flags |= SB_EXPD;
+ else
+ sb -> sb_requirements &= ~SR_EXPEDITED;
+ if (sb -> sb_version < SB_VRSN2) /* XXX */
+ sb -> sb_tsdu_us = sb -> sb_tsdu_them =
+ GET_TSDU_SIZE (tc -> tc_tsdusize);
+
+ if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
+ s -> s_mask |= SMASK_CN_TSDU;
+ s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
+ s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
+ }
+
+ s -> s_mask |= SMASK_CN_REQ;
+ if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
+ s -> s_mask |= SMASK_CN_SET;
+ s -> s_settings = sb -> sb_settings;
+ }
+
+ result = spkt2sd (s, sb -> sb_fd, 0, si);
+ s -> s_mask &= ~SMASK_UDATA_PGI;
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ freespkt (s);
+ if (result == NOTOK)
+ goto out1;
+
+ if ((s = sb2spkt (sb, si, sb -> sb_maxtime, NULLTX)) == NULL) {
+ if (si -> si_abort.sa_reason == SC_TIMER)
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "remote SPM timed-out");
+ result = NOTOK;
+ goto out2;
+ }
+
+ bzero ((char *) sc, sizeof *sc);
+ switch (s -> s_code) {
+ case SPDU_AC:
+ sc -> sc_sd = sb -> sb_fd;
+ sc -> sc_result = SC_ACCEPT;
+ if (s -> s_mask & SMASK_CN_REF)
+ sc -> sc_connect = s -> s_cn_reference; /* struct copy */
+ if (s -> s_mask & SMASK_CN_OPT)
+ sb -> sb_options = s -> s_options;
+ if (!(s -> s_mask & SMASK_CN_TSDU))
+ s -> s_tsdu_init = s -> s_tsdu_resp = 0;
+ if (s -> s_tsdu_init < sb -> sb_tsdu_us)
+ sb -> sb_tsdu_us = s -> s_tsdu_init;
+ if (s -> s_tsdu_resp < sb -> sb_tsdu_them)
+ sb -> sb_tsdu_them = s -> s_tsdu_resp;
+ if (BAD_TSDU_SIZE (sb -> sb_tsdu_us)) {
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "perposterous TSDU size (%d) for initiator",
+ sb -> sb_tsdu_us);
+ goto out2;
+ }
+ if (BAD_TSDU_SIZE (sb -> sb_tsdu_them)) {
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "perposterous TSDU size (%d) for responder",
+ sb -> sb_tsdu_them);
+ goto out2;
+ }
+ if (s -> s_mask & SMASK_CN_VRSN) {
+ if (!(s -> s_cn_version & sb -> sb_vrsnmask)) {
+ /* not SC_VERSION */
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "version mismatch: expecting something in 0x%x, got 0x%x",
+ sb -> sb_vrsnmask, s -> s_cn_version);
+ goto out2;
+ }
+ sb -> sb_vrsnmask &= s -> s_cn_version;
+ }
+ sb -> sb_version = (sb -> sb_vrsnmask & (1 << SB_VRSN2))
+ ? SB_VRSN2 : SB_VRSN1;
+ if (s -> s_mask & SMASK_CN_ISN)
+ sc -> sc_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
+ else
+ sc -> sc_isn = SERIAL_NONE;
+ if (!(s -> s_mask & SMASK_CN_REQ)) {
+ s -> s_mask |= SMASK_CN_REQ;
+ s -> s_cn_require = SR_DEFAULT;
+ }
+ switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
+ case SR_HALFDUPLEX:
+ if (s -> s_cn_require & SR_HALFDUPLEX)
+ break;
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "half-duplex negotiation failed");
+ goto out2;
+
+ case SR_DUPLEX:
+ if (s -> s_cn_require & SR_DUPLEX)
+ break;
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "full-duplex negotiation failed");
+ goto out2;
+
+ default:
+ break;
+ }
+#ifdef notdef /* screwy session protocol... */
+ if (s -> s_cn_require & ~sb -> sb_requirements) {
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "requirements negotiation failed");
+ goto out2;
+ }
+#endif
+ sb -> sb_requirements &= s -> s_cn_require;
+ switch (sb -> sb_requirements & (SR_HALFDUPLEX | SR_DUPLEX)) {
+ case SR_HALFDUPLEX:
+ case SR_DUPLEX:
+ break;
+
+ default:
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "half/full-duplex negotiation failed");
+ goto out2;
+ }
+ if ((sb -> sb_requirements & SR_EXCEPTIONS)
+ && !(sb -> sb_requirements & SR_HALFDUPLEX)) {
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "exception service requires half-duplex service");
+ goto out2;
+ }
+ sc -> sc_requirements = sb -> sb_requirements;
+ sc -> sc_settings = sc -> sc_please = 0;
+ dotokens ();
+ if (s -> s_mask & SMASK_CN_CALLED) {
+ if ((len = s -> s_calledlen)
+ > sizeof sb -> sb_responding.sa_selector)
+ len = sizeof sb -> sb_responding.sa_selector;
+ bcopy (s -> s_called, sb -> sb_responding.sa_selector,
+ sb -> sb_responding.sa_selectlen = len);
+ }
+ sc -> sc_responding = sb -> sb_responding; /* struct copy */
+ if ((sc -> sc_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
+ sc -> sc_ssdusize = tc -> tc_tsdusize - SSDU_MAGIC;
+ sc -> sc_qos = tc -> tc_qos; /* struct copy */
+ sc -> sc_qos.qos_sversion = sb -> sb_version + 1;
+ sc -> sc_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
+ copySPKTdata (s, sc);
+
+ freespkt (s);
+ sb -> sb_flags |= SB_CONN | SB_INIT;
+
+ return DONE;
+
+ case SPDU_RF: /* ignore s -> s_rf_disconnect */
+ sc -> sc_sd = NOTOK;
+ sc -> sc_result = s -> s_rlen > 0 ? *s -> s_rdata
+ : SC_NOTSPECIFIED;
+ if (s -> s_mask & SMASK_RF_REF)
+ sc -> sc_connect = s -> s_rf_reference; /* struct copy */
+ if ((sc -> sc_result == SC_REJECTED)
+ && (s -> s_mask & SMASK_RF_REQ))
+ sc -> sc_requirements = s -> s_rf_require;
+ if ((s -> s_mask & SMASK_CN_CALLED)
+ && (sc -> sc_result & SC_BASE)) {
+ if ((len = s -> s_calledlen)
+ > sizeof sb -> sb_responding.sa_selector)
+ len = sizeof sb -> sb_responding.sa_selector;
+ bcopy (s -> s_called, sb -> sb_responding.sa_selector,
+ sb -> sb_responding.sa_selectlen = len);
+ }
+ sc -> sc_responding = sb -> sb_responding; /* struct copy */
+ sc -> sc_data = s -> s_rdata + 1, sc -> sc_cc = s -> s_rlen - 1;
+ sc -> sc_realdata = s -> s_rdata, s -> s_rdata = NULL;
+ si -> si_type = SI_ABORT;
+ {
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ sa -> sa_peer = 0;
+ sa -> sa_reason = sc -> sc_result;
+ sa -> sa_info = sc -> sc_data, sa -> sa_cc = sc -> sc_cc;
+ sa -> sa_realinfo = NULL;
+ }
+ result = DONE;
+ break;
+
+ case SPDU_AB:
+ sc -> sc_sd = NOTOK;
+ sc -> sc_result = SC_ABORT;
+ si -> si_type = SI_ABORT;
+ {
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
+ ? 1 : 0))
+ sa -> sa_reason = sc -> sc_result;
+ sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
+ sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
+ }
+ result = DONE;
+ break;
+
+ default:
+ result = spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: expecting 0x%x, got 0x%x",
+ SPDU_AC, s -> s_code);
+ break;
+ }
+
+out2: ;
+ freespkt (s);
+out1: ;
+ freesblk (sb);
+
+ return result;
+}
+
+#undef dotoken
--- /dev/null
+/* ssaplose.c - SPM: you lose */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaplose.c,v 7.2 91/02/22 09:45:50 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaplose.c,v 7.2 91/02/22 09:45:50 mrose Interim $
+ *
+ *
+ * $Log: ssaplose.c,v $
+ * Revision 7.2 91/02/22 09:45:50 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/11/21 11:31:43 mrose
+ * sun
+ *
+ * Revision 7.0 89/11/23 22:25:29 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <varargs.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f */
+
+#ifndef lint
+int spktlose (va_alist)
+va_dcl
+{
+ int reason,
+ result,
+ sd,
+ secs,
+ value;
+ register struct ssapblk *sb;
+ register struct ssapkt *s;
+ struct SSAPindication sis;
+ register struct SSAPindication *si;
+ register struct SSAPabort *sa;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+ va_list ap;
+
+ va_start (ap);
+
+ sd = va_arg (ap, int);
+
+ si = va_arg (ap, struct SSAPindication *);
+ if (si == NULL)
+ si = &sis;
+
+ reason = va_arg (ap, int);
+ value = reason & SC_REFUSE;
+ reason &= ~SC_REFUSE;
+
+ result = _ssaplose (si, reason, ap);
+
+ va_end (ap);
+
+ if ((sa = &si -> si_abort) -> sa_cc > 0) {
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("spktlose [%s] %*.*s", SErrString (sa -> sa_reason),
+ sa -> sa_cc, sa -> sa_cc, sa -> sa_data));
+ }
+ else
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("spktlose [%s]", SErrString (sa -> sa_reason)));
+
+ if (value && SC_OFFICIAL (reason)) {
+ if ((s = newspkt (SPDU_RF)) == NULL)
+ return result;
+
+ s -> s_mask |= SMASK_RF_DISC;
+ s -> s_rf_disconnect |= RF_DISC_RELEASE;
+
+ if (reason == SC_VERSION) {
+ s -> s_mask |= SMASK_RF_VRSN;
+ s -> s_rf_version = SB_ALLVRSNS;
+ }
+
+ if (s -> s_rdata = malloc ((unsigned) (s -> s_rlen = 1)))
+ *s -> s_rdata = reason & 0xff;
+
+ secs = ses_rf_timer;
+ }
+ else {
+ if ((s = newspkt (SPDU_AB)) == NULL)
+ return result;
+
+ s -> s_mask |= SMASK_SPDU_AB | SMASK_AB_DISC;
+ s -> s_ab_disconnect = AB_DISC_RELEASE;
+ switch (reason) {
+ case SC_PROTOCOL:
+ case SC_VERSION:
+ s -> s_ab_disconnect |= AB_DISC_PROTO;
+ break;
+
+ case SC_CONGEST:
+ case SC_SSAPID:
+ break;
+
+ default:
+ s -> s_ab_disconnect |= AB_DISC_UNKNOWN;
+ break;
+ }
+
+ secs = ses_ab_timer;
+ }
+
+ value = spkt2sd (s, sd,
+ (sb = findsblk (sd)) && (sb -> sb_flags & SB_EXPD), si);
+
+ freespkt (s);
+ if (value == NOTOK)
+ return result;
+
+ if (secs >= 0)
+ switch (TReadRequest (sd, tx, secs, td)) {
+ case OK:
+ default:
+ TXFREE (tx);
+ break;
+
+ case NOTOK:
+ break;
+ }
+
+ return result;
+}
+#else
+/* VARARGS5 */
+
+int spktlose (sd, si, reason, what, fmt)
+int sd,
+ reason;
+struct SSAPindication *si;
+char *what,
+ *fmt;
+{
+ return spktlose (sd, si, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef lint
+int ssaplose (va_alist)
+va_dcl
+{
+ int reason,
+ result;
+ struct SSAPindication *si;
+ va_list ap;
+
+ va_start (ap);
+
+ si = va_arg (ap, struct SSAPindication *);
+ reason = va_arg (ap, int);
+
+ result = _ssaplose (si, reason, ap);
+
+ va_end (ap);
+
+ return result;
+}
+#else
+/* VARARGS4 */
+
+int ssaplose (si, reason, what, fmt)
+struct SSAPindication *si;
+int reason;
+char *what,
+ *fmt;
+{
+ return ssaplose (si, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef lint
+static int _ssaplose (si, reason, ap) /* what, fmt, args ... */
+register struct SSAPindication *si;
+int reason;
+va_list ap;
+{
+ register char *bp;
+ char buffer[BUFSIZ];
+ register struct SSAPabort *sa;
+
+ if (si) {
+ bzero ((char *) si, sizeof *si);
+ si -> si_type = SI_ABORT;
+ sa = &si -> si_abort;
+
+ asprintf (bp = buffer, ap);
+ bp += strlen (bp);
+
+ sa -> sa_peer = 0;
+ sa -> sa_reason = reason;
+ copySSAPdata (buffer, bp - buffer, sa);
+ }
+
+ return NOTOK;
+}
+#endif
--- /dev/null
+/* ssapmajor1.c - SPM: initiate majorsyncs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapmajor1.c,v 7.1 91/02/22 09:45:51 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapmajor1.c,v 7.1 91/02/22 09:45:51 mrose Interim $
+ *
+ *
+ * $Log: ssapmajor1.c,v $
+ * Revision 7.1 91/02/22 09:45:51 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:30 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-MAJOR-SYNC.REQUEST */
+
+int SMajSyncRequest (sd, ssn, data, cc, si)
+int sd;
+long *ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (ssn);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SN_SIZE, "majorsync");
+
+ result = SMajSyncRequestAux (sb, ssn, data, cc, MAP_SYNC_NOEND, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+int SMajSyncRequestAux (sb, ssn, data, cc, opts, si)
+register struct ssapblk *sb;
+long *ssn;
+char *data;
+int cc,
+ opts;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (SDoActivityAux (sb, si, 0, 0) == NOTOK)
+ return NOTOK;
+
+ if ((sb -> sb_requirements & SR_ACTIVITY)
+ && !(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP, "no activity in progress");
+
+ if (sb -> sb_flags & SB_MAA)
+ return ssaplose (si, SC_OPERATION, "awaiting your majorsync response");
+
+ if ((result = SWriteRequestAux (sb, SPDU_MAP, data, cc, opts,
+ *ssn = sb -> sb_V_M, 0, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_flags |= SB_MAP;
+ if (opts & MAP_SYNC_NOEND) {
+ if (sb -> sb_requirements & SR_ACTIVITY)
+ sb -> sb_flags |= SB_Vnextact;
+ }
+ else
+ sb -> sb_flags |= SB_AE, sb -> sb_flags &= ~SB_Vnextact;
+ if (sb -> sb_flags & SB_Vsc) {
+ sb -> sb_V_A = sb -> sb_V_M;
+ sb -> sb_flags &= ~SB_Vsc;
+ }
+ sb -> sb_V_M++;
+ }
+
+ return result;
+}
--- /dev/null
+/* ssapmajor2.c - SPM: respond to majorsyncs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapmajor2.c,v 7.1 91/02/22 09:45:53 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapmajor2.c,v 7.1 91/02/22 09:45:53 mrose Interim $
+ *
+ *
+ * $Log: ssapmajor2.c,v $
+ * Revision 7.1 91/02/22 09:45:53 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:31 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-MAJOR-SYNC.RESPONSE */
+
+int SMajSyncResponse (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SN_SIZE, "majorsync");
+
+ result = SMajSyncResponseAux (sb, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+int SMajSyncResponseAux (sb, data, cc, si)
+register struct ssapblk *sb;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_MAJORSYNC)
+ && !(sb -> sb_requirements & SR_ACTIVITY)
+ && !(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "major synchronize service unavailable");
+ if (!(sb -> sb_flags & SB_MAA))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no majorsync in progress");
+
+ if ((result = SWriteRequestAux (sb, SPDU_MAA, data, cc, 0,
+ sb -> sb_V_M - 1, 0, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_V_A = sb -> sb_V_R = sb -> sb_V_M;
+ if (sb -> sb_requirements & SR_ACTIVITY)
+ if (sb -> sb_flags & SB_Vnextact)
+ sb -> sb_flags |= SB_Vact;
+ else
+ sb -> sb_flags &= ~SB_Vact;
+
+ sb -> sb_flags &= ~(SB_MAA | SB_AE);
+ }
+
+ return result;
+}
--- /dev/null
+/* ssapminor1.c - SPM: initiate minorsyncs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapminor1.c,v 7.1 91/02/22 09:45:54 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapminor1.c,v 7.1 91/02/22 09:45:54 mrose Interim $
+ *
+ *
+ * $Log: ssapminor1.c,v $
+ * Revision 7.1 91/02/22 09:45:54 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:32 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-MINOR-SYNC.REQUEST */
+
+int SMinSyncRequest (sd, type, ssn, data, cc, si)
+int sd;
+int type;
+long *ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ switch (type) {
+ case SYNC_CONFIRM:
+ case SYNC_NOCONFIRM:
+ break;
+
+ default:
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "improper choice of type setting");
+ }
+ missingP (ssn);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SN_SIZE, "minorsync");
+
+ result = SMinSyncRequestAux (sb, type, ssn, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SMinSyncRequestAux (sb, type, ssn, data, cc, si)
+register struct ssapblk *sb;
+int type;
+long *ssn;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_MINORSYNC))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "minor synchronize service unavailable");
+
+ if ((sb -> sb_requirements & SR_DAT_EXISTS)
+ && !(sb -> sb_owned & ST_DAT_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "data token not owned by you");
+
+ if (!(sb -> sb_owned & ST_MIN_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "minorsync token not owned by you");
+
+ if ((sb -> sb_requirements & SR_ACTIVITY)
+ && !(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP, "no activity in progress");
+
+ if (sb -> sb_flags & SB_MAA)
+ return ssaplose (si, SC_OPERATION, "awaiting your majorsync response");
+
+ if ((result = SWriteRequestAux (sb, SPDU_MIP, data, cc, type,
+ *ssn = sb -> sb_V_M, 0, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ if (sb -> sb_flags & SB_Vsc) {
+ sb -> sb_V_A = sb -> sb_V_M;
+ sb -> sb_flags &= ~SB_Vsc;
+ }
+ sb -> sb_V_M++;
+ }
+
+ return result;
+}
--- /dev/null
+/* ssapminor2.c - SPM: respond to minorsyncs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapminor2.c,v 7.1 91/02/22 09:45:55 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapminor2.c,v 7.1 91/02/22 09:45:55 mrose Interim $
+ *
+ *
+ * $Log: ssapminor2.c,v $
+ * Revision 7.1 91/02/22 09:45:55 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:33 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-MINOR-SYNC.RESPONSE */
+
+int SMinSyncResponse (sd, ssn, data, cc, si)
+int sd;
+long ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ if (SERIAL_MIN > ssn || ssn > SERIAL_MAX)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid serial number");
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SN_SIZE, "minorsync");
+
+ result = SMinSyncResponseAux (sb, ssn, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SMinSyncResponseAux (sb, ssn, data, cc, si)
+register struct ssapblk *sb;
+long ssn;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_MINORSYNC))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "minor synchronize service unavailable");
+ if (!(sb -> sb_flags & SB_Vsc))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no minorsync in progress");
+ if (ssn < sb -> sb_V_A)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "bad choice for minor ssn, should be >= %ld", sb -> sb_V_A);
+
+ if ((result = SWriteRequestAux (sb, SPDU_MIA, data, cc, 0, ssn, 0, NULLSD,
+ NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else
+ sb -> sb_V_A = ssn + 1;
+
+ return result;
+}
--- /dev/null
+/* ssaprelease1.c - SPM: initiate release */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprelease1.c,v 7.1 91/02/22 09:45:56 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaprelease1.c,v 7.1 91/02/22 09:45:56 mrose Interim $
+ *
+ *
+ * $Log: ssaprelease1.c,v $
+ * Revision 7.1 91/02/22 09:45:56 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:34 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-RELEASE.REQUEST */
+
+int SRelRequest (sd, data, cc, secs, sr, si)
+int sd;
+char *data;
+int cc;
+int secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (sr);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SF_SIZE, "release");
+
+ result = SRelRequestAux (sb, data, cc, secs, sr, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if ((sb -> sb_requirements & requires) && !(sb -> sb_owned & bit)) \
+ return ssaplose (si, SC_OPERATION, NULLCP, \
+ "%s token not owned by you", type); \
+}
+
+
+static int SRelRequestAux (sb, data, cc, secs, sr, si)
+register struct ssapblk *sb;
+char *data;
+int cc;
+int secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+ register struct ssapkt *s;
+
+ dotokens ();
+
+ if (sb -> sb_flags & SB_CD)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "capability data request in progress");
+ if (sb -> sb_flags & SB_CDA)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "awaiting your capability data response");
+ if (sb -> sb_flags & SB_GTC)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "give control request in progress");
+ if (sb -> sb_flags & SB_MAA)
+ return ssaplose (si, SC_OPERATION, "awaiting your majorsync response");
+ if (sb -> sb_flags & SB_RELEASE)
+ return ssaplose (si, SC_OPERATION, "release already in progress");
+
+ if (sb -> sb_xspdu || sb -> sb_spdu)
+ return ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+
+ if ((s = newspkt (SPDU_FN)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ if (cc > 0) {
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ sb -> sb_retry = s;
+
+ return SRelRetryRequestAux (sb, secs, sr, si);
+}
+
+#undef dotoken
+
+/* \f S-RELEASE-RETRY.REQUEST (pseudo) */
+
+int SRelRetryRequest (sd, secs, sr, si)
+int sd;
+int secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (sr);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ if ((sb = findsblk (sd)) == NULL)
+ result = ssaplose (si, SC_PARAMETER, NULLCP,
+ "invalid session descriptor");
+ else
+ if (!(sb -> sb_flags & SB_RELEASE))
+ result = ssaplose (si, SC_OPERATION, "release not in progress");
+ else
+ result = SRelRetryRequestAux (sb, secs, sr, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SRelRetryRequestAux (sb, secs, sr, si)
+register struct ssapblk *sb;
+int secs;
+struct SSAPrelease *sr;
+struct SSAPindication *si;
+{
+ int code,
+ result;
+ register struct ssapkt *s;
+
+ if (sb -> sb_flags & SB_RELEASE)
+ goto waiting;
+
+ code = SPDU_FN;
+
+again: ;
+ if (((s = sb -> sb_retry) -> s_code = code) == SPDU_FN) {
+ s -> s_mask |= SMASK_FN_DISC;
+ s -> s_fn_disconnect = FN_DISC_RELEASE;
+ }
+
+ result = spkt2sd (s, sb -> sb_fd, 0, si);
+
+ if (s -> s_code == SPDU_FN) {
+ s -> s_mask &= ~(SMASK_UDATA_PGI | SMASK_FN_DISC);
+ s -> s_udata = NULL, s -> s_ulen = 0;
+ s -> s_fn_disconnect = 0;
+ }
+
+ if (result == NOTOK)
+ goto out1;
+
+waiting: ;
+ if ((s = sb2spkt (sb, si, secs, NULLTX)) == NULL) {
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if (sa -> sa_reason == SC_TIMER) {
+ sb -> sb_flags |= SB_RELEASE;
+
+ return NOTOK;
+ }
+
+ goto out2;
+ }
+
+ bzero ((char *) sr, sizeof *sr);
+ switch (s -> s_code) {
+ case SPDU_FN:
+ freespkt (s);
+ code = SPDU_DN;
+ goto again;
+
+ case SPDU_DN:
+ sr -> sr_affirmative = 1;
+ copySPKTdata (s, sr);
+ freespkt (s);
+ freesblk (sb);
+ return OK;
+
+ case SPDU_NF:
+ if (!(sb -> sb_requirements & SR_RLS_EXISTS)
+ || !(sb -> sb_owned & ST_RLS_TOKEN))
+ goto bad_nf;
+ sr -> sr_affirmative = 0;
+ copySPKTdata (s, sr);
+ freespkt (s);
+ return OK;
+
+ case SPDU_RS:
+ if (sb -> sb_spdu) /* XXX */
+ freespkt (sb -> sb_spdu);
+ sb -> sb_spdu = s;
+ return ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+
+ case SPDU_AB:
+ si -> si_type = SI_ABORT;
+ {
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
+ ? 1 : 0))
+ sa -> sa_reason = SC_ABORT;
+ sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
+ sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
+ }
+ break;
+
+ default:
+bad_nf: ;
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: not expecting 0x%x",
+ s -> s_code);
+ break;
+ }
+
+out2: ;
+ freespkt (s);
+out1: ;
+ freesblk (sb);
+
+ return NOTOK;
+}
--- /dev/null
+/* ssaprelease2.c - SPM: respond to release */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprelease2.c,v 7.1 91/02/22 09:45:57 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaprelease2.c,v 7.1 91/02/22 09:45:57 mrose Interim $
+ *
+ *
+ * $Log: ssaprelease2.c,v $
+ * Revision 7.1 91/02/22 09:45:57 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:36 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-RELEASE.RESPONSE */
+
+int SRelResponse (sd, status, data, cc, si)
+int sd;
+int status,
+ cc;
+char *data;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapFsig (sb, sd);
+ toomuchP (sb, data, cc, SR_SIZE, "release");
+
+ result = SRelResponseAux (sb, status, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f S-RELEASE.RESPONSE */
+
+static int SRelResponseAux (sb, status, data, cc, si)
+register struct ssapblk *sb;
+int status,
+ cc;
+char *data;
+struct SSAPindication *si;
+{
+ int code,
+ result;
+ register struct ssapkt *s;
+
+ switch (status) {
+ case SC_ACCEPT:
+ code = SPDU_DN;
+ break;
+
+ case SC_REJECTED:
+ if (!(sb -> sb_requirements & SR_NEGOTIATED))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "negotiated release service unavailable");
+ if (!(sb -> sb_requirements & SR_RLS_EXISTS))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "release token unavailable");
+ if (sb -> sb_owned & ST_RLS_TOKEN)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "release token owned by you");
+
+ code = SPDU_NF;
+ break;
+
+ default:
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "invalid value for status parameter");
+ }
+
+ if ((s = newspkt (code)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+ if (cc > 0) {
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+ result = spkt2sd (s, sb -> sb_fd, 0, si);
+ s -> s_mask &= ~SMASK_UDATA_PGI;
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ freespkt (s);
+ if (result == NOTOK || code == SPDU_DN)
+ freesblk (sb);
+ else
+ sb -> sb_flags &= ~SB_FINN;
+
+ return result;
+}
--- /dev/null
+/* ssapreport.c - SPM: exception reports */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapreport.c,v 7.1 91/02/22 09:45:58 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapreport.c,v 7.1 91/02/22 09:45:58 mrose Interim $
+ *
+ *
+ * $Log: ssapreport.c,v $
+ * Revision 7.1 91/02/22 09:45:58 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:37 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-U-EXCEPTION-REPORT.REQUEST */
+
+int SUReportRequest (sd, reason, data, cc, si)
+int sd;
+int reason;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ if (!(SP_OK (reason)))
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid reason");
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, SP_SIZE, "report");
+
+ result = SUReportRequestAux (sb, reason, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SUReportRequestAux (sb, reason, data, cc, si)
+register struct ssapblk *sb;
+int reason;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_EXCEPTIONS))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "exceptions service unavailable");
+ if (!(sb -> sb_requirements & SR_DAT_EXISTS))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "data token not available");
+ if (sb -> sb_owned & ST_DAT_TOKEN)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "data token owned by you");
+ if ((sb -> sb_requirements & SR_ACTIVITY)
+ && !(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no activity in progress");
+
+ if ((result = SWriteRequestAux (sb, SPDU_ED, data, cc, reason, 0L, 0,
+ NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else
+ sb -> sb_flags |= SB_ED;
+
+ return result;
+}
--- /dev/null
+/* ssaprespond.c - SPM: responder */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprespond.c,v 7.3 91/02/22 09:45:59 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaprespond.c,v 7.3 91/02/22 09:45:59 mrose Interim $
+ *
+ *
+ * $Log: ssaprespond.c,v $
+ * Revision 7.3 91/02/22 09:45:59 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/11/21 11:31:45 mrose
+ * sun
+ *
+ * Revision 7.1 89/11/27 10:30:46 mrose
+ * sync
+ *
+ * Revision 7.0 89/11/23 22:25:38 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f S-CONNECT.INDICATION */
+
+int SInit (vecp, vec, ss, si)
+int vecp;
+char **vec;
+struct SSAPstart *ss;
+struct SSAPindication *si;
+{
+ int len;
+ register struct ssapblk *sb;
+ register struct ssapkt *s;
+ struct TSAPstart tss;
+ register struct TSAPstart *ts = &tss;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ isodetailor (NULLCP, 0);
+
+ if (vecp < 2)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "bad initialization vector");
+ missingP (vec);
+ missingP (ss);
+ missingP (si);
+
+ if ((sb = newsblk ()) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+ if (vecp == 2 || TInit (vecp, vec, ts, td) != NOTOK) {
+ int sd;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+
+ if (vecp == 2) {
+ if (TRestoreState (vec[1], ts, td) == NOTOK) {
+ (void) ts2sslose (si, "TRestoreState", td);
+ (void) ssaplose (si, SC_PARAMETER, NULLCP,
+ "bad initialization vector");
+ goto out1;
+ }
+ bzero (vec[0], strlen (vec[0]));
+ bzero (vec[1], strlen (vec[1]));
+ *vec = NULL;
+ }
+ else {
+ if (TConnResponse (ts -> ts_sd, &ts -> ts_called,
+ ts -> ts_expedited, NULLCP, 0, NULLQOS, td) == NOTOK) {
+ (void) ts2sslose (si, "TConnResponse", td);
+ (void) TDiscRequest (ts -> ts_sd, NULLCP, 0, td);
+ goto out1;
+ }
+ }
+ sd = ts -> ts_sd;
+
+ if (TReadRequest (sb -> sb_fd = sd, tx, NOTOK, td) == NOTOK) {
+ (void) ts2sslose (si, "TReadRequest", td);
+ goto out1;
+ }
+
+ s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, NULLIP);
+ TXFREE (tx);
+
+ if (s == NULL || s -> s_errno != SC_ACCEPT) {
+ (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST)
+ | SC_REFUSE, NULLCP, NULLCP);
+ goto out2;
+ }
+
+ if (s -> s_code != SPDU_CN) {
+ (void) spktlose (sd, si, (s ? s -> s_errno : SC_CONGEST)
+ | SC_REFUSE, NULLCP,
+ "session protocol mangled: expected 0x%x, got 0x%x",
+ SPDU_CN, s -> s_code);
+ goto out2;
+ }
+
+ if (s -> s_mask & SMASK_CN_VRSN
+ && !(s -> s_cn_version & SB_ALLVRSNS)) {
+ (void) spktlose (sd, si, SC_VERSION | SC_REFUSE, NULLCP,
+ "version mismatch: expecting something in 0x%x, got 0x%x",
+ SB_ALLVRSNS, s -> s_cn_version);
+ goto out2;
+ }
+ }
+ else {
+ int reason;
+
+ vec += vecp - 2;
+ s = NULL;
+ if ((reason = td -> td_reason) != DR_PARAMETER
+ || TRestoreState (vec[0], ts, td) == NOTOK
+ || (s = str2spkt (vec[1])) == NULL
+ || s -> s_errno != SC_ACCEPT) {
+ if (s)
+ freespkt (s);
+ else
+ (void) ts2sslose (si, reason != DR_PARAMETER ? "TInit"
+ : "TRestoreState", td);
+ (void) ssaplose (si, SC_PARAMETER, NULLCP,
+ "bad initialization vector");
+ goto out1;
+ }
+ bzero (vec[0], strlen (vec[0]));
+ bzero (vec[1], strlen (vec[1]));
+ *vec = NULL;
+ }
+
+ sb -> sb_fd = ts -> ts_sd;
+ sb -> sb_version =
+ (s -> s_mask & SMASK_CN_VRSN)
+ ? ((s -> s_cn_version & (1 << SB_VRSN2))
+ ? SB_VRSN2 : SB_VRSN1)
+ : s -> s_ulen > SS_SIZE
+ ? SB_VRSN2 : SB_VRSN1;
+ if (ts -> ts_expedited)
+ sb -> sb_flags |= SB_EXPD;
+
+ bzero ((char *) ss, sizeof *ss);
+ ss -> ss_sd = sb -> sb_fd;
+ if (s -> s_mask & SMASK_CN_REF)
+ ss -> ss_connect = s -> s_cn_reference; /* struct copy */
+ if (s -> s_mask & SMASK_CN_OPT)
+ sb -> sb_options = s -> s_options;
+ if (s -> s_mask & SMASK_CN_ISN)
+ ss -> ss_isn = sb -> sb_V_A = sb -> sb_V_M = s -> s_isn;
+ else
+ ss -> ss_isn = SERIAL_NONE;
+ if (!(s -> s_mask & SMASK_CN_TSDU))
+ s -> s_tsdu_init = s -> s_tsdu_resp = 0;
+ if (s -> s_tsdu_init
+ < (sb -> sb_tsdu_them = GET_TSDU_SIZE (ts -> ts_tsdusize)))
+ sb -> sb_tsdu_them = s -> s_tsdu_init;
+ if (s -> s_tsdu_resp
+ < (sb -> sb_tsdu_us = GET_TSDU_SIZE (ts -> ts_tsdusize)))
+ sb -> sb_tsdu_us = s -> s_tsdu_resp;
+ if (sb -> sb_version >= SB_VRSN2) /* XXX */
+ sb -> sb_tsdu_them = sb -> sb_tsdu_us = 0;
+
+ if (s -> s_mask & SMASK_CN_SET)
+ sb -> sb_settings = ss -> ss_settings = s -> s_settings;
+ sb -> sb_requirements = (s -> s_mask & SMASK_CN_REQ ? s -> s_cn_require
+ : SR_DEFAULT) & SR_MYREQUIRE;
+ if (!ts -> ts_expedited)
+ sb -> sb_requirements &= ~SR_EXPEDITED;
+ if (!(sb -> sb_requirements & SR_HALFDUPLEX))
+ sb -> sb_requirements &= ~SR_EXCEPTIONS;
+ ss -> ss_requirements = sb -> sb_requirements;
+ ss -> ss_calling.sa_addr = ts -> ts_calling; /* struct copy */
+ if (s -> s_mask & SMASK_CN_CALLING) {
+ if ((len = s -> s_callinglen)
+ > sizeof ss -> ss_calling.sa_selector)
+ len = sizeof ss -> ss_calling.sa_selector;
+ bcopy (s -> s_calling, ss -> ss_calling.sa_selector,
+ ss -> ss_calling.sa_selectlen = len);
+ }
+ sb -> sb_initiating = ss -> ss_calling; /* struct copy */
+ ss -> ss_called.sa_addr = ts -> ts_called; /* struct copy */
+ if (s -> s_mask & SMASK_CN_CALLED) {
+ if ((len = s -> s_calledlen)
+ > sizeof ss -> ss_called.sa_selector)
+ len = sizeof ss -> ss_called.sa_selector;
+ bcopy (s -> s_called, ss -> ss_called.sa_selector,
+ ss -> ss_called.sa_selectlen = len);
+ }
+ sb -> sb_responding = ss -> ss_called; /* struct copy */
+ if ((ss -> ss_ssdusize = sb -> sb_tsdu_us - SSDU_MAGIC) < 0)
+ ss -> ss_ssdusize = ts -> ts_tsdusize - SSDU_MAGIC;
+ ss -> ss_qos = ts -> ts_qos; /* struct copy */
+ ss -> ss_qos.qos_sversion = sb -> sb_version + 1;
+ ss -> ss_qos.qos_extended = (sb -> sb_flags & SB_EXPD) ? 1 : 0;
+ copySPKTdata (s, ss);
+
+ freespkt (s);
+
+ return OK;
+
+out2: ;
+ freespkt(s);
+
+out1: ;
+ freesblk (sb);
+
+ return NOTOK;
+}
+
+/* \f S-CONNECT.RESPONSE */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ switch (sb -> sb_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ switch (settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE << shift: \
+ settings &= ~(ST_MASK << shift); \
+ settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ settings &= ~(ST_MASK << shift); \
+ settings |= ST_RESP_VALUE << shift; \
+ sb -> sb_owned |= bit; \
+ break; \
+ \
+ default: \
+ return ssaplose (si, SC_PARAMETER, NULLCP, \
+ "improper choice of %s token setting", type); \
+ } \
+ break; \
+ \
+ case ST_INIT_VALUE << shift: \
+ if ((settings & (ST_MASK << shift)) == (ST_RSVD_VALUE << shift)) \
+ please |= bit; \
+ settings &= ~(ST_MASK << shift); \
+ settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ settings &= ~(ST_MASK << shift); \
+ settings |= ST_RESP_VALUE << shift; \
+ sb -> sb_owned |= bit; \
+ break; \
+ } \
+}
+
+/* \f */
+
+int SConnResponse (sd, ref, responding, status, requirements, settings,
+ isn, data, cc, si)
+int sd;
+struct SSAPref *ref;
+struct SSAPaddr *responding;
+int status,
+ requirements,
+ settings,
+ cc;
+long isn;
+char *data;
+struct SSAPindication *si;
+{
+ int result,
+ please;
+ register struct ssapkt *s;
+ register struct ssapblk *sb;
+
+ if ((sb = findsblk (sd)) == NULL || (sb -> sb_flags & SB_CONN))
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
+ missingP (ref);
+ refmuchP (ref);
+ if (ref -> sr_vlen)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "bad format for reference");
+#ifdef notdef
+ missingP (responding);
+#endif
+ if (responding)
+ sb -> sb_responding = *responding; /* struct copy */
+ switch (status) {
+ case SC_ACCEPT:
+ if (requirements & ~SR_MYREQUIRE)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "requirements settings not supported");
+#ifdef notdef /* screwy session protocol... */
+ if (requirements & ~sb -> sb_requirements)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "requirements settings not available");
+#endif
+ if ((requirements & SR_HALFDUPLEX) && (requirements & SR_DUPLEX))
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "half-duplex and duplex services are incompatible");
+ if ((requirements & SR_EXCEPTIONS)
+ && !(requirements & SR_HALFDUPLEX))
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "exception service requires half-duplex service");
+ sb -> sb_requirements &= requirements;
+ sb -> sb_owned = 0, please = 0;
+ dotokens ();
+ if (sb -> sb_requirements
+ & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)) {
+ if (!(sb -> sb_requirements & SR_ACTIVITY)
+ || isn != SERIAL_NONE)
+ if (SERIAL_MIN > isn || isn > SERIAL_MAX + 1)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "bad choice for initial serial number");
+ }
+ else
+ if (isn != SERIAL_NONE)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "initial serial number invalid given requirements");
+ break;
+
+ case SC_NOTSPECIFIED:
+ case SC_CONGESTION:
+ case SC_REJECTED:
+ break;
+
+ default:
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid result");
+ }
+ if (data == NULL)
+ cc = 0;
+ else
+ if (cc > (sb -> sb_version < SB_VRSN2 ? SC_SIZE : ENCLOSE_MAX))
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "too much initial user data, %d octets", cc);
+ missingP (si);
+
+ if (status != SC_ACCEPT) {
+ if ((s = newspkt (SPDU_RF)) == NULL) {
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out1;
+ }
+
+ s -> s_mask |= SMASK_RF_REF;
+ s -> s_rf_reference = *ref; /* struct copy */
+ if (status == SC_REJECTED) {
+ s -> s_mask |= SMASK_RF_REQ;
+ s -> s_rf_require = requirements;
+ }
+ if ((s -> s_rdata = malloc ((unsigned) (s -> s_rlen = 1 + cc)))
+ == NULL) {
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out2;
+ }
+ *s -> s_rdata = status & 0xff;
+ if (cc > 0)
+ bcopy (data, s -> s_rdata + 1, cc);
+ result = refuse (sb, s, si);
+ freesblk (sb);
+
+ return (result != NOTOK && status != SC_ACCEPT ? OK : NOTOK);
+ }
+
+ if ((s = newspkt (SPDU_AC)) == NULL) {
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out1;
+ }
+
+ s -> s_mask |= SMASK_CN_REF | SMASK_CN_OPT | SMASK_CN_VRSN;
+ s -> s_cn_reference = *ref; /* struct copy */
+ s -> s_options = CR_OPT_NULL;
+ s -> s_cn_version = 1 << sb -> sb_version;
+
+ if (isn != SERIAL_NONE) {
+ s -> s_mask |= SMASK_CN_ISN;
+ s -> s_isn = isn;
+ }
+
+ if (sb -> sb_tsdu_us || sb -> sb_tsdu_them) {
+ s -> s_mask |= SMASK_CN_TSDU;
+ s -> s_tsdu_resp = GET_TSDU_SIZE (sb -> sb_tsdu_us);
+ s -> s_tsdu_init = GET_TSDU_SIZE (sb -> sb_tsdu_them);
+ }
+
+ s -> s_mask |= SMASK_CN_REQ;
+ if ((s -> s_cn_require = sb -> sb_requirements) & SR_TOKENS) {
+ s -> s_mask |= SMASK_CN_SET;
+ s -> s_settings = settings;
+ }
+ if (please) {
+ s -> s_mask |= SMASK_AC_TOKEN;
+ s -> s_ac_token = please;
+ }
+ if (responding) {
+ s -> s_mask |= SMASK_CN_CALLED;
+ bcopy (sb -> sb_responding.sa_selector, s -> s_called,
+ s -> s_calledlen = sb -> sb_responding.sa_selectlen);
+ }
+
+ if (cc > 0) {
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+ if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+ freesblk (sb);
+ else
+ sb -> sb_flags |= SB_CONN;
+ s -> s_mask &= ~SMASK_UDATA_PGI;
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ freespkt(s);
+
+ return result;
+
+out2: ;
+ freespkt (s);
+out1: ;
+ freesblk (sb);
+
+ return NOTOK;
+}
+
+#undef dotoken
+
+/* \f */
+
+static int refuse (sb, s, si)
+register struct ssapblk *sb;
+register struct ssapkt *s;
+register struct SSAPindication *si;
+{
+ int result;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ s -> s_mask |= SMASK_RF_DISC;
+ s -> s_rf_disconnect |= RF_DISC_RELEASE;
+
+ result = spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD ? 1 : 0, si);
+
+ freespkt (s);
+ if (result == NOTOK)
+ return NOTOK;
+
+ if (ses_rf_timer >= 0)
+ switch (TReadRequest (sb -> sb_fd, tx, ses_rf_timer, td)) {
+ case OK:
+ default: /* what could this be? */
+ TXFREE (tx);
+ break;
+
+ case NOTOK:
+ sb -> sb_fd = NOTOK;
+ break;
+ }
+
+ return OK;
+}
--- /dev/null
+/* ssapresync.c - SPM: initiate resyncs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapresync1.c,v 7.1 91/02/22 09:46:01 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapresync1.c,v 7.1 91/02/22 09:46:01 mrose Interim $
+ *
+ *
+ * $Log: ssapresync1.c,v $
+ * Revision 7.1 91/02/22 09:46:01 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:41 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-RESYNCHRONIZE.REQUEST */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ switch (settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE << shift: \
+ case ST_RESP_VALUE << shift: \
+ case ST_CALL_VALUE << shift: \
+ break; \
+ \
+ default: \
+ return ssaplose (si, SC_PARAMETER, NULLCP, \
+ "improper choice of %s token setting",type); \
+ } \
+}
+
+/* \f */
+
+int SReSyncRequest (sd, type, ssn, settings, data, cc, si)
+int sd;
+int type,
+ settings;
+long ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ switch (type) {
+ case SYNC_RESTART:
+ break;
+
+ case SYNC_ABANDON:
+ if (ssn != SERIAL_NONE)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "serial number inappropriate");
+ break;
+
+ case SYNC_SET:
+ if (SERIAL_MIN > ssn || ssn > SERIAL_MAX + 1)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "invalid serial number");
+ break;
+
+ default:
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "improper choice of type setting");
+ }
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapRsig (sb, sd);
+ toomuchP (sb, data, cc, SN_SIZE, "resync");
+
+ result = SReSyncRequestAux (sb, type, ssn, settings, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SReSyncRequestAux (sb, type, ssn, settings, data, cc, si)
+register struct ssapblk *sb;
+int type,
+ settings;
+long ssn;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_RESYNC))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "resynchronize service unavailable");
+
+ if ((sb -> sb_requirements & SR_ACTIVITY)
+ && !(sb -> sb_flags & SB_Vact))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no activity in progress");
+
+ if ((sb -> sb_flags & SB_RA)
+ && SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0, type, ssn,
+ sb -> sb_rs, sb -> sb_rsn) == NOTOK)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "resync in progress takes precedence");
+
+ switch (type) {
+ case SYNC_RESTART:
+ if (sb -> sb_V_M < ssn || ssn < sb -> sb_V_R)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "bad choice for resync ssn, should be in [%d..%d]",
+ sb -> sb_V_R, sb -> sb_V_M);
+ break;
+
+ case SYNC_ABANDON:
+ ssn = sb -> sb_V_M;
+ break;
+
+ case SYNC_SET:
+ break;
+ }
+
+ dotokens ();
+
+ if ((result = SWriteRequestAux (sb, SPDU_RS, data, cc, type, ssn,
+ settings, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_flags |= SB_RS, sb -> sb_flags &= ~(SB_RA | SB_EDACK | SB_ERACK);
+ sb -> sb_rs = type;
+ sb -> sb_rsn = ssn;
+ sb -> sb_rsettings = sb -> sb_requirements & SR_TOKENS ? settings : 0;
+ }
+
+ return result;
+}
+
+#undef dotoken
--- /dev/null
+/* ssapresync2.c - SPM: respond to resyncs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapresync2.c,v 7.1 91/02/22 09:46:02 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapresync2.c,v 7.1 91/02/22 09:46:02 mrose Interim $
+ *
+ *
+ * $Log: ssapresync2.c,v $
+ * Revision 7.1 91/02/22 09:46:02 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:42 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-RESYNCHRONIZE.RESPONSE */
+
+int SReSyncResponse (sd, ssn, settings, data, cc, si)
+int sd;
+int settings;
+long ssn;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapRsig (sb, sd);
+ toomuchP (sb, data, cc, SN_SIZE, "resync");
+
+ result = SReSyncResponseAux (sb, ssn, settings, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SReSyncResponseAux (sb, ssn, settings, data, cc, si)
+register struct ssapblk *sb;
+long ssn;
+int settings;
+char *data;
+int cc;
+register struct SSAPindication *si;
+{
+ int result;
+
+ if (!(sb -> sb_requirements & SR_RESYNC))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "resynchronize service unavailable");
+ if (!(sb -> sb_flags & SB_RA))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "no resync in progress");
+
+ switch (sb -> sb_rs) {
+ case SYNC_RESTART:
+ ssn = sb -> sb_rsn;
+ break;
+
+ case SYNC_ABANDON:
+ ssn = sb -> sb_V_A;
+ break;
+
+ case SYNC_SET:
+ break;
+ }
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ switch (sb -> sb_rsettings & (ST_MASK << shift)) { \
+ dotoken1 (requires,shift,bit,type); \
+ \
+ dotoken2 (requires,shift,bit,type); \
+ } \
+}
+#define dotoken1(requires,shift,bit,type) \
+ case ST_CALL_VALUE << shift: \
+ switch (settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE << shift: \
+ settings &= ~(ST_MASK << shift); \
+ settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ settings &= ~(ST_MASK << shift); \
+ settings |= ST_RESP_VALUE << shift; \
+ break; \
+ \
+ default: \
+ return ssaplose (si, SC_PARAMETER, NULLCP, \
+ "improper choice of %s token setting", type); \
+ } \
+ break;
+#define dotoken2(requires,shift,bit,type) \
+ default: \
+ if ((sb -> sb_rsettings & (ST_MASK << shift)) \
+ != (settings & (ST_MASK << shift))) \
+ return ssaplose (si, SC_OPERATION, NULLCP, \
+ "setting of %s token is not your choice"); \
+ break;
+ dotokens ();
+#undef dotoken
+#undef dotoken1
+#undef dotoken2
+
+ if ((result = SWriteRequestAux (sb, SPDU_RA, data, cc, 0, ssn,
+ settings, NULLSD, NULLSD, NULLSR, si)) == NOTOK)
+ freesblk (sb);
+ else {
+ sb -> sb_flags &= ~SB_RA;
+ sb -> sb_V_A = sb -> sb_V_M = ssn;
+ if (sb -> sb_rs != SYNC_RESTART)
+ sb -> sb_V_R = 0;
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ switch (settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE << shift: \
+ if (sb -> sb_flags & SB_INIT) \
+ sb -> sb_owned |= bit; \
+ else \
+ sb -> sb_owned &= ~bit; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ if (!(sb -> sb_flags & SB_INIT)) \
+ sb -> sb_owned |= bit; \
+ else \
+ sb -> sb_owned &= ~bit; \
+ break; \
+ } \
+}
+ dotokens ();
+#undef dotoken
+ }
+
+ return result;
+}
--- /dev/null
+/* ssaprovider.c - implement the session protocol */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaprovider.c,v 7.5 91/02/22 09:46:03 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaprovider.c,v 7.5 91/02/22 09:46:03 mrose Interim $
+ *
+ *
+ * $Log: ssaprovider.c,v $
+ * Revision 7.5 91/02/22 09:46:03 mrose
+ * Interim 6.8
+ *
+ * Revision 7.4 91/01/10 04:11:29 mrose
+ * foo
+ *
+ * Revision 7.3 90/11/21 11:31:47 mrose
+ * sun
+ *
+ * Revision 7.2 90/08/08 14:14:02 mrose
+ * update
+ *
+ * Revision 7.1 89/11/30 23:51:19 mrose
+ * touch-up
+ *
+ * Revision 7.0 89/11/23 22:25:45 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f DATA */
+
+static int once_only = 0;
+static struct ssapblk ssapque;
+static struct ssapblk *SHead = &ssapque;
+
+
+int TDATAser (), TDISCser ();
+
+
+/* \f S-DATA.REQUEST */
+
+int SDataRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ return SSendRequest (sd, data, cc, 1, 1, si);
+}
+
+
+int SSendRequest (sd, data, cc, begin, end, si)
+int sd;
+char *data;
+int cc,
+ begin,
+ end;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ struct udvec uvs[2];
+ register struct udvec *uv = uvs;
+ register struct ssapblk *sb;
+
+ missingP (data);
+ if (cc <= 0)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "illegal value for SSDU length (%d)", cc);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+
+ uv -> uv_base = data, uv -> uv_len = cc, uv++;
+ uv -> uv_base = NULL;
+
+ result = SDataRequestAux (sb, SPDU_DT, uvs, begin, end, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f S-WRITE.REQUEST (pseudo; write user data vectors) */
+
+int SWriteRequest (sd, typed, uv, si)
+int sd;
+int typed;
+struct udvec *uv;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (uv);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+
+ result = SDataRequestAux (sb, typed ? SPDU_TD : SPDU_DT, uv, 1, 1, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+#define NSPUV 12 /* really should be MSG_MAXIOVLEN - 4 */
+
+
+int SDataRequestAux (sb, code, uv, begin, end, si)
+register struct ssapblk *sb;
+int code;
+register struct udvec *uv;
+int begin,
+ end;
+struct SSAPindication *si;
+{
+ int cc,
+ j,
+ len,
+ n,
+ result;
+ register char *bp,
+ *ep;
+ register struct ssapkt *s;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+ struct udvec vvs[NSPUV];
+ register struct udvec *vv,
+ *wv;
+ struct udvec *xv;
+
+ switch (code) {
+ case SPDU_DT:
+ if ((sb -> sb_requirements & SR_DAT_EXISTS)
+ && !(sb -> sb_owned & ST_DAT_TOKEN))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "data token not owned by you");
+ break;
+
+ case SPDU_TD:
+ if (!(sb -> sb_requirements & SR_TYPEDATA))
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "typed data service unavailable");
+ break;
+ }
+
+ n = 0;
+ for (vv = uv; vv -> uv_base; vv++)
+ n += vv -> uv_len;
+ if (n == 0)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "zero-length SSDU");
+
+ ep = (bp = uv -> uv_base) + (cc = uv -> uv_len);
+ while (uv -> uv_base) {
+ len = sb -> sb_tsdu_us ? min (n, sb -> sb_tsdu_us - SSDU_MAGIC) : n;
+ vv = vvs;
+ vvs[0].uv_base = vvs[1].uv_base = NULL;
+ vvs[1].uv_inline = 0;
+
+ if (code == SPDU_DT) {
+ if ((s = newspkt (SPDU_GT)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ s -> s_mask |= SMASK_SPDU_GT;
+
+ if (spkt2tsdu (s, &vv -> uv_base, &vv -> uv_len) == NOTOK) {
+ (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+ goto out1;
+ }
+ freespkt (s);
+ s = NULL;
+ vv++;
+ }
+
+ xv = vv++;
+
+ wv = vvs + NSPUV - 1;
+ for (; len > 0 && vv < wv; len -= j) {
+ j = min (cc, len);
+ vv -> uv_base = bp, vv -> uv_len = j, vv -> uv_inline = 1, vv++;
+ bp += j, cc -= j, n -= j;
+
+ if (bp >= ep) {
+ if ((bp = (++uv) -> uv_base) == NULL)
+ break;
+ ep = bp + (cc = uv -> uv_len);
+ }
+ }
+ if (!sb -> sb_tsdu_us && uv -> uv_base) {
+ (void) ssaplose (si, SC_PARAMETER, NULLCP,
+ "too many vector entries in SDU");
+ goto out2;
+ }
+ vv -> uv_base = NULL;
+
+ vv = xv;
+ if ((s = newspkt (code)) == NULL) {
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out2;
+ }
+ if (sb -> sb_tsdu_us) {
+ s -> s_mask |= SMASK_ENCLOSE;
+ if (begin) {
+ s -> s_enclose |= ENCL_BEGIN;
+ begin = 0;
+ }
+ if (end && uv -> uv_base == NULL)
+ s -> s_enclose |= ENCL_END;
+ }
+ if (spkt2tsdu (s, &vv -> uv_base, &vv -> uv_len) == NOTOK) {
+ (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+ goto out3;
+ }
+ freespkt (s);
+ s = NULL;
+
+ if ((result = TWriteRequest (sb -> sb_fd, vvs, td)) == NOTOK)
+ (void) ts2sslose (si, "TWriteRequest", td);
+
+ free (vvs[0].uv_base);
+ if (code == SPDU_DT)
+ free (vvs[1].uv_base);
+
+ if (result == NOTOK)
+ return NOTOK;
+ }
+ return OK;
+
+out3: ;
+ if (vvs[1].uv_base && !vvs[1].uv_inline)
+ free (vvs[1].uv_base);
+out2: ;
+ if (vvs[0].uv_base)
+ free (vvs[0].uv_base);
+out1: ;
+ freespkt (s);
+
+ return NOTOK;
+}
+
+/* \f S-READ.REQUEST (pseudo; synchronous read) */
+
+int SReadRequest (sd, sx, secs, si)
+int sd;
+struct SSAPdata *sx;
+int secs;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (sx);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ if ((sb = findsblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_PARAMETER, NULLCP, "invalid session descriptor");
+ }
+ if (!(sb -> sb_flags & SB_CONN)) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "session descriptor not connected");
+ }
+ if (sb -> sb_flags & SB_FINN) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "session descriptor finishing");
+ }
+
+ result = SReadRequestAux (sb, sx, secs, si, 0, NULLTX);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SReadRequestAux (sb, sx, secs, si, async, tx)
+register struct ssapblk *sb;
+register struct SSAPdata *sx;
+int secs;
+struct SSAPindication *si;
+int async;
+struct TSAPdata *tx;
+{
+ int eot;
+ char tokens;
+ register struct ssapkt *s;
+
+ bzero ((char *) sx, sizeof *sx);
+ sx -> sx_qbuf.qb_forw = sx -> sx_qbuf.qb_back = &sx -> sx_qbuf;
+ bzero ((char *) si, sizeof *si);
+
+ for (; s = sb2spkt (sb, si, secs, tx); tx = NULLTX) {
+ if (!(s -> s_mask & SMASK_SPDU_EXPD))
+ switch (sb -> sb_pr) {
+ case SPDU_PR:
+ break;
+
+ case SPDU_MAA:
+ if (s -> s_code == SPDU_MAA)
+ sb -> sb_pr = SPDU_PR;
+ break;
+
+ case SPDU_RS:
+ switch (s -> s_code) {
+ case SPDU_AB:
+#ifdef notdef
+ case SPDU_AI: /* aka SPDU_AB */
+#endif
+ if (s -> s_mask & SMASK_SPDU_AB)
+ break; /* else fall */
+ case SPDU_AD:
+ case SPDU_RS:
+ sb -> sb_pr = SPDU_PR;
+ break;
+
+ default:
+ goto drop_it;
+ }
+ break;
+
+ case SPDU_RA:
+ switch (s -> s_code) {
+ case SPDU_AB:
+ break;
+
+ case SPDU_AA:
+#ifdef notdef
+ case SPDU_AIA: /* aka SPDU_AA */
+#endif
+ if (s -> s_mask & SMASK_SPDU_AA)
+ break; /* else fall */
+ case SPDU_ADA:
+ case SPDU_RA:
+ sb -> sb_pr = SPDU_PR;
+ break;
+
+ default:
+drop_it: ;
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("discarding 0x%x SPDU", s -> s_code));
+ freespkt (s);
+ goto spin;
+ }
+ break;
+
+ case SPDU_AB:
+ if (s -> s_code != SPDU_AB)
+ goto drop_it;
+ sb -> sb_pr = SPDU_PR;
+ break;
+
+ default:
+ break;
+ }
+
+ if (sb -> sb_flags & (SB_RS | SB_AI))
+ switch (s -> s_code) {
+ case SPDU_PR:
+ switch (s -> s_pr_type) {
+ case PR_RS:
+ case PR_RA:
+ break;
+ default:
+ goto drop_it;
+ }
+ break;
+
+ case SPDU_RS:
+ if (SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+ sb -> sb_rs, sb -> sb_rsn,
+ (int) s -> s_rs_type, (long) s -> s_rs_serial)
+ != NOTOK)
+ goto drop_it;
+ break;
+
+ case SPDU_RA:
+ break;
+
+ case SPDU_AD:
+ if (SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+ sb -> sb_rs, sb -> sb_rsn, SYNC_DISC, 0L)
+ != NOTOK)
+ goto drop_it;
+ break;
+
+ case SPDU_AB:
+#ifdef notdef
+ case SPDU_AI: /* aka SPDU_AB */
+#endif
+ if (s -> s_mask & SMASK_SPDU_AB)
+ break;
+ if (SDoCollideAux (sb -> sb_flags & SB_INIT ? 1 : 0,
+ sb -> sb_rs, sb -> sb_rsn, SYNC_INTR, 0L)
+ != NOTOK)
+ goto drop_it;
+ break;
+ }
+
+ if (sb -> sb_flags & (SB_ED | SB_ERACK))
+ switch (s -> s_code) {
+ case SPDU_AB:
+ break;
+
+ case SPDU_MAP:
+ case SPDU_MIP:
+ if (sb -> sb_flags & SB_ED)
+ break;
+ goto drop_it;
+
+ case SPDU_PR:
+ if (s -> s_pr_type == PR_RS)
+ break;
+ goto drop_it;
+
+ case SPDU_GT:
+ if ((s -> s_mask & SMASK_SPDU_GT)
+ && (s -> s_mask & SMASK_GT_TOKEN)
+ && (s -> s_gt_token & ST_DAT_TOKEN))
+ break; /* else fall */
+
+ default:
+ goto drop_it;
+ }
+
+ if (sb -> sb_len > 0)
+ switch (s -> s_code) {
+ case SPDU_PT:
+ case SPDU_EX:
+ break;
+
+ case SPDU_PR:
+ if (s -> s_pr_type != PR_RS)
+ break;
+ case SPDU_RS:
+ case SPDU_ER:
+ case SPDU_ED:
+ case SPDU_AD:
+#ifdef notdef
+ case SPDU_AI: /* aka SPDU_AB */
+#endif
+ case SPDU_AB:
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("flush partially assembled (T))SSDU"));
+ QBFREE (&sb -> sb_qbuf);
+ sb -> sb_len = 0;
+ break;
+
+ case SPDU_GT:
+ if (s -> s_mask & SMASK_SPDU_GT)
+ break; /* else SPDU_DT */
+ default:
+ if (sb -> sb_code == s -> s_code)
+ break;
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: expecting 0x%x, got 0x%x during segmentation",
+ sb -> sb_code, s -> s_code);
+ goto out;
+ }
+
+/* allows AB SPDUs to have 512, not 9, octets (which is fine by me) */
+ if (s -> s_ulen > CN_SIZE && sb -> sb_version < SB_VRSN2) {
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "too much user data (%d) in SPDU 0x%x",
+ s -> s_ulen, s -> s_code);
+ goto out;
+ }
+
+ if ((s -> s_mask & SMASK_ENCLOSE)
+ && (s -> s_code != SPDU_DT || (s -> s_mask & SMASK_SPDU_GT))
+ && s -> s_code != SPDU_TD) {
+ if (sb -> sb_version < SB_VRSN2) {
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "unexpected segmentation for SPDU 0x%x",
+ s -> s_code);
+ goto out;
+ }
+
+/* XXX: in practice, I don't think this is unreasonable. It is
+ however not too restrictive */
+
+ if (s -> s_enclose != ENCL_MASK) {
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "non-trivial segmentation (0x%x) for SPDU 0x%x",
+ s -> s_enclose, s -> s_code);
+ goto out;
+ }
+ }
+
+ switch (s -> s_code) {
+ case SPDU_PT:
+ if (sb -> sb_flags & SB_GTC) {
+ freespkt (s);
+ goto spin;
+ }
+ tokens = 0;
+ if (s -> s_mask & SMASK_PT_TOKEN) {
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if ((sb -> sb_requirements & requires) \
+ && (s -> s_pt_token & bit)) \
+ tokens |= bit; \
+}
+ dotokens ();
+#undef dotoken
+ }
+ si -> si_type = SI_TOKEN;
+ {
+ register struct SSAPtoken *st = &si -> si_token;
+
+ st -> st_type = ST_PLEASE;
+ st -> st_tokens = tokens;
+ st -> st_owned = sb -> sb_owned;
+ copySPKTdata (s, st);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_GT:
+ if (s -> s_mask & SMASK_SPDU_GT) {
+ if (sb -> sb_flags & SB_GTC) {
+ freespkt (s);
+ goto spin;
+ }
+ tokens = 0;
+ if (s -> s_mask & SMASK_GT_TOKEN) {
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if ((sb -> sb_requirements & requires) \
+ && (s -> s_gt_token & bit)) \
+ sb -> sb_owned |= bit, tokens |= bit; \
+}
+ dotokens ();
+#undef dotoken
+ }
+ freespkt (s);
+ if (tokens & ST_DAT_TOKEN)
+ sb -> sb_flags &= ~(SB_ED | SB_ERACK);
+ si -> si_type = SI_TOKEN;
+ {
+ register struct SSAPtoken *st = &si -> si_token;
+
+ st -> st_type = ST_GIVE;
+ st -> st_tokens = tokens;
+ st -> st_owned = sb -> sb_owned;
+ }
+ return DONE;
+ } /* else fall for case SPDU_DT: */
+#ifdef notdef
+ case SPDU_DT:
+#endif
+ case SPDU_TD:
+ sb -> sb_code = s -> s_code;
+ if (sb -> sb_tsdu_them) {
+ if (!(s -> s_mask & SMASK_ENCLOSE)) {
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "no segmentation information");
+ break;
+ }
+ if ((s -> s_enclose & ENCL_BEGIN)
+ ? sb -> sb_len > 0 : sb -> sb_len == 0) {
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "segmentation mismatch");
+ break;
+ }
+ eot = s -> s_enclose & ENCL_END;
+ }
+ else
+ eot = 1;
+ if (s -> s_qbuf.qb_forw != &s -> s_qbuf) {
+ sb -> sb_qbuf.qb_back -> qb_forw = s -> s_qbuf.qb_forw;
+ s -> s_qbuf.qb_forw -> qb_back = sb -> sb_qbuf.qb_back;
+ s -> s_qbuf.qb_back -> qb_forw = &sb -> sb_qbuf;
+ sb -> sb_qbuf.qb_back = s -> s_qbuf.qb_back;
+ sb -> sb_len += s -> s_qlen;
+ s -> s_qbuf.qb_forw =
+ s -> s_qbuf.qb_back = &s -> s_qbuf;
+ s -> s_qlen = 0;
+ }
+ if (!eot && (s -> s_code == SPDU_DT) && sb -> sb_spdu) {
+ freespkt (sb -> sb_spdu);
+ sb -> sb_spdu = NULL;
+ }
+ freespkt (s);
+ if (!eot)
+ goto spin;
+ sx -> sx_type = sb -> sb_code == SPDU_DT ? SX_NORMAL
+ : SX_TYPED;
+ if (sb -> sb_qbuf.qb_forw != &sb -> sb_qbuf) {
+ sx -> sx_qbuf = sb -> sb_qbuf;/* struct copy */
+ sx -> sx_qbuf.qb_forw -> qb_back =
+ sx -> sx_qbuf.qb_back -> qb_forw = &sx -> sx_qbuf;
+ sx -> sx_cc = sb -> sb_len;
+ sb -> sb_qbuf.qb_forw =
+ sb -> sb_qbuf.qb_back = &sb -> sb_qbuf;
+ sb -> sb_len = 0;
+ }
+ return OK;
+
+ case SPDU_EX:
+ if (sb -> sb_pr != SPDU_PR) {
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("buffering XSDU during preparation"));
+ if (sb -> sb_xspdu) {
+ (void) spktlose (sb -> sb_fd, si, SC_CONGEST, NULLCP,
+ "unable to buffer second XSDU");
+ break;
+ }
+ sb -> sb_xspdu = s;
+ goto spin;
+ }
+ sx -> sx_type = SX_EXPEDITED;
+ if (s -> s_qbuf.qb_forw != &s -> s_qbuf) {
+ sx -> sx_qbuf = s -> s_qbuf;/* struct copy */
+ sx -> sx_qbuf.qb_forw -> qb_back =
+ sx -> sx_qbuf.qb_back -> qb_forw = &sx -> sx_qbuf;
+ sx -> sx_cc = s -> s_qlen;
+ s -> s_qbuf.qb_forw =
+ s -> s_qbuf.qb_back = &s -> s_qbuf;
+ s -> s_qlen = 0;
+ }
+ freespkt (s);
+ return OK;
+
+ case SPDU_CD:
+ case SPDU_CDA:
+ if (s -> s_code == SPDU_CD) {
+ sb -> sb_flags |= SB_CDA;
+ sx -> sx_type = SX_CAPDIND;
+ }
+ else {
+ sb -> sb_flags &= ~SB_CD;
+ sx -> sx_type = SX_CAPDCNF;
+ }
+ if (s -> s_udata) {
+ register struct qbuf *qb;
+
+ qb = (struct qbuf *)
+ malloc (sizeof *qb + (unsigned) s -> s_ulen);
+ if (qb == NULL) {
+ (void) spktlose (sb -> sb_fd, si, SC_CONGEST, NULLCP,
+ "out of memory");
+ break;
+ }
+ bcopy (s -> s_udata, qb -> qb_data = qb -> qb_base,
+ qb -> qb_len = s -> s_ulen);
+ insque (qb, &sx -> sx_qbuf);
+ sx -> sx_cc = s -> s_ulen;
+ }
+ freespkt (s);
+ return OK;
+
+ case SPDU_GTC:
+ if (sb -> sb_flags & SB_Vact) {
+ freespkt (s);
+ goto spin;
+ }
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ sb -> sb_owned |= bit; \
+}
+ dotokens ();
+#undef dotoken
+ freespkt (s);
+ if ((s = newspkt (SPDU_GTA)) == NULL) {
+ (void) spktlose (sb -> sb_fd, si, SC_CONGEST, NULLCP,
+ "out of memory");
+ break;
+ }
+ if (spkt2sd (s, sb -> sb_fd, 0, si) == NOTOK)
+ break;
+ freespkt (s);
+ si -> si_type = SI_TOKEN;
+ {
+ register struct SSAPtoken *st = &si -> si_token;
+
+ st -> st_type = ST_CONTROL;
+ st -> st_tokens = st -> st_owned = sb -> sb_owned;
+ }
+ return DONE;
+
+ case SPDU_GTA:
+ if (!(sb -> sb_flags & SB_GTC)) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_flags &= ~SB_GTC;
+spin: ;
+ if (!async || sb -> sb_spdu)
+ continue;
+ si -> si_type = SI_DATA;
+ {
+ register struct SSAPdata *sk = &si -> si_data;
+
+ bzero ((char *) sk, sizeof *sk);
+ sk -> sx_qbuf.qb_forw = sk -> sx_qbuf.qb_back =
+ &sk -> sx_qbuf;
+ }
+ return DONE;
+
+ case SPDU_MAP:
+#ifdef notdef
+ case SPDU_AE: /* aka SPDU_MAP */
+#endif
+ if (sb -> sb_V_M != s -> s_map_serial) {
+ freespkt (s);
+ goto spin;
+ }
+ if (!(s -> s_mask & SMASK_MAP_SYNC)
+ || !(s -> s_map_sync & MAP_SYNC_NOEND))
+ goto spdu_ae;
+ if (!(sb -> sb_flags & SB_Vsc))
+ sb -> sb_V_A = sb -> sb_V_M;
+ sb -> sb_V_M++;
+ if (sb -> sb_flags & (SB_ED | SB_ERACK)) {
+ freespkt (s);
+ goto spin;
+ }
+ if (sb -> sb_requirements & SR_ACTIVITY)
+ sb -> sb_flags |= SB_Vnextact;
+ sb -> sb_flags |= SB_MAA;
+ si -> si_type = SI_SYNC;
+ {
+ register struct SSAPsync *sn = &si -> si_sync;
+
+ sn -> sn_type = SN_MAJORIND;
+ sn -> sn_ssn = s -> s_map_serial;
+ copySPKTdata (s, sn);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_MAA:
+#ifdef notdef
+ case SPDU_AEA: /* aka SPDU_MAA */
+#endif
+ if (sb -> sb_V_M != s -> s_maa_serial + 1) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_V_A = sb -> sb_V_R = sb -> sb_V_M;
+ if (sb -> sb_requirements & SR_ACTIVITY)
+ if (sb -> sb_flags & SB_Vnextact)
+ sb -> sb_flags |= SB_Vact;
+ else
+ sb -> sb_flags &= ~SB_Vact;
+ sb -> sb_flags &= ~SB_MAP;
+ if (sb -> sb_flags & SB_AE) {
+ sb -> sb_flags &= ~SB_AE;
+ si -> si_type = SI_ACTIVITY;
+ {
+ register struct SSAPactivity *sv = &si -> si_activity;
+
+ sv -> sv_type = SV_ENDCNF;
+ sv -> sv_ssn = s -> s_maa_serial;
+ copySPKTdata (s, sv);
+ }
+ }
+ else {
+ si -> si_type = SI_SYNC;
+ {
+ register struct SSAPsync *sn = &si -> si_sync;
+
+ sn -> sn_type = SN_MAJORCNF;
+ sn -> sn_ssn = s -> s_maa_serial;
+ copySPKTdata (s, sn);
+ }
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_MIP:
+ if (!(sb -> sb_flags & SB_Vsc)) {
+ sb -> sb_V_A = sb -> sb_V_M;
+ sb -> sb_flags |= SB_Vsc;
+ }
+ sb -> sb_V_M++;
+ if (sb -> sb_flags & (SB_ED | SB_ERACK)) {
+ freespkt (s);
+ goto spin;
+ }
+ si -> si_type = SI_SYNC;
+ {
+ register struct SSAPsync *sn = &si -> si_sync;
+
+ sn -> sn_type = SN_MINORIND;
+ sn -> sn_options = (s -> s_mask & SMASK_MIP_SYNC)
+ && (s -> s_mip_sync & MIP_SYNC_NOEXPL)
+ ? SYNC_NOCONFIRM : SYNC_CONFIRM;
+ sn -> sn_ssn = s -> s_mip_serial;
+ copySPKTdata (s, sn);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_MIA:
+ if ((sb -> sb_flags & SB_Vsc)
+ || sb -> sb_V_A > s -> s_mia_serial
+ || s -> s_mia_serial >= sb -> sb_V_M) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_V_A = s -> s_mia_serial;
+ si -> si_type = SI_SYNC;
+ {
+ register struct SSAPsync *sn = &si -> si_sync;
+
+ sn -> sn_type = SN_MINORCNF;
+ sn -> sn_ssn = s -> s_mia_serial;
+ copySPKTdata (s, sn);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_RS:
+ if (s -> s_rs_type == SYNC_RESTART
+ && sb -> sb_V_R > s -> s_rs_serial) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_flags &= ~SB_RS, sb -> sb_flags |= SB_RA;
+ sb -> sb_rs = s -> s_rs_type;
+ sb -> sb_rsn = s -> s_rs_serial;
+ if (s -> s_mask & SMASK_RS_SET)
+ sb -> sb_rsettings = s -> s_rs_settings;
+ else {
+ sb -> sb_rsettings = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ if ((sb -> sb_owned & bit) \
+ && (sb -> sb_flags & SB_INIT)) \
+ sb -> sb_rsettings = ST_INIT_VALUE << shift; \
+ else \
+ sb -> sb_rsettings = ST_RESP_VALUE << shift; \
+}
+ dotokens ();
+#undef dotoken
+ }
+ si -> si_type = SI_SYNC;
+ {
+ register struct SSAPsync *sn = &si -> si_sync;
+
+ sn -> sn_type = SN_RESETIND;
+ sn -> sn_options = sb -> sb_rs;
+ sn -> sn_ssn = sb -> sb_rsn;
+ sn -> sn_settings = sb -> sb_rsettings;
+ copySPKTdata (s, sn);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_RA:
+ sb -> sb_flags &= ~SB_RS;
+ sb -> sb_V_A = sb -> sb_V_M = s -> s_ra_serial;
+ if (sb -> sb_rs != SYNC_RESTART)
+ sb -> sb_V_R = 0;
+ if (s -> s_mask & SMASK_RA_SET)
+ sb -> sb_rsettings = s -> s_ra_settings;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ switch (sb -> sb_rsettings & (ST_MASK << shift)) { \
+ dotoken1 (requires,shift,bit,type); \
+ \
+ dotoken2 (requires,shift,bit,type); \
+ } \
+}
+#define dotoken1(requires,shift,bit,type) \
+ case ST_CALL_VALUE << shift: \
+ switch (s -> s_ra_settings & (ST_MASK << shift)) { \
+ case ST_INIT_VALUE: \
+ if (sb -> sb_flags & SB_INIT) \
+ sb -> sb_owned |= bit; \
+ else \
+ sb -> sb_owned &= ~bit; \
+ break; \
+ \
+ case ST_RESP_VALUE: \
+ if (!(sb -> sb_flags & SB_INIT)) \
+ sb -> sb_owned |= bit; \
+ else \
+ sb -> sb_owned &= ~bit; \
+ break; \
+ } \
+ break;
+#define dotoken2(requires,shift,bit,type) \
+ case ST_INIT_VALUE << shift: \
+ if (sb -> sb_flags & SB_INIT) \
+ sb -> sb_owned |= bit; \
+ else \
+ sb -> sb_owned &= ~bit; \
+ break; \
+ \
+ case ST_RESP_VALUE << shift: \
+ if (!(sb -> sb_flags & SB_INIT)) \
+ sb -> sb_owned |= bit; \
+ else \
+ sb -> sb_owned &= ~bit; \
+ break;
+ dotokens ();
+#undef dotoken
+#undef dotoken1
+#undef dotoken2
+ si -> si_type = SI_SYNC;
+ {
+ register struct SSAPsync *sn = &si -> si_sync;
+
+ sn -> sn_type = SN_RESETCNF;
+ sn -> sn_ssn = sb -> sb_V_M;
+ sn -> sn_settings = sb -> sb_rsettings;
+ copySPKTdata (s, sn);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_PR:
+ switch (s -> s_pr_type) {
+ case PR_MAA:
+ sb -> sb_pr = SPDU_MAA;
+ break;
+ case PR_RS:
+ sb -> sb_flags &= ~(SB_ED | SB_ERACK);
+ sb -> sb_pr = SPDU_RS;
+ break;
+ case PR_RA:
+ sb -> sb_pr = SPDU_RA;
+ break;
+ case PR_AB:
+ sb -> sb_pr = SPDU_AB;
+ break;
+ }
+ freespkt (s);
+ goto spin;
+
+ case SPDU_ER: /* this implementation never generates these */
+ sb -> sb_flags |= SB_ERACK;
+ si -> si_type = SI_REPORT;
+ {
+ register struct SSAPreport *sp = &si -> si_report;
+
+ sp -> sp_peer = 0;
+ sp -> sp_reason = SP_PROTOCOL;
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_ED:
+ if (sb -> sb_owned & ST_DAT_TOKEN)
+ sb -> sb_flags |= SB_EDACK;
+ si -> si_type = SI_REPORT;
+ {
+ register struct SSAPreport *sp = &si -> si_report;
+
+ sp -> sp_peer = 1;
+ sp -> sp_reason = s -> s_ed_reason;
+ copySPKTdata (s, sp);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_AS:
+ if (sb -> sb_flags & SB_Vact) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_V_A = sb -> sb_V_M = sb -> sb_V_R = 1;
+ sb -> sb_flags |= SB_Vact;
+ si -> si_type = SI_ACTIVITY;
+ {
+ register struct SSAPactivity *sv = &si -> si_activity;
+
+ sv -> sv_type = SV_START;
+ sv -> sv_id = s -> s_as_id; /* struct copy */
+ copySPKTdata (s, sv);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_AR:
+ if (sb -> sb_flags & SB_Vact) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_V_A = sb -> sb_V_M = s -> s_ar_serial + 1;
+ sb -> sb_V_R = 1;
+ sb -> sb_flags |= SB_Vact;
+ si -> si_type = SI_ACTIVITY;
+ {
+ register struct SSAPactivity *sv = &si -> si_activity;
+
+ sv -> sv_type = SV_RESUME;
+ sv -> sv_id = s -> s_ar_id; /* struct copy */
+ sv -> sv_oid = s -> s_ar_oid; /* struct copy */
+ if (s -> s_mask & SMASK_AR_REF) /* struct copy */
+ sv -> sv_connect = s -> s_ar_reference;
+ sv -> sv_ssn = s -> s_ar_serial;
+ copySPKTdata (s, sv);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_AD:
+spdu_ai: ;
+ if (!(sb -> sb_flags & SB_Vact)) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_flags &= ~(SB_RS | SB_RA), sb -> sb_flags |= SB_AIA;
+ sb -> sb_rs = SYNC_INTR;
+ si -> si_type = SI_ACTIVITY;
+ {
+ register struct SSAPactivity *sv = &si -> si_activity;
+
+ sv -> sv_type = s -> s_code == SPDU_AI ? SV_INTRIND
+ : SV_DISCIND;
+ sv -> sv_reason = s -> s_ai_reason;
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_AA:
+#ifdef notdef
+ case SPDU_AIA: /* aka SPDU_AA */
+#endif
+ if (s -> s_mask & SMASK_SPDU_AA) {
+ freespkt (s);
+ goto spin;
+ } /* else fall */
+ case SPDU_ADA:
+ if (!(sb -> sb_flags & SB_Vact)) {
+ freespkt (s);
+ goto spin;
+ }
+ sb -> sb_flags &= ~(SB_AI | SB_Vact);
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (sb -> sb_requirements & requires) \
+ sb -> sb_owned |= bit; \
+}
+ dotokens ();
+#undef dotoken
+ si -> si_type = SI_ACTIVITY;
+ {
+ register struct SSAPactivity *sv = &si -> si_activity;
+
+ sv -> sv_type = s -> s_code == SPDU_AIA ? SV_INTRCNF
+ : SV_DISCCNF;
+ }
+ freespkt (s);
+ return DONE;
+
+spdu_ae: ;
+ if (!(sb -> sb_flags & SB_Vsc))
+ sb -> sb_V_A = sb -> sb_V_M;
+ sb -> sb_V_M++;
+ sb -> sb_flags &= ~SB_Vnextact;
+ sb -> sb_flags |= SB_MAA | SB_AE;
+ si -> si_type = SI_ACTIVITY;
+ {
+ register struct SSAPactivity *sv = &si -> si_activity;
+
+ sv -> sv_type = SV_ENDIND;
+ sv -> sv_ssn = s -> s_map_serial;
+ copySPKTdata (s, sv);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_FN:
+ sb -> sb_flags |= SB_FINN;
+ si -> si_type = SI_FINISH;
+ {
+ register struct SSAPfinish *sf = &si -> si_finish;
+
+ copySPKTdata (s, sf);
+ }
+ freespkt (s);
+ return DONE;
+
+ case SPDU_AB:
+ if (!(s -> s_mask & SMASK_SPDU_AB))
+ goto spdu_ai;
+ sb -> sb_flags &= ~(SB_ED | SB_EDACK | SB_ERACK);
+ si -> si_type = SI_ABORT;
+ {
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if (!(sa -> sa_peer = (s -> s_ab_disconnect & AB_DISC_USER)
+ ? 1 : 0))
+ sa -> sa_reason = SC_ABORT;
+ sa -> sa_info = s -> s_udata, sa -> sa_cc = s -> s_ulen;
+ sa -> sa_realinfo = s -> s_udata, s -> s_udata = NULL;
+ }
+#ifdef notdef /* only if transport connection is to be re-used */
+ freespkt (s);
+ if (s = newspkt (SPDU_AA)) {
+ s -> s_mask |= SMASK_SPDU_AA;
+ (void) spkt2sd (s, sb -> sb_fd, sb -> sb_flags & SB_EXPD
+ ? 1 : 0, (struct SSAPindication *) 0);
+ }
+#endif
+ break;
+
+ default:
+ (void) spktlose (sb -> sb_fd, si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: not expecting 0x%x",
+ s -> s_code);
+ break;
+ }
+ break;
+ }
+
+ if (si -> si_abort.sa_reason == SC_TIMER)
+ return NOTOK;
+
+out: ;
+ freespkt (s);
+ freesblk (sb);
+
+ return NOTOK;
+}
+
+/* \f */
+
+/* a decision tree (ugh!) */
+
+int SDoCollideAux (init, localop, localssn, remoteop, remotessn)
+int init,
+ localop,
+ remoteop;
+long localssn,
+ remotessn;
+{
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("collide: local<%d,%ld,%s> remote<%d,%ld,%s>",
+ localop, localssn, init ? "initiator" : "responder",
+ remoteop, remotessn, init ? "responder" : "initiator"));
+
+ if (localop == SYNC_DISC)
+ return OK;
+
+ if (remoteop == SYNC_DISC)
+ return NOTOK;
+
+ if (localop == SYNC_INTR)
+ return OK;
+
+ if (remoteop == SYNC_DISC)
+ return NOTOK;
+
+ if (localop == SYNC_ABANDON) {
+ if (remoteop != SYNC_ABANDON)
+ return OK;
+
+ return (init ? OK : NOTOK);
+ }
+ else
+ if (remoteop == SYNC_ABANDON)
+ return NOTOK;
+
+ if (localop == SYNC_SET) {
+ if (remoteop != SYNC_SET)
+ return OK;
+
+ return (init ? OK : NOTOK);
+ }
+ else
+ if (remoteop == SYNC_SET)
+ return NOTOK;
+
+ if (localssn == remotessn)
+ return (init ? OK : NOTOK);
+
+ return (localssn < remotessn ? OK : NOTOK);
+}
+
+/* \f define vectors for INDICATION events */
+
+int SSetIndications (sd, data, tokens, sync, activity, report, finish,
+ abort, si)
+int sd;
+IFP data,
+ tokens,
+ sync,
+ activity,
+ report,
+ finish,
+ abort;
+struct SSAPindication *si;
+{
+ SBV smask;
+ register struct ssapblk *sb;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if (data || tokens || sync || activity || report || finish || abort) {
+ missingP (data);
+ missingP (tokens);
+ missingP (sync);
+ missingP (activity);
+ missingP (report);
+ missingP (finish);
+ missingP (abort);
+ }
+ _iosignals_set = 1;
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+
+ if (sb -> sb_DataIndication = data)
+ sb -> sb_flags |= SB_ASYN;
+ else
+ sb -> sb_flags &= ~SB_ASYN;
+ sb -> sb_TokenIndication = tokens;
+ sb -> sb_SyncIndication = sync;
+ sb -> sb_ActivityIndication = activity;
+ sb -> sb_ReportIndication = report;
+ sb -> sb_ReleaseIndication = finish;
+ sb -> sb_AbortIndication = abort;
+
+ if (TSetIndications (sb -> sb_fd, TDATAser, TDISCser, td) == NOTOK) {
+ sb -> sb_flags &= ~SB_ASYN;
+ if (td -> td_reason == DR_WAITING)
+ return ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+ else
+ return ts2sslose (si, "TSetIndications", td);
+ }
+
+ (void) sigiomask (smask);
+
+ return OK;
+}
+
+/* \f TSAP interface */
+
+int spkt2sd (s, sd, expedited, si)
+register struct ssapkt *s;
+int sd,
+ expedited;
+register struct SSAPindication *si;
+{
+ int i,
+ len,
+ result;
+ char *base,
+ *dp;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if (expedited)
+ s -> s_mask |= SMASK_SPDU_EXPD;
+ if (spkt2tsdu (s, &base, &len) == NOTOK) {
+ (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+ return NOTOK;
+ }
+ if (s -> s_code == SPDU_EX) {/* only SX_EXSIZE octets, so no big deal... */
+ if (s -> s_udata) {
+ if ((dp = realloc (base, (unsigned) (i = len + s -> s_ulen)))
+ == NULL) {
+ free (base);
+ (void) ssaplose (si, SC_CONGEST, NULLCP, NULLCP);
+ return NOTOK;
+ }
+ bcopy (s -> s_udata, (base = dp) + len, s -> s_ulen);
+ len = i;
+ }
+ }
+
+ if (len > TX_SIZE)
+ expedited = 0;
+ if ((result = expedited ? TExpdRequest (sd, base, len, td)
+ : TDataRequest (sd, base, len, td)) == NOTOK)
+ (void) ts2sslose (si, expedited ? "TExpdRequest" : "TDataRequest", td);
+
+ if (base)
+ free (base);
+
+ return result;
+}
+
+/* \f */
+
+struct ssapkt *sb2spkt (sb, si, secs, ty)
+register struct ssapblk *sb;
+register struct SSAPindication *si;
+int secs;
+register struct TSAPdata *ty;
+{
+ int cc;
+ register struct ssapkt *s,
+ *p;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if (sb -> sb_pr == SPDU_PR && sb -> sb_xspdu) {
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("returning XSDU buffered during preparation"));
+ s = sb -> sb_xspdu;
+ sb -> sb_xspdu = NULL;
+
+ return s;
+ }
+
+ if (sb -> sb_spdu) { /* get previous category 0 SPDU */
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("returning category 0 SPDU previously buffered"));
+ s = sb -> sb_spdu;
+ sb -> sb_spdu = NULL;
+
+ return s;
+ }
+
+ if (ty) {
+ *tx = *ty; /* struct copy */
+ tx -> tx_qbuf.qb_forw -> qb_back =
+ tx -> tx_qbuf.qb_back -> qb_forw = &tx -> tx_qbuf;
+ bzero ((char *) ty, sizeof *ty);
+ ty -> tx_qbuf.qb_forw = ty -> tx_qbuf.qb_back = &ty -> tx_qbuf;
+ }
+ else
+ if (TReadRequest (sb -> sb_fd, tx, secs, td) == NOTOK) {
+ if (td -> td_reason != DR_TIMER)
+ (void) ts2sslose (si, "TReadRequest", td);
+ else
+ (void) ssaplose (si, SC_TIMER, NULLCP, NULLCP);
+
+ return NULL;
+ }
+
+ DLOG (ssap_log, LLOG_DEBUG, ("read TSDU, size %d", tx -> tx_cc));
+
+ if ((s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, (cc = 1, &cc))) == NULL
+ || s -> s_errno != SC_ACCEPT) {
+ (void) ssaplose (si, s ? s -> s_errno : SC_CONGEST, NULLCP, NULLCP);
+bad1: ;
+ freespkt (s);
+ TXFREE (tx);
+ return NULL;
+ }
+
+ if (tx -> tx_expedited)
+ s -> s_mask |= SMASK_SPDU_EXPD;
+ tx -> tx_cc -= cc;
+
+ switch (s -> s_code) {
+ case SPDU_GT: /* category 0 SPDUs */
+ case SPDU_PT:
+ if (tx -> tx_cc <= 0)
+ goto simple;
+ break;
+
+ case SPDU_EX: /* category 1 SPDUs with user data */
+ case SPDU_TD:
+ if (tx -> tx_qbuf.qb_forw != &tx -> tx_qbuf) {
+ s -> s_qbuf = tx -> tx_qbuf;/* struct copy */
+ s -> s_qbuf.qb_forw -> qb_back =
+ s -> s_qbuf.qb_back -> qb_forw = &s -> s_qbuf;
+ s -> s_qlen = tx -> tx_cc;
+ }
+ return s;
+
+ case SPDU_CN: /* category 1 SPDUs */
+ case SPDU_AC:
+ case SPDU_RF:
+ case SPDU_FN:
+ case SPDU_DN:
+ case SPDU_NF:
+ case SPDU_AB:
+ case SPDU_AA:
+ case SPDU_GTC:
+ case SPDU_GTA:
+ case SPDU_PR:
+ if (tx -> tx_cc <= 0) {
+ simple: ;
+ TXFREE (tx);
+ return s;
+ }
+ (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: not expecting user information after 0x%x (%d bytes)",
+ s -> s_code, tx -> tx_cc);
+ goto bad1;
+
+ default:
+ (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: not expecting 0x%x",
+ s -> s_code);
+ goto bad1;
+ }
+
+ sb -> sb_spdu = p = s; /* save category 0 SPDU */
+
+ if ((s = tsdu2spkt (&tx -> tx_qbuf, tx -> tx_cc, (cc = 0, &cc))) == NULL
+ || s -> s_errno != SC_ACCEPT) {
+ (void) ssaplose (si, s ? s -> s_errno : SC_CONGEST, NULLCP, NULLCP);
+bad2: ;
+ freespkt (s);
+ freespkt (p);
+ sb -> sb_spdu = NULL;
+ TXFREE (tx);
+ return NULL;
+ }
+
+ if (tx -> tx_expedited)
+ s -> s_mask |= SMASK_SPDU_EXPD;
+ tx -> tx_cc -= cc;
+
+ switch ((p -> s_code) << 8 | s -> s_code) {
+ case (SPDU_GT << 8) | SPDU_DT: /* category 2 SPDUs with user data */
+ if (tx -> tx_qbuf.qb_forw != &tx -> tx_qbuf) {
+ s -> s_qbuf = tx -> tx_qbuf;/* struct copy */
+ s -> s_qbuf.qb_forw -> qb_back =
+ s -> s_qbuf.qb_back -> qb_forw = &s -> s_qbuf;
+ s -> s_qlen = tx -> tx_cc;
+ }
+ break;
+
+ case (SPDU_GT << 8) | SPDU_MIP: /* category 2 SPDUs */
+ case (SPDU_PT << 8) | SPDU_MIA:
+ case (SPDU_GT << 8) | SPDU_MAP:
+ case (SPDU_PT << 8) | SPDU_MAA:
+ case (SPDU_GT << 8) | SPDU_RS:
+ case (SPDU_PT << 8) | SPDU_RA:
+ case (SPDU_GT << 8) | SPDU_AS:
+ case (SPDU_GT << 8) | SPDU_AR:
+ case (SPDU_GT << 8) | SPDU_AD:
+ case (SPDU_PT << 8) | SPDU_ADA:
+ case (SPDU_GT << 8) | SPDU_AI:
+ case (SPDU_PT << 8) | SPDU_AIA:
+#ifdef notdef
+ case (SPDU_GT << 8) | SPDU_AE: /* aka SPDU_MAP */
+ case (SPDU_PT << 8) | SPDU_AEA: /* aka SPDU_MAA */
+#endif
+ case (SPDU_GT << 8) | SPDU_CD:
+ case (SPDU_PT << 8) | SPDU_CDA:
+ case (SPDU_PT << 8) | SPDU_ER:
+ case (SPDU_PT << 8) | SPDU_ED:
+ if (tx -> tx_cc <= 0) {
+ TXFREE (tx);
+ break;
+ }
+ (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: not expecting user information after 0x%x (%d bytes)",
+ s -> s_code, tx -> tx_cc);
+ goto bad2;
+
+ default:
+ (void) ssaplose (si, SC_PROTOCOL, NULLCP,
+ "session protocol mangled: not expecting 0x%x to be concatenated after 0x%x",
+ s -> s_code, p -> s_code);
+ goto bad2;
+ }
+
+ switch (s -> s_code) {
+ default:
+ if (p -> s_code == SPDU_GT) {
+ if ((p -> s_mask & SMASK_GT_TOKEN) && p -> s_gt_token)
+ break;
+ }
+ else {
+ if (((p -> s_mask & SMASK_PT_TOKEN) && p -> s_pt_token)
+ || p -> s_ulen)
+ break;
+ } /* fall... */
+
+ case SPDU_RS:
+ case SPDU_AD:
+ case SPDU_AI:
+ case SPDU_CD:
+ freespkt (p);
+ sb -> sb_spdu = NULL;
+ break;
+ }
+
+ return s;
+}
+
+/* \f */
+
+static int TDATAser (sd, tx)
+int sd;
+register struct TSAPdata *tx;
+{
+ IFP abort;
+ register struct ssapblk *sb;
+ struct SSAPdata sxs;
+ register struct SSAPdata *sx = &sxs;
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if ((sb = findsblk (sd)) == NULL)
+ return;
+
+ abort = sb -> sb_AbortIndication;
+
+ for (;; tx = NULLTX) {
+ switch (SReadRequestAux (sb, sx, OK, si, 1, tx)) {
+ case NOTOK:
+ (*abort) (sd, sa);
+ return;
+
+ case OK:
+ (*sb -> sb_DataIndication) (sd, sx);
+ break;
+
+ case DONE:
+ switch (si -> si_type) {
+ case SI_TOKEN:
+ (*sb -> sb_TokenIndication) (sd, &si -> si_token);
+ break;
+
+ case SI_SYNC:
+ (*sb -> sb_SyncIndication) (sd, &si -> si_sync);
+ break;
+
+ case SI_ACTIVITY:
+ (*sb -> sb_ActivityIndication) (sd, &si -> si_activity);
+ break;
+
+ case SI_REPORT:
+ (*sb -> sb_ReportIndication) (sd, &si -> si_report);
+ break;
+
+ case SI_FINISH:
+ (*sb -> sb_ReleaseIndication) (sd, &si -> si_finish);
+ break;
+
+ case SI_DATA: /* partially assembled (T)SSDU */
+ break;
+ }
+ break;
+ }
+
+ if (sb -> sb_spdu == NULL)
+ break;
+ }
+}
+
+/* \f */
+
+static int TDISCser (sd, td)
+int sd;
+register struct TSAPdisconnect *td;
+{
+ IFP abort;
+ register struct ssapblk *sb;
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+
+ if ((sb = findsblk (sd)) == NULL)
+ return;
+
+ (void) ts2sslose (si, NULLCP, td);
+
+ abort = sb -> sb_AbortIndication;
+
+ sb -> sb_fd = NOTOK;
+ (void) freesblk (sb);
+
+ (*abort) (sd, &si -> si_abort);
+}
+
+/* \f */
+
+int ts2sslose (si, event, td)
+register struct SSAPindication *si;
+char *event;
+register struct TSAPdisconnect *td;
+{
+ int reason;
+ char *cp,
+ buffer[BUFSIZ];
+
+ if (event)
+ SLOG (ssap_log, LLOG_EXCEPTIONS, NULLCP,
+ (td -> td_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
+ TErrString (td -> td_reason), td -> td_cc, td -> td_cc,
+ td -> td_data));
+
+ cp = "";
+ switch (td -> td_reason) {
+ case DR_REMOTE:
+ case DR_CONGEST:
+ reason = SC_CONGEST;
+ break;
+
+ case DR_SESSION:
+ case DR_ADDRESS:
+ reason = SC_ADDRESS;
+ break;
+
+ case DR_REFUSED:
+ reason = SC_REFUSED;
+ break;
+
+ default:
+ (void) sprintf (cp = buffer, " (%s at transport)",
+ TErrString (td -> td_reason));
+ case DR_NETWORK:
+ reason = SC_TRANSPORT;
+ break;
+ }
+
+ if (td -> td_cc > 0)
+ return ssaplose (si, reason, NULLCP, "%*.*s%s",
+ td -> td_cc, td -> td_cc, td -> td_data, cp);
+ else
+ return ssaplose (si, reason, NULLCP, "%s", *cp ? cp + 1 : cp);
+}
+
+/* \f INTERNAL */
+
+struct ssapblk *newsblk () {
+ register struct ssapblk *sb;
+
+ sb = (struct ssapblk *) calloc (1, sizeof *sb);
+ if (sb == NULL)
+ return NULL;
+
+ sb -> sb_fd = NOTOK;
+ sb -> sb_qbuf.qb_forw = sb -> sb_qbuf.qb_back = &sb -> sb_qbuf;
+ sb -> sb_pr = SPDU_PR;
+
+ if (once_only == 0) {
+ SHead -> sb_forw = SHead -> sb_back = SHead;
+ once_only++;
+ }
+
+ insque (sb, SHead -> sb_back);
+
+ return sb;
+}
+
+
+int freesblk (sb)
+register struct ssapblk *sb;
+{
+ if (sb == NULL)
+ return;
+
+ if (sb -> sb_fd != NOTOK) {
+ struct TSAPdata txs;
+ struct TSAPdisconnect tds;
+
+ if (sb -> sb_flags & SB_FINN)
+ /* Wait for a TDiscInd for ses_dn_timer seconds */
+ if (ses_dn_timer >= 0)
+ while (TReadRequest (sb -> sb_fd, &txs, ses_dn_timer,
+ &tds) != NOTOK) {
+ TXFREE (&txs);
+ }
+
+ (void) TDiscRequest (sb -> sb_fd, NULLCP, 0, &tds);
+ }
+
+ if (sb -> sb_retry) {
+ sb -> sb_retry -> s_mask &= ~SMASK_UDATA_PGI;
+ sb -> sb_retry -> s_udata = NULL, sb -> sb_retry -> s_ulen = 0;
+ freespkt (sb -> sb_retry);
+ }
+
+ if (sb -> sb_xspdu)
+ freespkt (sb -> sb_xspdu);
+ if (sb -> sb_spdu)
+ freespkt (sb -> sb_spdu);
+
+ QBFREE (&sb -> sb_qbuf);
+
+ remque (sb);
+
+ free ((char *) sb);
+}
+
+/* \f */
+
+struct ssapblk *findsblk (sd)
+register int sd;
+{
+ register struct ssapblk *sb;
+
+ if (once_only == 0)
+ return NULL;
+
+ for (sb = SHead -> sb_forw; sb != SHead; sb = sb -> sb_forw)
+ if (sb -> sb_fd == sd)
+ return sb;
+
+ return NULL;
+}
--- /dev/null
+/* ssapselect.c - SPM: map descriptors */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapselect.c,v 7.1 91/02/22 09:46:07 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapselect.c,v 7.1 91/02/22 09:46:07 mrose Interim $
+ *
+ *
+ * $Log: ssapselect.c,v $
+ * Revision 7.1 91/02/22 09:46:07 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:50 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f map session descriptors for select() */
+
+int SSelectMask (sd, mask, nfds, si)
+int sd;
+fd_set *mask;
+int *nfds;
+register struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ missingP (mask);
+ missingP (nfds);
+
+ smask = sigioblock ();
+
+ if ((sb = findsblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "invalid session descriptor");
+ }
+
+ if ((result = TSelectMask (sb -> sb_fd, mask, nfds, td)) == NOTOK)
+ if (td -> td_reason == DR_WAITING)
+ (void) ssaplose (si, SC_WAITING, NULLCP, NULLCP);
+ else
+ (void) ts2sslose (si, "TSelectMask", td);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
--- /dev/null
+/* ssaptoken.c - SPM: tokens */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaptoken.c,v 7.1 91/02/22 09:46:08 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaptoken.c,v 7.1 91/02/22 09:46:08 mrose Interim $
+ *
+ *
+ * $Log: ssaptoken.c,v $
+ * Revision 7.1 91/02/22 09:46:08 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:50 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-TOKEN-GIVE.REQUEST */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (tokens & bit) { \
+ if (!(sb -> sb_requirements & requires)) \
+ return ssaplose (si, SC_OPERATION, NULLCP, \
+ "%s token unavailable", type); \
+ if (!(sb -> sb_owned & bit)) \
+ return ssaplose (si, SC_OPERATION, NULLCP, \
+ "%s token not owned by you", type); \
+ settings |= bit; \
+ } \
+}
+
+/* \f */
+
+int SGTokenRequest (sd, tokens, si)
+int sd;
+int tokens;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapXsig (sb, sd);
+
+ result = SGTokenRequestAux (sb, tokens, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SGTokenRequestAux (sb, tokens, si)
+register struct ssapblk *sb;
+int tokens;
+struct SSAPindication *si;
+{
+ int result,
+ settings;
+ register struct ssapkt *s;
+
+ settings = 0;
+ dotokens ();
+ if (settings == 0)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "no tokens to give");
+
+ if (sb -> sb_flags & SB_GTC)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "give control request in progress");
+
+ if (settings & ST_DAT_TOKEN)
+ sb -> sb_flags &= ~(SB_EDACK | SB_ERACK);
+ else
+ if (sb -> sb_flags & (SB_EDACK | SB_ERACK))
+ return ssaplose (si, SC_OPERATION, "exception in progress");
+
+ if ((s = newspkt (SPDU_GT)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ s -> s_mask |= SMASK_SPDU_GT;
+
+ s -> s_mask |= SMASK_GT_TOKEN;
+ s -> s_gt_token = settings & 0xff;
+
+ if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+ freesblk (sb);
+ else
+ sb -> sb_owned &= ~s -> s_gt_token;
+
+ freespkt (s);
+
+ return result;
+}
+
+#undef dotoken
+
+/* \f S-TOKEN-PLEASE.REQUEST */
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (tokens & bit) { \
+ if (!(sb -> sb_requirements & requires)) \
+ return ssaplose (si, SC_OPERATION, NULLCP, \
+ "%s token unavailable", type); \
+ if (sb -> sb_owned & bit) \
+ return ssaplose (si, SC_OPERATION, NULLCP, \
+ "%s token owned by you", type); \
+ settings |= bit; \
+ } \
+}
+
+/* \f */
+
+int SPTokenRequest (sd, tokens, data, cc, si)
+int sd;
+int tokens,
+ cc;
+char *data;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ register struct ssapblk *sb;
+
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+ toomuchP (sb, data, cc, ST_SIZE, "token");
+
+ result = SPTokenRequestAux (sb, tokens, data, cc, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int SPTokenRequestAux (sb, tokens, data, cc, si)
+register struct ssapblk *sb;
+int tokens,
+ cc;
+char *data;
+struct SSAPindication *si;
+{
+ int result,
+ settings;
+ register struct ssapkt *s;
+
+ settings = 0;
+ dotokens ();
+ if (settings == 0)
+ return ssaplose (si, SC_PARAMETER, NULLCP, "no tokens to ask for");
+
+ if (sb -> sb_flags & SB_GTC)
+ return ssaplose (si, SC_OPERATION, NULLCP,
+ "give control request in progress");
+
+ if ((s = newspkt (SPDU_PT)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+ s -> s_mask |= SMASK_PT_TOKEN;
+ s -> s_pt_token = settings & 0xff;
+
+ if (cc > 0) {
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+ if ((result = spkt2sd (s, sb -> sb_fd, 0, si)) == NOTOK)
+ freesblk (sb);
+ s -> s_mask &= ~SMASK_UDATA_PGI;
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ freespkt (s);
+
+ return result;
+}
+
+#undef dotoken
--- /dev/null
+/* ssaptyped.c - SPM: write typed data */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssaptyped.c,v 7.1 91/02/22 09:46:09 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssaptyped.c,v 7.1 91/02/22 09:46:09 mrose Interim $
+ *
+ *
+ * $Log: ssaptyped.c,v $
+ * Revision 7.1 91/02/22 09:46:09 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:51 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "spkt.h"
+
+/* \f S-TYPED-DATA.REQUEST */
+
+int STypedRequest (sd, data, cc, si)
+int sd;
+char *data;
+int cc;
+struct SSAPindication *si;
+{
+ SBV smask;
+ int result;
+ struct udvec uvs[2];
+ register struct udvec *uv = uvs;
+ register struct ssapblk *sb;
+
+ missingP (data);
+ if (cc <= 0)
+ return ssaplose (si, SC_PARAMETER, NULLCP,
+ "illegal value for TSSDU length (%d)", cc);
+ missingP (si);
+
+ smask = sigioblock ();
+
+ ssapPsig (sb, sd);
+
+ uv -> uv_base = data, uv -> uv_len = cc, uv++;
+ uv -> uv_base = NULL;
+
+ result = SDataRequestAux (sb, SPDU_TD, uvs, 1, 1, si);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
--- /dev/null
+/* ssapwrite.c - SPM: write various SPDUs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/ssapwrite.c,v 7.1 91/02/22 09:46:10 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/ssapwrite.c,v 7.1 91/02/22 09:46:10 mrose Interim $
+ *
+ *
+ * $Log: ssapwrite.c,v $
+ * Revision 7.1 91/02/22 09:46:10 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:52 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+
+/* \f */
+
+int SWriteRequestAux (sb, code, data, cc, type, ssn, settings,
+ id, oid, ref, si)
+register struct ssapblk *sb;
+int code;
+char *data;
+int cc,
+ type,
+ settings;
+long ssn;
+struct SSAPactid *id,
+ *oid;
+struct SSAPref *ref;
+struct SSAPindication *si;
+{
+ int result;
+ register struct ssapkt *s,
+ *p;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+ struct udvec uvs[3];
+ register struct udvec *uv;
+
+ if (sb -> sb_flags & SB_EXPD)
+ switch (code) {
+ case SPDU_MAA:
+ result = PR_MAA;
+ goto send_pr;
+
+ case SPDU_AI:
+ case SPDU_AD:
+ case SPDU_RS:
+ result = PR_RS;
+ goto send_pr;
+
+ case SPDU_AIA:
+ case SPDU_ADA:
+ case SPDU_RA:
+ result = PR_RA;
+ send_pr: ;
+ if ((p = newspkt (SPDU_PR)) == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ p -> s_mask |= SMASK_PR_TYPE;
+ p -> s_pr_type = result;
+ result = spkt2sd (p, sb -> sb_fd, 1, si);
+ freespkt (p);
+ if (result == NOTOK)
+ return NOTOK;
+ break;
+
+ default:
+ break;
+ }
+
+ uv = uvs;
+ uvs[0].uv_base = uvs[1].uv_base = NULL;
+
+ switch (code) {
+ case SPDU_MAP:
+ case SPDU_MIP:
+ case SPDU_RS:
+ case SPDU_AS:
+ case SPDU_AR:
+ case SPDU_AD:
+ case SPDU_AI:
+#ifdef notdef /* aka SPDU_MAP */
+ case SPDU_AE:
+#endif
+ case SPDU_CD:
+ if (s = newspkt (SPDU_GT))
+ s -> s_mask |= SMASK_SPDU_GT;
+ break;
+
+ default:
+ s = newspkt (SPDU_PT);
+ break;
+ }
+ if (s == NULL)
+ return ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+
+ if (spkt2tsdu (s, &uv -> uv_base, &uv -> uv_len) == NOTOK) {
+ (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+ goto out1;
+ }
+ freespkt (s);
+ uv++;
+
+ if ((s = newspkt (code)) == NULL) {
+ (void) ssaplose (si, SC_CONGEST, NULLCP, "out of memory");
+ goto out2;
+ }
+ switch (code) {
+ case SPDU_MAP:
+ if (type) {
+ s -> s_mask |= SMASK_MAP_SYNC;
+ s -> s_map_sync = type;
+ }
+ s -> s_mask |= SMASK_MAP_SERIAL;
+ s -> s_map_serial = ssn;
+ break;
+
+ case SPDU_MAA:
+ s -> s_mask |= SMASK_MAA_SERIAL;
+ s -> s_maa_serial = ssn;
+ break;
+
+ case SPDU_MIP:
+ if (type == SYNC_NOCONFIRM) {
+ s -> s_mask |= SMASK_MIP_SYNC;
+ s -> s_mip_sync = MIP_SYNC_NOEXPL;
+ }
+ s -> s_mask |= SMASK_MIP_SERIAL;
+ s -> s_mip_serial = ssn;
+ break;
+
+ case SPDU_MIA:
+ s -> s_mask |= SMASK_MIA_SERIAL;
+ s -> s_mia_serial = ssn;
+ break;
+
+ case SPDU_RS:
+ if (sb -> sb_requirements & SR_TOKENS) {
+ s -> s_mask |= SMASK_RS_SET;
+ s -> s_rs_settings = settings;
+ }
+ s -> s_mask |= SMASK_RS_TYPE;
+ s -> s_rs_type = type;
+ s -> s_mask |= SMASK_RS_SSN;
+ s -> s_rs_serial = ssn;
+ break;
+
+ case SPDU_RA:
+ if (sb -> sb_requirements & SR_TOKENS) {
+ s -> s_mask |= SMASK_RA_SET;
+ s -> s_ra_settings = settings;
+ }
+ s -> s_mask |= SMASK_RA_SSN;
+ s -> s_ra_serial = ssn;
+ break;
+
+ case SPDU_AS:
+ s -> s_mask |= SMASK_AS_ID;
+ s -> s_as_id = *id; /* struct copy */
+ break;
+
+ case SPDU_AR:
+ s -> s_mask |= SMASK_AR_OID | SMASK_AR_SSN | SMASK_AR_ID;
+ s -> s_ar_oid = *oid; /* struct copy */
+ s -> s_ar_serial = ssn;
+ s -> s_ar_id = *id; /* struct copy */
+ if (ref) {
+ s -> s_mask |= SMASK_AR_REF;
+ s -> s_ar_reference = *ref; /* struct copy */
+ }
+ break;
+
+ case SPDU_AI:
+ s -> s_mask |= SMASK_AI_REASON;
+ s -> s_ai_reason = type;
+ break;
+
+ case SPDU_AD:
+ s -> s_mask |= SMASK_AD_REASON;
+ s -> s_ad_reason = type;
+ break;
+
+ case SPDU_ED:
+ s -> s_mask |= SMASK_ED_REASON;
+ s -> s_ed_reason = type;
+ break;
+
+ default:
+ break;
+ }
+
+ if (cc > 0) {
+ s -> s_mask |= SMASK_UDATA_PGI;
+ s -> s_udata = data, s -> s_ulen = cc;
+ }
+ else
+ s -> s_udata = NULL, s -> s_ulen = 0;
+ result = spkt2tsdu (s, &uv -> uv_base, &uv -> uv_len);
+ s -> s_mask &= ~SMASK_UDATA_PGI;
+ s -> s_udata = NULL, s -> s_ulen = 0;
+
+ if (result == NOTOK) {
+ (void) ssaplose (si, s -> s_errno, NULLCP, NULLCP);
+ goto out3;
+ }
+ freespkt (s);
+ uv++;
+
+ uv -> uv_base = NULL;
+
+ if ((result = TWriteRequest (sb -> sb_fd, uvs, td)) == NOTOK)
+ (void) ts2sslose (si, "TWriteRequest", td);
+
+ free (uvs[0].uv_base);
+ free (uvs[1].uv_base);
+
+ return result;
+
+out3: ;
+ if (uvs[1].uv_base)
+ free (uvs[1].uv_base);
+out2: ;
+ if (uvs[0].uv_base)
+ free (uvs[0].uv_base);
+out1: ;
+ freespkt (s);
+
+ return NOTOK;
+}
--- /dev/null
+/* str2spkt.c - read/write a SPDU thru a string */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/str2spkt.c,v 7.1 91/02/22 09:46:12 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/str2spkt.c,v 7.1 91/02/22 09:46:12 mrose Interim $
+ *
+ *
+ * $Log: str2spkt.c,v $
+ * Revision 7.1 91/02/22 09:46:12 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:53 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f */
+
+char *spkt2str (s)
+struct ssapkt *s;
+{
+ int i,
+ len;
+ char *base,
+ *dp;
+ static char buffer[(CONNECT_MAX + BUFSIZ) * 2 + 1];
+
+ if (spkt2tsdu (s, &base, &len) == NOTOK)
+ return NULLCP;
+ if (s -> s_udata)
+ switch (s -> s_code) {
+ case SPDU_DT:
+ if (s -> s_mask & SMASK_SPDU_GT)
+ break; /* else fall */
+ case SPDU_EX:
+ case SPDU_TD:
+ if ((dp = realloc (base, (unsigned) (i = len + s -> s_ulen)))
+ == NULL) {
+ free (base);
+ return NULLCP;
+ }
+ bcopy (s -> s_udata, (base = dp) + len, s -> s_ulen);
+ len = i;
+ break;
+
+ default:
+ break;
+ }
+
+ buffer[explode (buffer, (u_char *) base, len)] = NULL;
+ if (len > 0)
+ free (base);
+
+#ifdef DEBUG
+ if (ssap_log -> ll_events & LLOG_PDUS) {
+ LLOG (ssap_log, LLOG_PDUS,
+ ("write %d bytes, \"%s\"", strlen (buffer), buffer));
+ spkt2text (ssap_log, s, 0);
+ }
+#endif
+
+ return buffer;
+}
+
+/* \f */
+
+struct ssapkt *str2spkt (buffer)
+char *buffer;
+{
+ int cc;
+ char packet[CONNECT_MAX + BUFSIZ];
+ register struct ssapkt *s;
+ struct qbuf qbs;
+ register struct qbuf *qb = &qbs,
+ *qp;
+
+ bzero ((char *) qb, sizeof *qb);
+ qb -> qb_forw = qb -> qb_back = qb;
+
+ cc = implode ((u_char *) packet, buffer, strlen (buffer));
+ if ((qp = (struct qbuf *) malloc (sizeof *qp + (unsigned) cc)) == NULL)
+ s = NULLSPKT;
+ else {
+ bcopy (packet, qp -> qb_data = qp -> qb_base, qp -> qb_len = cc);
+ insque (qp, qb -> qb_back);
+ s = tsdu2spkt (qb, cc, NULLIP);
+ QBFREE (qb);
+ }
+
+#ifdef DEBUG
+ if (ssap_log -> ll_events & LLOG_PDUS) {
+ LLOG (ssap_log, LLOG_PDUS,
+ ("read %d bytes, \"%s\"", strlen (buffer), buffer));
+ spkt2text (ssap_log, s, 1);
+ }
+#endif
+
+ return s;
+}
--- /dev/null
+/* text2spkt.c - read/write a SPDU thru a debug filter */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/text2spkt.c,v 7.1 91/02/22 09:46:13 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/text2spkt.c,v 7.1 91/02/22 09:46:13 mrose Interim $
+ *
+ *
+ * $Log: text2spkt.c,v $
+ * Revision 7.1 91/02/22 09:46:13 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:54 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+#include "logger.h"
+
+
+#define sprintc(v,b) sprintb ((int) (v), (b))
+
+/* \f */
+
+#define SPDU_TYPE(e) (void) ll_printf (lp, "%sCODE/ %s\n", rw, e)
+
+#define DMASK "\020\01RELEASE\02USER\03PROTOCOL\04UNKNOWN"
+#define EMASK "\020\01BEGIN\02END"
+#define OMASK "\020\01EXTD"
+#define RMASK \
+ "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+#define SMASK "\020\01NOEND"
+#define TMASK "\020\01DATA\03SYNC\05ACTIVITY\07RELEASE"
+#define YMASK "\020\01NOEXPLICIT"
+
+
+
+void spkt2text (lp, s, read)
+register LLog *lp;
+register struct ssapkt *s;
+int read;
+{
+ char *rw = read ? "<--- " : "---> ";
+
+ LLOG (lp, LLOG_ALL,
+ ("dump of SPDU 0x%x, errno=0x%x mask=0x%x%s",
+ s, s -> s_errno, s -> s_mask,
+ s -> s_mask & SMASK_SPDU_EXPD ? " (expedited)" : ""));
+ (void) ll_printf (lp, "%s(\n", rw);
+
+ (void) ll_printf (lp, "%sLI/ %d\n", rw, s -> s_li);
+
+ switch (s -> s_code) {
+ case SPDU_CN:
+ case SPDU_AC:
+ SPDU_TYPE (s -> s_code == SPDU_CN ? "CONNECT" : "ACCEPT");
+ if (s -> s_mask & SMASK_CN_REF)
+ type_ref (lp, rw, &s -> s_cn_reference);
+ if (s -> s_mask & SMASK_CN_OPT)
+ type_bits (lp, rw, "OPTIONS", s -> s_options, CR_OPT_MASK,
+ OMASK);
+ if (s -> s_mask & SMASK_CN_TSDU)
+ type_tsdu (lp, rw, s -> s_tsdu_init, s -> s_tsdu_resp);
+ if (s -> s_mask & SMASK_CN_VRSN)
+ type_vrsn (lp, rw, s -> s_cn_version);
+ if (s -> s_mask & SMASK_CN_ISN)
+ type_ssn (lp, rw, "ISN", s -> s_isn);
+ if (s -> s_mask & SMASK_CN_SET)
+ type_settings (lp, rw, s -> s_settings);
+ if (s -> s_code == SPDU_AC && (s -> s_mask & SMASK_AC_TOKEN))
+ type_bits (lp, rw, "TOKENS", s -> s_ac_token, -1, TMASK);
+ if (s -> s_mask & SMASK_CN_REQ)
+ type_bits (lp, rw, "REQUIREMENTS", s -> s_cn_require,
+ -1, RMASK);
+ if (s -> s_mask & SMASK_CN_CALLING)
+ type_id (lp, "CALLING", rw, s -> s_calling, s -> s_callinglen);
+ if (s -> s_mask & SMASK_CN_CALLED)
+ type_id (lp, "CALLED", rw, s -> s_called, s -> s_calledlen);
+ break;
+
+ case SPDU_RF:
+ SPDU_TYPE ("REFUSE");
+ if (s -> s_mask & SMASK_RF_REF)
+ type_ref (lp, rw, &s -> s_rf_reference);
+ if (s -> s_mask & SMASK_RF_DISC)
+ type_bits (lp, rw, "DISCONNECT", s -> s_rf_disconnect,
+ RF_DISC_MASK, DMASK);
+ if (s -> s_mask & SMASK_RF_REQ)
+ type_bits (lp, rw, "REQUIREMENTS", s -> s_rf_require,
+ -1, RMASK);
+ if (s -> s_mask & SMASK_RF_VRSN)
+ type_vrsn (lp, rw, s -> s_rf_version);
+ if (s -> s_rlen > 0) {
+ type_reason (lp, rw, *s -> s_rdata & 0xff);
+ if (s -> s_rlen > 1)
+ type_data (lp, "REASON", rw, s -> s_rlen - 1,
+ s -> s_rdata + 1);
+ }
+ break;
+
+ case SPDU_FN:
+ SPDU_TYPE ("FINISH");
+ if (s -> s_mask & SMASK_FN_DISC)
+ type_bits (lp, rw, "DISCONNECT", s -> s_fn_disconnect,
+ FN_DISC_MASK, DMASK);
+ break;
+
+ case SPDU_DN:
+ SPDU_TYPE ("DISCONNECT");
+ break;
+
+ case SPDU_NF:
+ SPDU_TYPE ("NOT FINISHED");
+ break;
+
+ case SPDU_AB:
+#ifdef notdef
+ case SPDU_AI: /* aka SPDU_AB */
+#endif
+ if (s -> s_mask & SMASK_SPDU_AB) {
+ SPDU_TYPE ("ABORT");
+ if (s -> s_mask & SMASK_AB_DISC)
+ type_bits (lp, rw, "DISCONNECT", s -> s_ab_disconnect,
+ AB_DISC_MASK, DMASK);
+ if (s -> s_mask & SMASK_AB_REFL)
+ type_data (lp, "REFLECT", rw, sizeof s -> s_reflect,
+ (char *) s -> s_reflect);
+ break;
+ }
+ SPDU_TYPE ("ACTIVITY INTERRUPT");
+ if (s -> s_mask & SMASK_AI_REASON)
+ type_error (lp, rw, s -> s_ai_reason);
+ break;
+
+ case SPDU_AA:
+#ifdef notdef
+ case SPDU_AIA: /* aka SPDU_AA */
+#endif
+ if (s -> s_mask & SMASK_SPDU_AA)
+ SPDU_TYPE ("ABORT ACCEPT");
+ else
+ SPDU_TYPE ("ACTIVITY INTERRUPT ACK");
+ break;
+
+ case SPDU_GT:
+#ifdef notdef
+ case SPDU_DT: /* aka SPDU_GT */
+#endif
+ if (s -> s_mask & SMASK_SPDU_GT) {
+ SPDU_TYPE ("GIVE TOKENS");
+ if (s -> s_mask & SMASK_GT_TOKEN)
+ type_bits (lp, rw, "TOKENS", s -> s_gt_token, -1, TMASK);
+ }
+ else
+ SPDU_TYPE ("DATA TRANSFER");
+ break;
+
+ case SPDU_EX:
+ SPDU_TYPE ("EXPEDITED");
+ break;
+
+ case SPDU_TD:
+ SPDU_TYPE ("TYPED DATA");
+ break;
+
+ case SPDU_CD:
+ SPDU_TYPE ("CAPABILITY DATA");
+ break;
+
+ case SPDU_CDA:
+ SPDU_TYPE ("CAPABILITY DATA ACK");
+ break;
+
+ case SPDU_PT:
+ SPDU_TYPE ("PLEASE TOKENS");
+ if (s -> s_mask & SMASK_PT_TOKEN)
+ type_bits (lp, rw, "TOKENS", s -> s_pt_token, -1, TMASK);
+ break;
+
+ case SPDU_GTC:
+ SPDU_TYPE ("GIVE TOKENS CONFIRM");
+ break;
+
+ case SPDU_GTA:
+ SPDU_TYPE ("GIVE TOKENS ACK");
+ break;
+
+ case SPDU_MIP:
+ SPDU_TYPE ("MINOR SYNCHRONIZATION POINT");
+ if (s -> s_mask & SMASK_MIP_SYNC)
+ type_bits (lp, rw, "SYNC", s -> s_mip_sync, MIP_SYNC_MASK,
+ YMASK);
+ if (s -> s_mask & SMASK_MIP_SERIAL)
+ type_ssn (lp, rw, "SSN", s -> s_mip_serial);
+ break;
+
+ case SPDU_MIA:
+ SPDU_TYPE ("MINOR SYNC ACK");
+ if (s -> s_mask & SMASK_MIA_SERIAL)
+ type_ssn (lp, rw, "SSN", s -> s_mia_serial);
+ break;
+
+ case SPDU_MAP:
+#ifdef notdef
+ case SPDU_AE: /* aka SPDU_MAP */
+#endif
+ if ((s -> s_mask & SMASK_MAP_SYNC)
+ && (s -> s_map_sync & MAP_SYNC_NOEND)) {
+ SPDU_TYPE ("MAJOR SYNCHRONIZATION POINT");
+ type_bits (lp, rw, "SYNC", s -> s_map_sync, MAP_SYNC_MASK,
+ SMASK);
+ }
+ else
+ SPDU_TYPE ("ACTIVITY END");
+ if (s -> s_mask & SMASK_MAP_SERIAL)
+ type_ssn (lp, rw, "SSN", s -> s_map_serial);
+ break;
+
+ case SPDU_MAA:
+#ifdef notdef
+ case SPDU_AEA: /* aka SPDU_MAA */
+#endif
+ SPDU_TYPE ("MAJOR SYNC/ACTIVITY END ACK");
+ if (s -> s_mask & SMASK_MAA_SERIAL)
+ type_ssn (lp, rw, "SSN", s -> s_maa_serial);
+ break;
+
+ case SPDU_RS:
+ SPDU_TYPE ("RESYNCHRONIZE");
+ if (s -> s_mask & SMASK_RS_SET)
+ type_settings (lp, rw, s -> s_rs_settings);
+ if (s -> s_mask & SMASK_RS_TYPE)
+ type_resync (lp, rw, s -> s_rs_type);
+ if (s -> s_mask & SMASK_RS_SSN)
+ type_ssn (lp, rw, "RSN", s -> s_rs_serial);
+ break;
+
+ case SPDU_RA:
+ SPDU_TYPE ("RESYNCHRONIZE ACK");
+ if (s -> s_mask & SMASK_RA_SET)
+ type_settings (lp, rw, s -> s_ra_settings);
+ if (s -> s_mask & SMASK_RA_SSN)
+ type_ssn (lp, rw, "RSN", s -> s_ra_serial);
+ break;
+
+ case SPDU_PR:
+ SPDU_TYPE ("PREPARE");
+ type_prepare (lp, rw, s -> s_pr_type);
+ break;
+
+ case SPDU_ER:
+ SPDU_TYPE ("EXCEPTION REPORT");
+ break;
+
+ case SPDU_ED:
+ SPDU_TYPE ("EXCEPTION DATA");
+ if (s -> s_mask & SMASK_ED_REASON)
+ type_error (lp, rw, s -> s_ed_reason);
+ break;
+
+ case SPDU_AS:
+ SPDU_TYPE ("ACTIVITY START");
+ if (s -> s_mask & SMASK_AS_ID) {
+ (void) ll_printf (lp, "%s", rw);
+ type_info (lp, "ID/ %d", (int) s -> s_as_id.sd_len,
+ s -> s_as_id.sd_data);
+ (void) ll_printf (lp, "\n");
+ }
+ break;
+
+ case SPDU_AR:
+ SPDU_TYPE ("ACTIVITY RESUME");
+ if (s -> s_mask & SMASK_AR_REF)
+ type_ref (lp, rw, &s -> s_ar_reference);
+ if (s -> s_mask & SMASK_AR_OID) {
+ (void) ll_printf (lp, "%s", rw);
+ type_info (lp, "OLD ID/ %d", (int) s -> s_ar_oid.sd_len,
+ s -> s_ar_oid.sd_data);
+ (void) ll_printf (lp, "\n");
+ }
+ if (s -> s_mask & SMASK_AR_SSN)
+ type_ssn (lp, rw, "SSN", s -> s_ar_serial);
+ if (s -> s_mask & SMASK_AR_ID) {
+ (void) ll_printf (lp, "%s", rw);
+ type_info (lp, "ID/ %d", (int) s -> s_ar_id.sd_len,
+ s -> s_ar_id.sd_data);
+ (void) ll_printf (lp, "\n");
+ }
+ break;
+
+ case SPDU_AD:
+ SPDU_TYPE ("ACTIVITY DISCARD");
+ if (s -> s_mask & SMASK_AD_REASON)
+ type_error (lp, rw, s -> s_ad_reason);
+ break;
+
+ case SPDU_ADA:
+ SPDU_TYPE ("ACTIVITY DISCARD ACK");
+ break;
+
+ default:
+ (void) ll_printf (lp, "%sCODE/ 0x%x\n", rw, s -> s_code);
+ break;
+ }
+
+ if (s -> s_mask & SMASK_ENCLOSE)
+ type_bits (lp, rw, "ENCLOSURE", s -> s_enclose, ENCL_MASK, EMASK);
+
+ if (s -> s_udata)
+ if (s -> s_code == SPDU_ER)
+ type_data (lp, "REFLECT", rw, s -> s_ulen, s -> s_udata);
+ else
+ if (s -> s_mask & SMASK_UDATA_PGI)
+ type_data (lp, "USER", rw, s -> s_ulen, s -> s_udata);
+ else {
+ (void) ll_printf (lp, "%sUSER INFO/ ", rw);
+ type_info (lp, "%d", s -> s_ulen, s -> s_udata);
+ (void) ll_printf (lp, "\n");
+ }
+ (void) ll_printf (lp, "%s)\n", rw);
+
+ (void) ll_sync (lp);
+}
+
+/* \f */
+
+static type_id (lp, type, rw, selector, len)
+LLog *lp;
+char *type,
+ *rw;
+char *selector;
+int len;
+{
+ char buffer[BUFSIZ];
+
+ buffer[explode (buffer, (u_char *) selector, len)] = NULL;
+
+ (void) ll_printf (lp, "%s%s/ %d/\"%s\"\n", rw, type, len, buffer);
+}
+
+
+static type_ssn (lp, rw, what, ssn)
+LLog *lp;
+char *rw,
+ *what;
+u_long ssn;
+{
+ (void) ll_printf (lp, "%s%s/ %d\n", rw, what, ssn);
+}
+
+
+static type_bits (lp, rw, s, bits, mask, t)
+LLog *lp;
+char *rw,
+ *s,
+ *t;
+u_char bits,
+ mask;
+{
+ (void) ll_printf (lp, "%s%s/ %s", rw, s, sprintc (bits & mask, t));
+ if (bits & ~mask)
+ (void) ll_printf (lp, ": illegal use of %s", sprintc (bits & ~mask, t));
+ (void) ll_printf (lp, "\n");
+}
+
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ token = (settings >> shift) & ST_MASK; \
+ (void) ll_printf (lp, " %s:%s", type, token == ST_INIT_VALUE ? "initiator" \
+ : token == ST_RESP_VALUE ? "responder" \
+ : token == ST_CALL_VALUE ? "choice" \
+ : "reserved"); \
+}
+
+static type_settings (lp, rw, settings)
+LLog *lp;
+char *rw;
+u_char settings;
+{
+ int token;
+
+ (void) ll_printf (lp, "%sSETTINGS/", rw);
+ dotokens ();
+ (void) ll_printf (lp, "\n");
+}
+
+#undef dotoken
+
+
+static type_tsdu (lp, rw, init, resp)
+LLog *lp;
+char *rw;
+u_short init,
+ resp;
+{
+ (void) ll_printf (lp, "%sTSDU/ INITIATOR: %d, RESPONDER: %d\n",
+ rw, init, resp);
+}
+
+
+static type_ref (lp, rw, ref)
+LLog *lp;
+char *rw;
+struct SSAPref *ref;
+{
+ (void) ll_printf (lp, "%sREFERENCE/", rw);
+ if (ref -> sr_vlen)
+ type_info (lp, "<CALLING %d", (int) ref -> sr_calling_len,
+ ref -> sr_calling);
+ else
+ type_info (lp, " <USER %d", (int) ref -> sr_ulen, ref -> sr_udata);
+ type_info (lp, ", COMMON %d", (int) ref -> sr_clen, ref -> sr_cdata);
+ type_info (lp, ", ADDITIONAL %d", (int) ref -> sr_alen, ref -> sr_adata);
+ if (ref -> sr_vlen)
+ type_info (lp, ", CALLED %d", (int) ref -> sr_called_len,
+ ref -> sr_called);
+ (void) ll_printf (lp, ">\n");
+}
+
+
+static type_vrsn (lp, rw, version)
+LLog *lp;
+char *rw;
+u_char version;
+{
+ (void) ll_printf (lp, "%sVERSION/ 0x%x\n", rw, version);
+}
+
+
+static type_reason (lp, rw, reason)
+LLog *lp;
+char *rw;
+int reason;
+{
+ (void) ll_printf (lp, "%sREASON/ 0x%x: %s\n", rw, reason,
+ SErrString ((int) reason));
+}
+
+
+static type_prepare (lp, rw, type)
+LLog *lp;
+char *rw;
+u_char type;
+{
+ (void) ll_printf (lp, "%sTYPE/ ", rw);
+ switch (type) {
+ case PR_MAA:
+ (void) ll_printf (lp, "MAA");
+ break;
+ case PR_RS:
+ (void) ll_printf (lp, "RS");
+ break;
+ case PR_RA:
+ (void) ll_printf (lp, "RA");
+ break;
+ case PR_AB:
+ (void) ll_printf (lp, "AB");
+ break;
+ default:
+ (void) ll_printf (lp, "%d: illegal value", type);
+ break;
+ }
+ (void) ll_printf (lp, "\n");
+}
+
+
+static type_error (lp, rw, reason)
+LLog *lp;
+char *rw;
+u_char reason;
+{
+ (void) ll_printf (lp, "%sREASON/ ", rw);
+ switch (reason) {
+ case SP_NOREASON:
+ (void) ll_printf (lp, "No specific reason stated");
+ break;
+ case SP_JEOPARDY:
+ (void) ll_printf (lp, "User receiving ability jeopardized");
+ break;
+ case SP_SEQUENCE:
+ (void) ll_printf (lp, "User sequence error");
+ break;
+ case SP_LOCAL:
+ (void) ll_printf (lp, "Local SS-user error");
+ break;
+ case SP_PROCEDURAL:
+ (void) ll_printf (lp, "Unrecoverable procedural error");
+ break;
+ case SP_DEMAND:
+ (void) ll_printf (lp, "Demand data token");
+ break;
+ default:
+ (void) ll_printf (lp, "%d: illegal value", reason);
+ break;
+ }
+ (void) ll_printf (lp, "\n");
+}
+
+
+static type_resync (lp, rw, type)
+LLog *lp;
+char *rw;
+u_char type;
+{
+ (void) ll_printf (lp, "%sTYPE/ ", rw);
+ switch (type) {
+ case SYNC_RESTART:
+ (void) ll_printf (lp, "restart");
+ break;
+ case SYNC_ABANDON:
+ (void) ll_printf (lp, "abandon");
+ break;
+ case SYNC_SET:
+ (void) ll_printf (lp, "set");
+ break;
+ default:
+ (void) ll_printf (lp, "%d: illegal value", type);
+ break;
+ }
+ (void) ll_printf (lp, "\n");
+}
+
+
+static type_data (lp, type, rw, len, data)
+LLog *lp;
+char *type,
+ *rw,
+ *data;
+int len;
+{
+ (void) ll_printf (lp, "%s%s DATA/ ", rw, type);
+ type_info (lp, "%d", len, data);
+ (void) ll_printf (lp, "\n");
+}
+
+
+static type_info (lp, fmt, len, data)
+LLog *lp;
+char *fmt,
+ *data;
+int len;
+{
+ char buffer[BUFSIZ];
+
+ (void) ll_printf (lp, fmt, len);
+ if (0 < len && len < sizeof buffer / 2) {
+ buffer[explode (buffer, (u_char *) data, len)] = NULL;
+ (void) ll_printf (lp, " %s", buffer);
+ }
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+void text2spkt (s)
+struct ssapkt *s;
+{
+ /* NOT YET IMPLEMENTED */
+}
--- /dev/null
+/* tsdu2spkt.c - read/write a SPDU to a TSDU */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.1 91/02/22 09:46:14 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/ssap/RCS/tsdu2spkt.c,v 7.1 91/02/22 09:46:14 mrose Interim $
+ *
+ *
+ * $Log: tsdu2spkt.c,v $
+ * Revision 7.1 91/02/22 09:46:14 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:25:55 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "spkt.h"
+#include "tailor.h"
+
+/* \f */
+
+struct local_buf {
+ char *top; /* Top of buffer */
+ char *ptr; /* Pointer to working buffer */
+ int pgi; /* Offset of last PGI li */
+ int left; /* Number of bytes left */
+ int li; /* Running spdu length */
+ int allocli; /* Allocated li */
+ int len; /* Current buffer size */
+};
+
+/* \f */
+
+#define PMASK_NODATA 0x000000
+#define PMASK_CN_ID 0x000001 /* 1: Connection ID */
+#define PMASK_CN_ITEMS 0x000002 /* 5: Connect/Accept Item */
+#define PMASK_SYNC 0x000004 /* 15: Sync Type Item */
+#define PMASK_TOKEN 0x000008 /* 16: Token Item */
+#define PMASK_TDISC 0x000010 /* 17: Transport Disc */
+#define PMASK_USER_REQ 0x000020 /* 20: Session User Req */
+#define PMASK_VERSION 0x000040 /* 22: Version Number */
+#define PMASK_PREPARE 0x000080 /* 24: Prepare type */
+#define PMASK_ENCLOSE 0x000100 /* 25: Enclosure Item */
+#define PMASK_TOKEN_SET 0x000200 /* 26: Token Setting Item */
+#define PMASK_RESYNC 0x000400 /* 27: Resync type */
+#define PMASK_LINK 0x000800 /* 33: Linking information */
+#define PMASK_ACT_ID 0x001000 /* 41: Activity ID */
+#define PMASK_SERIAL 0x002000 /* 42: Serial Number */
+#define PMASK_MIA_DATA 0x004000 /* 46: MIA User Data */
+#define PMASK_REFLECT 0x008000 /* 49: Reflect parameter */
+#define PMASK_REASON 0x010000 /* 50: Refusal Reason */
+#define PMASK_SSAP_CALLING 0x020000 /* 51: Calling SSAP ID */
+#define PMASK_SSAP_CALLED 0x040000 /* 52: Called SSAP ID */
+#define PMASK_UDATA 0x080000 /* 193: User data */
+#define PMASK_XDATA 0x100000 /* 194: Extended user data */
+
+#define PMASK_VARLEN 0x800000 /* PI is Variable Len */
+#define PMASK_NOTSUPPORTED -1 /* Type not supported */
+
+
+static int si_table[] = {
+ PMASK_REFLECT, /* 0x00: SPDU_ER */
+ PMASK_ENCLOSE /* 0x01: SPDU_GT & SPDU_DT */
+ | PMASK_TOKEN,
+ PMASK_TOKEN /* 0x02: SPDU_PT */
+ | PMASK_ENCLOSE
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x03 */
+ PMASK_NOTSUPPORTED, /* 0x04 */
+ PMASK_NODATA, /* 0x05: SPDU_EX */
+ PMASK_NOTSUPPORTED, /* 0x06 */
+ PMASK_PREPARE, /* 0x07: SPDU_PR */
+ PMASK_ENCLOSE /* 0x08: SPDU_NF */
+ | PMASK_UDATA,
+ PMASK_TDISC /* 0x09: SPDU_FN */
+ | PMASK_ENCLOSE
+ | PMASK_UDATA,
+ PMASK_ENCLOSE /* 0x0a: SPDU_DN */
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x0b */
+ PMASK_CN_ID /* 0x0c: SPDU_RF */
+ | PMASK_TDISC
+ | PMASK_USER_REQ
+ | PMASK_VERSION
+ | PMASK_ENCLOSE
+ | PMASK_REASON,
+ PMASK_CN_ID /* 0x0d: SPDU_CN */
+ | PMASK_CN_ITEMS
+ | PMASK_USER_REQ
+ | PMASK_VERSION
+ | PMASK_SSAP_CALLING
+ | PMASK_SSAP_CALLED
+ | PMASK_UDATA
+ | PMASK_XDATA,
+ PMASK_CN_ID /* 0x0e: SPDU_AC */
+ | PMASK_CN_ITEMS
+ | PMASK_USER_REQ
+ | PMASK_VERSION
+ | PMASK_SSAP_CALLING
+ | PMASK_TOKEN
+ | PMASK_ENCLOSE
+ | PMASK_SSAP_CALLED
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x0f */
+ PMASK_NOTSUPPORTED, /* 0x10 */
+ PMASK_NOTSUPPORTED, /* 0x11 */
+ PMASK_NOTSUPPORTED, /* 0x12 */
+ PMASK_NOTSUPPORTED, /* 0x13 */
+ PMASK_NOTSUPPORTED, /* 0x14 */
+ PMASK_NODATA, /* 0x15: SPDU_GTC */
+ PMASK_NODATA, /* 0x16: SPDU_GTA */
+ PMASK_NOTSUPPORTED, /* 0x17 */
+ PMASK_NOTSUPPORTED, /* 0x18 */
+ PMASK_TDISC /* 0x19: SPDU_AB & SPDU_AI */
+ | PMASK_REFLECT
+ | PMASK_REASON
+ | PMASK_ENCLOSE
+ | PMASK_UDATA,
+ PMASK_NODATA, /* 0x1a: SPDU_AA & SPDU_AIA */
+ PMASK_NOTSUPPORTED, /* 0x1b */
+ PMASK_NOTSUPPORTED, /* 0x1c */
+ PMASK_LINK /* 0x1d: SPDU_AR */
+ | PMASK_ACT_ID
+ | PMASK_ENCLOSE
+ | PMASK_SERIAL
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x1e */
+ PMASK_NOTSUPPORTED, /* 0x1f */
+ PMASK_NOTSUPPORTED, /* 0x20 */
+ PMASK_ENCLOSE, /* 0x21: SPDU_TD */
+ PMASK_TOKEN_SET /* 0x22: SPDU_RA */
+ | PMASK_ENCLOSE
+ | PMASK_SERIAL
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x23 */
+ PMASK_NOTSUPPORTED, /* 0x24 */
+ PMASK_NOTSUPPORTED, /* 0x25 */
+ PMASK_NOTSUPPORTED, /* 0x26 */
+ PMASK_NOTSUPPORTED, /* 0x27 */
+ PMASK_NOTSUPPORTED, /* 0x28 */
+ PMASK_SYNC /* 0x29: SPDU_MAP & SPDU_AE */
+ | PMASK_ENCLOSE
+ | PMASK_SERIAL
+ | PMASK_UDATA,
+ PMASK_ENCLOSE /* 0x2a: SPDU_MAA & SPDU_AEA */
+ | PMASK_SERIAL
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x2b */
+ PMASK_NOTSUPPORTED, /* 0x2c */
+ PMASK_ENCLOSE /* 0x2d: SPDU_AS */
+ | PMASK_ACT_ID
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x2e */
+ PMASK_NOTSUPPORTED, /* 0x2f */
+ PMASK_ENCLOSE /* 0x30: SPDU_ED */
+ | PMASK_REASON
+ | PMASK_UDATA,
+ PMASK_SYNC /* 0x31: SPDU_MIP */
+ | PMASK_ENCLOSE
+ | PMASK_SERIAL
+ | PMASK_UDATA,
+ PMASK_ENCLOSE /* 0x32: SPDU_MIA */
+ | PMASK_SERIAL
+ | PMASK_MIA_DATA,
+ PMASK_NOTSUPPORTED, /* 0x33 */
+ PMASK_NOTSUPPORTED, /* 0x34 */
+ PMASK_TOKEN_SET /* 0x35: SPDU_RS */
+ | PMASK_ENCLOSE
+ | PMASK_RESYNC
+ | PMASK_SERIAL
+ | PMASK_UDATA,
+ PMASK_NOTSUPPORTED, /* 0x36 */
+ PMASK_NOTSUPPORTED, /* 0x37 */
+ PMASK_NOTSUPPORTED, /* 0x38 */
+ PMASK_REASON, /* 0x39: SPDU_AD */
+ PMASK_NODATA, /* 0x3a: SPDU_ADA */
+ PMASK_NOTSUPPORTED, /* 0x3b */
+ PMASK_NOTSUPPORTED, /* 0x3c */
+ PMASK_ENCLOSE /* 0x3d: SPDU_CD */
+ | PMASK_UDATA,
+ PMASK_ENCLOSE /* 0x3e: SPDU_CDA */
+ | PMASK_UDATA
+};
+#define SI_TABLE_LEN ((sizeof si_table) / (sizeof si_table[0]))
+
+/* \f */
+
+#define PGI_CN_ID 1
+#define PI_CALLED_SS 9
+#define PI_CALLING_SS 10
+#define PI_COMMON_REF 11
+#define PI_ADD_INFO 12
+#define PGI_CN_ITEMS 5
+#define PI_PROTOCOL_OPT 19
+#define PI_TSDU_MAXSIZ 21
+#define PI_VERSION 22
+#define PI_ISN 23
+#define PI_TOKEN_SET 26
+#define PI_ISN2 55
+#define PI_SYNC 15
+#define PI_TOKEN 16
+#define PI_TDISC 17
+#define PI_USER_REQ 20
+#define PI_PREPARE 24
+#define PI_ENCLOSE 25
+#define PI_RESYNC 27
+#define PGI_AR_LINK 33
+#define PI_AR_CALLED 9
+#define PI_AR_CALLING 10
+#define PI_AR_COMMON 11
+#define PI_AR_ADDT 12
+#define PI_AR_OLD 41
+#define PI_AR_SERIAL 42
+#define PI_ACT_ID 41
+#define PI_SERIAL 42
+#define PI_MIA_DATA 46
+#define PI_REFLECT 49
+#define PI_REASON 50
+#define PI_SSAP_CALLING 51
+#define PI_SSAP_CALLED 52
+#define PI_UDATA 193
+#define PI_XDATA 194
+
+
+static int pi_table[] = {
+ 0, /* 0x00 */
+ PMASK_VARLEN | PMASK_CN_ID, /* 0x01: Connection ID */
+ 0, 0, 0, /* 0x02-04 */
+ PMASK_VARLEN | PMASK_CN_ITEMS, /* 0x05: Connect/Accept Item */
+ 0, 0, 0, /* 0x06-08 */
+ PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x09: Called Session SS */
+ PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0a: Calling Session SS */
+ PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0b: Common Reference */
+ PMASK_VARLEN | PMASK_CN_ID | PMASK_LINK,/* 0x0c: Additional Info */
+ 0, 0, /* 0x0d-0e */
+ PMASK_SYNC, /* 0x0f: Sync Type Item */
+ PMASK_TOKEN, /* 0x10: Token Item */
+ PMASK_TDISC, /* 0x11: Transport Disc */
+ 0, /* 0x12 */
+ PMASK_CN_ITEMS, /* 0x13: Protocol Option */
+ PMASK_USER_REQ, /* 0x14: Session User Req */
+ PMASK_VARLEN | PMASK_CN_ITEMS, /* 0x15: TSDU Max Size */
+ PMASK_VERSION, /* 0x16: Version Number */
+ PMASK_VARLEN | PMASK_CN_ITEMS, /* 0x17: Initial Serial Num */
+ PMASK_PREPARE, /* 0x18: Prepare Type */
+ PMASK_ENCLOSE, /* 0x19: Enclosure Item */
+ PMASK_CN_ITEMS | PMASK_TOKEN_SET, /* 0x1a: Token setting item */
+ PMASK_RESYNC, /* 0x1b: Resync type */
+ 0, 0, 0, 0, 0, /* 0x1c-20 */
+ PMASK_VARLEN | PMASK_LINK, /* 0x21: Activity Link */
+ 0, 0, 0, 0, 0, 0, 0, /* 0x22-28 */
+ PMASK_VARLEN | PMASK_ACT_ID, /* 0x29: Activity ID */
+ PMASK_VARLEN | PMASK_SERIAL, /* 0x2a: Serial Number */
+ 0, 0, 0, /* 0x2b-2d */
+ PMASK_VARLEN | PMASK_MIA_DATA, /* 0x2e: MIA User Data */
+ 0, 0, /* 0x2f-30 */
+ PMASK_VARLEN | PMASK_REFLECT, /* 0x31: Reflect parameter */
+ PMASK_VARLEN | PMASK_REASON, /* 0x32: Refusal Reason */
+ PMASK_VARLEN | PMASK_SSAP_CALLING, /* 0x33: Calling SSAP ID */
+ PMASK_VARLEN | PMASK_SSAP_CALLED, /* 0x34: Called SSAP ID */
+ 0, 0, /* 0x35-36 */
+ PMASK_VARLEN | PMASK_CN_ITEMS /* 0x17: 2nd initial s/n */
+};
+#define PI_TABLE_LEN ((sizeof pi_table) / (sizeof pi_table[0]))
+
+/* \f */
+
+static int pi_length[PI_TABLE_LEN] = {
+ 0, /* 0x00 */
+ SREF_USER_SIZE /* 0x01: Connection ID */
+ + SREF_COMM_SIZE
+ + SREF_ADDT_SIZE
+ + 6,
+ 0, 0, 0, /* 0x02-04 */
+ 1 + 4 + 1 + 6 + 1 + 10, /* 0x05: Connect/Accept Item */
+ 0, 0, 0, /* 0x06-08 */
+ SREF_USER_SIZE, /* 0x09: Called Session SS */
+ SREF_USER_SIZE, /* 0x0a: Calling Session SS */
+ SREF_COMM_SIZE, /* 0x0b: Common Reference */
+ SREF_ADDT_SIZE, /* 0x0c: Additional Info */
+ 0, 0, /* 0x0d-0e */
+ 1, /* 0x0f: Sync Type Item */
+ 1, /* 0x10: Token Item */
+ 1, /* 0x11: Transport Disc */
+ 0, /* 0x12 */
+ 1, /* 0x13: Protocol Option */
+ 2, /* 0x14: Session User Req */
+ 4, /* 0x15: TSDU Max Size */
+ 1, /* 0x16: Version Number */
+ SIZE_CN_ISN, /* 0x17: Initial Serial Num */
+ 1, /* 0x18: Prepare Type */
+ 1, /* 0x19: Enclosure Item */
+ 1, /* 0x1a: Token setting item */
+ 1, /* 0x1b: Resync type */
+ 0, 0, 0, 0, 0, /* 0x1c-20 */
+ 2 * SREF_USER_SIZE /* 0x21: Activity Link */
+ + SREF_COMM_SIZE
+ + SREF_ADDT_SIZE
+ + SID_DATA_SIZE
+ + SIZE_CN_ISN
+ + 6 * 2,
+ 0, 0, 0, 0, 0, 0, 0, /* 0x22-28 */
+ SID_DATA_SIZE, /* 0x29: Activity ID */
+ SIZE_CN_ISN, /* 0x2a: Serial Number */
+ 0, 0, 0, /* 0x2b-2d */
+ SEGMENT_MAX /* MIA_SIZE */, /* 0x2e: MIA User Data */
+ 0, 0, /* 0x2f-30 */
+ SEGMENT_MAX, /* 0x31: Reflect parameter */
+ RF_SIZE, /* 0x32: Refusal Reason */
+ SSSIZE, /* 0x33: Calling SSAP ID */
+ SSSIZE, /* 0x34: Called SSAP ID */
+ 0, 0, /* 0x35-36 */
+ SIZE_CN_ISN, /* 0x37: 2nd initial s/n */
+};
+
+/* \f */
+
+#define If_Set(flag) if (s -> s_mask & (flag))
+#define If_Reset(flag) if (!(s -> s_mask & (flag)))
+#define Set(flag) s -> s_mask |= (flag)
+#define Reset(flag) s -> s_mask &= ~(flag)
+
+#define Put_Item(code,value) \
+ put2spdu((code), pi_length[(code)], (value), &c)
+
+#define Put_Ref(r,code) \
+{ \
+ start_pgi (PGI_CN_ID, &c); \
+ if (r.sr_ulen) \
+ put2spdu (code, (int) r.sr_ulen, r.sr_udata, &c); \
+ if (r.sr_clen) \
+ put2spdu (PI_COMMON_REF, (int) r.sr_clen, r.sr_cdata, &c); \
+ if (r.sr_alen) \
+ put2spdu (PI_ADD_INFO, (int) r.sr_alen, r.sr_adata, &c); \
+ end_pgi (&c); \
+}
+
+#define Put_SSN(code,ssn) \
+{ \
+ if ((ssn) > SERIAL_MAX + 1) { \
+ if (c.len) \
+ free (c.top); \
+ s -> s_errno = SC_PROTOCOL; \
+ return NOTOK; \
+ } \
+ (void) sprintf (isn, "%lu", (ssn)); \
+ put2spdu ((code), strlen (isn), isn, &c); \
+}
+
+/* this used to check
+
+ if (s -> s_ulen > (csize)) {
+ if (c.len)
+ free (c.top);
+ s -> s_errno = SC_PROTOCOL;
+ return NOTOK;
+ }
+
+ but with version 2 session, there's really no point... */
+
+#define Put_UData(csize) \
+{ \
+ if (s -> s_udata) { \
+ put2spdu (PI_UDATA, s -> s_ulen, s -> s_udata, &c); \
+ } \
+}
+
+#define Put_XData(csize) \
+{ \
+ if (s -> s_udata) { \
+ put2spdu (s -> s_ulen > csize ? PI_XDATA : PI_UDATA, s -> s_ulen, \
+ s -> s_udata, &c); \
+ } \
+}
+
+#define Put_MData(csize) \
+{ \
+ if (s -> s_udata) { \
+ put2spdu (PI_MIA_DATA, s -> s_ulen, s -> s_udata, &c); \
+ } \
+}
+
+/* \f */
+
+static start_spdu (s, c, basesize)
+struct ssapkt *s;
+struct local_buf *c;
+int basesize;
+{
+ if (s -> s_udata)
+ switch (s -> s_code) {
+ case SPDU_DT: /* caller responsible for this... */
+ case SPDU_EX:
+ case SPDU_TD:
+ break;
+
+ default:
+ if (s -> s_ulen)
+ basesize += s -> s_ulen + (s -> s_ulen > 254 ? 4 : 2);
+ break;
+ }
+
+ switch (s -> s_code) {
+ case SPDU_CN:
+ case SPDU_AC:
+ If_Set (SMASK_CN_REF) {
+ basesize += 2;
+ if (s -> s_cn_reference.sr_ulen)
+ basesize += 2 + s -> s_cn_reference.sr_ulen;
+ if (s -> s_cn_reference.sr_clen)
+ basesize += 2 + s -> s_cn_reference.sr_clen;
+ if (s -> s_cn_reference.sr_alen)
+ basesize += 2 + s -> s_cn_reference.sr_alen;
+ }
+ If_Set (SMASK_CN_CALLING)
+ basesize += s -> s_callinglen + 2;
+ If_Set (SMASK_CN_CALLED)
+ basesize += s -> s_calledlen + 2;
+ break;
+
+ case SPDU_RF:
+ If_Set (SMASK_RF_REF) {
+ basesize += 2;
+ if (s -> s_rf_reference.sr_ulen)
+ basesize += 2 + s -> s_rf_reference.sr_ulen;
+ if (s -> s_rf_reference.sr_clen)
+ basesize += 2 + s -> s_rf_reference.sr_clen;
+ if (s -> s_rf_reference.sr_alen)
+ basesize += 2 + s -> s_rf_reference.sr_alen;
+ }
+ break;
+
+ case SPDU_AR:
+ basesize += 2;
+ If_Set (SMASK_AR_REF) {
+ if (s -> s_ar_reference.sr_ulen)
+ basesize += 2 + s -> s_ar_reference.sr_ulen;
+ if (s -> s_ar_reference.sr_clen)
+ basesize += 2 + s -> s_ar_reference.sr_clen;
+ if (s -> s_ar_reference.sr_alen)
+ basesize += 2 + s -> s_ar_reference.sr_alen;
+ if (s -> s_ar_reference.sr_vlen)
+ basesize += 2 + s -> s_ar_reference.sr_vlen;
+ }
+ break;
+ }
+
+ if (basesize < 254)
+ basesize = 254;
+ c -> li = c -> pgi = 0;
+ c -> len = basesize + ((basesize > 254) ? 4 : 2);
+ if ((c -> top = malloc ((unsigned) c -> len)) == NULL) {
+ c -> len = 0;
+ s -> s_errno = SC_CONGEST;
+ }
+ else
+ s -> s_errno = SC_ACCEPT;
+ if ((c -> allocli = c -> left = basesize) > 254)
+ c -> ptr = c -> top + 4;
+ else
+ c -> ptr = c -> top + 2;
+}
+
+/* \f */
+
+static int end_spdu (code, c)
+unsigned char code;
+struct local_buf *c;
+{
+ if (c -> len) {
+ if (c -> allocli > 254) {
+ if (c -> li < 255) {
+ bcopy ((c -> top + 2), c -> top, (c -> len - c -> left));
+ *(c -> top + 1) = c -> li;
+ c -> len = c -> li + 2;
+ }
+ else {
+ *(c -> top + 1) = 255;
+ *(c -> top + 2) = (c -> li >> 8) & 0xff;
+ *(c -> top + 3) = c -> li & 0xff;
+ c -> len = c -> li + 4;
+ }
+ }
+ else {
+ *(c -> top + 1) = c -> li;
+ c -> len = c -> ptr - c -> top;
+ }
+ *c -> top = code;
+ return OK;
+ }
+
+ return NOTOK;
+}
+
+/* \f */
+
+static start_pgi (code, c)
+unsigned char code;
+struct local_buf *c;
+{
+ put2spdu ((int) code, 0, NULLCP, c);
+ if (c -> len)
+ c -> pgi = (c -> ptr - c -> top - 1);
+}
+
+
+static end_pgi (c)
+struct local_buf *c;
+{
+ if (c -> len)
+ *(c -> top + c -> pgi) = (c -> len - c -> left) - (c -> pgi + 1);
+}
+
+/* \f */
+
+static put2spdu (code, li, value, c)
+int code;
+int li;
+char *value;
+struct local_buf *c;
+{
+ int cl = li;
+ char *p1,
+ *p2;
+
+ if (c -> len) {
+ cl += (li < 255) ? 2 : 4;
+ if (c -> left >= cl)
+ c -> left -= cl;
+ else {
+/* XXX: this clause of Dwight's is all WRONG, WRONG, WRONG. I think we
+ should make start_spdu() smarter, if necessary and change this to
+
+ c -> len = 0;
+ return;
+*/
+ char *cp;
+
+ if (c -> allocli < 255)
+ cl += 2;
+ cp = realloc (c -> top, (unsigned) (c -> len += cl));
+ if (cp == NULL) {
+ c -> len = 0;
+ return;
+ }
+ c -> ptr = (c -> top = cp) + (c -> len - c -> left);
+ if (c -> allocli < 255) {
+ c -> allocli += cl;
+ cl = c -> len - c -> left + 2;
+ for (p1 = c -> ptr, p2 = p1 + 2; cl; cl--)
+ *p2-- = *p1--;
+ c -> pgi += 2;
+ c -> left -= 2;
+ }
+ }
+ *c -> ptr++ = code & 0xff;
+ if (li < 255) {
+ *c -> ptr++ = li;
+ c -> li += 2 + li;
+ }
+ else {
+ *c -> ptr++ = 255;
+ *c -> ptr++ = (li >> 8) & 0xff;
+ *c -> ptr++ = li & 0xff;
+ c -> li += 4 + li;
+ }
+
+ bcopy (value, c -> ptr, li);
+ c -> ptr += li;
+ }
+}
+
+/* \f */
+
+int spkt2tsdu (s, base, len)
+register struct ssapkt *s;
+char **base;
+int *len;
+{
+ struct local_buf c;
+ char isn[SIZE_CN_ISN + 1];
+
+ c.len = 0;
+ switch (s -> s_code) {
+ case SPDU_CN:
+ start_spdu (s, &c, CN_BASE_SIZE);
+ If_Set (SMASK_CN_REF)
+ Put_Ref (s -> s_cn_reference, PI_CALLING_SS);
+ If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN
+ | SMASK_CN_SET) {
+ start_pgi (PGI_CN_ITEMS, &c);
+ If_Set (SMASK_CN_OPT)
+ Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options);
+ If_Set (SMASK_CN_TSDU) {
+ u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16
+ | s -> s_tsdu_resp & 0xffff;
+ tsdu_maxsize = htonl (tsdu_maxsize);
+ Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize);
+ }
+ If_Set (SMASK_CN_VRSN)
+ Put_Item (PI_VERSION, (char *) &s -> s_cn_version);
+ If_Set (SMASK_CN_ISN)
+ Put_SSN (PI_ISN, s -> s_isn);
+ If_Set (SMASK_CN_SET)
+ Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings);
+ end_pgi (&c);
+ }
+ If_Set (SMASK_CN_REQ) {
+ u_short requirements = htons (s -> s_cn_require);
+ Put_Item (PI_USER_REQ, (char *) &requirements);
+ }
+ If_Set (SMASK_CN_CALLING)
+ put2spdu (PI_SSAP_CALLING, s -> s_callinglen,
+ s -> s_calling, &c);
+ If_Set (SMASK_CN_CALLED)
+ put2spdu (PI_SSAP_CALLED, s -> s_calledlen,
+ s -> s_called, &c);
+ Put_XData (CN_SIZE);
+ break;
+
+ case SPDU_AC:
+ start_spdu (s, &c, AC_BASE_SIZE);
+ If_Set (SMASK_CN_REF)
+ Put_Ref (s -> s_cn_reference, PI_CALLED_SS);
+ If_Set (SMASK_CN_OPT | SMASK_CN_TSDU | SMASK_CN_VRSN | SMASK_CN_ISN
+ | SMASK_CN_SET) {
+ start_pgi (PGI_CN_ITEMS, &c);
+ If_Set (SMASK_CN_OPT)
+ Put_Item (PI_PROTOCOL_OPT, (char *) &s -> s_options);
+ If_Set (SMASK_CN_TSDU) {
+ u_long tsdu_maxsize = (s -> s_tsdu_init & 0xffff) << 16
+ | s -> s_tsdu_resp & 0xffff;
+ tsdu_maxsize = htonl (tsdu_maxsize);
+ Put_Item (PI_TSDU_MAXSIZ, (char *) &tsdu_maxsize);
+ }
+ If_Set (SMASK_CN_VRSN)
+ Put_Item (PI_VERSION, (char *) &s -> s_cn_version);
+ If_Set (SMASK_CN_ISN)
+ Put_SSN (PI_ISN, s -> s_isn);
+ If_Set (SMASK_CN_SET)
+ Put_Item (PI_TOKEN_SET, (char *) &s -> s_settings);
+ end_pgi (&c);
+ }
+ If_Set (SMASK_AC_TOKEN)
+ Put_Item (PI_TOKEN, (char *) &s -> s_ac_token);
+ If_Set (SMASK_CN_REQ) {
+ u_short requirements = htons (s -> s_cn_require);
+ Put_Item (PI_USER_REQ, (char *) &requirements);
+ }
+ If_Set (SMASK_CN_CALLING)
+ put2spdu (PI_SSAP_CALLING, s -> s_callinglen,
+ s -> s_calling, &c);
+ If_Set (SMASK_CN_CALLED)
+ put2spdu (PI_SSAP_CALLED, s -> s_calledlen,
+ s -> s_called, &c);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (AC_SIZE);
+ break;
+
+ case SPDU_RF:
+ start_spdu (s, &c, RF_BASE_SIZE);
+ If_Set (SMASK_RF_REF)
+ Put_Ref (s -> s_rf_reference, PI_CALLED_SS);
+ If_Set (SMASK_RF_DISC)
+ Put_Item (PI_TDISC, (char *) &s -> s_rf_disconnect);
+ If_Set (SMASK_RF_REQ) {
+ u_short requirements = htons (s -> s_rf_require);
+ Put_Item (PI_USER_REQ, (char *) &requirements);
+ }
+ If_Set (SMASK_RF_VRSN)
+ Put_Item (PI_VERSION, (char *) &s -> s_rf_version);
+ if (s -> s_rlen > RF_SIZE) {
+ if (c.len)
+ free (c.top);
+ s -> s_errno = SC_PROTOCOL;
+ return NOTOK;
+ }
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ if (s -> s_rlen > 0)
+ put2spdu (PI_REASON, s -> s_rlen, s -> s_rdata, &c);
+ break;
+
+ case SPDU_FN:
+ start_spdu (s, &c, FN_BASE_SIZE);
+ If_Set (SMASK_FN_DISC)
+ Put_Item (PI_TDISC, (char *) &s -> s_fn_disconnect);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (FN_SIZE);
+ break;
+
+ case SPDU_DN:
+ start_spdu (s, &c, DN_BASE_SIZE);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (DN_SIZE);
+ break;
+
+ case SPDU_NF:
+ start_spdu (s, &c, NF_BASE_SIZE);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (NF_SIZE);
+ break;
+
+ case SPDU_AB:
+#ifdef notdef
+ case SPDU_AI: /* aka SPDU_AB */
+#endif
+ If_Set (SMASK_SPDU_AB) {
+ start_spdu (s, &c, AB_BASE_SIZE);
+ If_Reset (SMASK_AB_DISC) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_Item (PI_TDISC, (char *) &s -> s_ab_disconnect);
+ If_Set (SMASK_AB_REFL)
+ put2spdu (PI_REFLECT, AB_REFL_SIZE,
+ (char *) s -> s_reflect, &c);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (AB_SIZE);
+ break;
+ }
+ start_spdu (s, &c, AI_BASE_SIZE);
+ If_Set (SMASK_AI_REASON)
+ put2spdu (PI_REASON, 1, (char *) &s -> s_ai_reason, &c);
+ break;
+
+ case SPDU_AA:
+#ifdef notdef
+ case SPDU_AIA: /* aka SPDU_AA */
+#endif
+ If_Set (SMASK_SPDU_AA) {
+ start_spdu (s, &c, AA_BASE_SIZE);
+ break;
+ }
+ start_spdu (s, &c, AIA_BASE_SIZE);
+ break;
+
+ case SPDU_GT:
+#ifdef notdef
+ case SPDU_DT: /* aka SPDU_GT */
+#endif
+ If_Set (SMASK_SPDU_GT) {
+ start_spdu (s, &c, GT_BASE_SIZE);
+ If_Set (SMASK_GT_TOKEN)
+ Put_Item (PI_TOKEN, (char *) &s -> s_gt_token);
+ break;
+ } /* else fall */
+ start_spdu (s, &c, DT_BASE_SIZE);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+/* NB: caller responsible for mapping s -> s_udata to user info */
+ break;
+
+ case SPDU_TD:
+ start_spdu (s, &c, TD_BASE_SIZE);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+/* NB: caller responsible for mapping s -> s_udata to user info */
+ break;
+
+ case SPDU_EX:
+ start_spdu (s, &c, EX_BASE_SIZE);
+/* NB: caller responsible for mapping s -> s_udata to user info */
+ break;
+
+ case SPDU_CD:
+ start_spdu (s, &c, CD_BASE_SIZE);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (CD_SIZE);
+ break;
+
+ case SPDU_CDA:
+ start_spdu (s, &c, CDA_BASE_SIZE);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (CDA_SIZE);
+ break;
+
+ case SPDU_PT:
+ start_spdu (s, &c, PT_BASE_SIZE);
+ If_Set (SMASK_PT_TOKEN)
+ Put_Item (PI_TOKEN, (char *) &s -> s_pt_token);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (PT_SIZE);
+ break;
+
+ case SPDU_GTC:
+ start_spdu (s, &c, GTC_BASE_SIZE);
+ break;
+
+ case SPDU_GTA:
+ start_spdu (s, &c, GTA_BASE_SIZE);
+ break;
+
+ case SPDU_MIP:
+ start_spdu (s, &c, MIP_BASE_SIZE);
+ If_Set (SMASK_MIP_SYNC)
+ Put_Item (PI_SYNC, (char *) &s -> s_mip_sync);
+ If_Reset (SMASK_MIP_SERIAL) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_mip_serial);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (MIP_SIZE);
+ break;
+
+ case SPDU_MAP:
+#ifdef notdef
+ case SPDU_AE: /* aka SPDU_MAP */
+#endif
+ If_Set (SMASK_MAP_SYNC) {
+ start_spdu (s, &c, MAP_BASE_SIZE);
+ Put_Item (PI_SYNC, (char *) &s -> s_map_sync);
+ }
+ else
+ start_spdu (s, &c, AE_BASE_SIZE);
+ If_Reset (SMASK_MAP_SERIAL) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_map_serial);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (MAP_SIZE);
+ break;
+
+ case SPDU_MIA:
+ start_spdu (s, &c, MIA_BASE_SIZE);
+ If_Reset (SMASK_MIA_SERIAL) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_mia_serial);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_MData (MIA_SIZE);
+ break;
+
+ case SPDU_MAA:
+#ifdef notdef
+ case SPDU_AEA: /* aka SPDU_MAA */
+#endif
+ start_spdu (s, &c, MAA_BASE_SIZE);
+ If_Reset (SMASK_MAA_SERIAL) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_maa_serial);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (MAA_SIZE);
+ break;
+
+ case SPDU_RS:
+ start_spdu (s, &c, RS_BASE_SIZE);
+ If_Set (SMASK_RS_SET)
+ Put_Item (PI_TOKEN_SET, (char *) &s -> s_rs_settings);
+ If_Reset (SMASK_RS_TYPE) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_Item (PI_RESYNC, (char *) &s -> s_rs_type);
+ If_Reset (SMASK_RS_SSN) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_rs_serial);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (RS_SIZE);
+ break;
+
+ case SPDU_RA:
+ start_spdu (s, &c, RA_BASE_SIZE);
+ If_Set (SMASK_RA_SET)
+ Put_Item (PI_TOKEN_SET, (char *) &s -> s_ra_settings);
+ If_Reset (SMASK_RA_SSN) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_ra_serial);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (RA_SIZE);
+ break;
+
+ case SPDU_PR:
+ start_spdu (s, &c, PR_BASE_SIZE);
+ If_Reset (SMASK_PR_TYPE) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_Item (PI_PREPARE, (char *) &s -> s_pr_type);
+ break;
+
+ case SPDU_ER: /* we don't do these! */
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_ED:
+ start_spdu (s, &c, ED_BASE_SIZE);
+ If_Reset (SMASK_ED_REASON) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ put2spdu (PI_REASON, 1, (char *) &s -> s_ed_reason, &c);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (ED_SIZE);
+ break;
+
+ case SPDU_AS:
+ start_spdu (s, &c, AS_BASE_SIZE);
+ If_Reset (SMASK_AS_ID) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ put2spdu (PI_ACT_ID, (int) s -> s_as_id.sd_len,
+ s -> s_as_id.sd_data, &c);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (AS_SIZE);
+ break;
+
+ case SPDU_AR:
+ start_spdu (s, &c, AR_BASE_SIZE);
+ start_pgi (PGI_AR_LINK, &c);
+ If_Set (SMASK_AR_REF) {
+ if (s -> s_ar_reference.sr_called_len)
+ put2spdu (PI_AR_CALLED,
+ (int) s -> s_ar_reference.sr_called_len,
+ s -> s_ar_reference.sr_called, &c);
+ if (s -> s_ar_reference.sr_calling_len)
+ put2spdu (PI_AR_CALLING,
+ (int) s -> s_ar_reference.sr_calling_len,
+ s -> s_ar_reference.sr_calling, &c);
+ if (s -> s_ar_reference.sr_clen)
+ put2spdu (PI_AR_COMMON, (int) s -> s_ar_reference.sr_clen,
+ s -> s_ar_reference.sr_cdata, &c);
+ if (s -> s_ar_reference.sr_alen)
+ put2spdu (PI_AR_ADDT, (int) s -> s_ar_reference.sr_alen,
+ s -> s_ar_reference.sr_adata, &c);
+ }
+ If_Reset (SMASK_AR_OID) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ put2spdu (PI_ACT_ID, (int) s -> s_ar_oid.sd_len,
+ s -> s_ar_oid.sd_data, &c);
+ If_Reset (SMASK_AR_SSN) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ Put_SSN (PI_SERIAL, s -> s_ar_serial);
+ end_pgi (&c);
+ If_Reset (SMASK_AR_ID) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ put2spdu (PI_ACT_ID, (int) s -> s_ar_id.sd_len,
+ s -> s_ar_id.sd_data, &c);
+ If_Set (SMASK_ENCLOSE)
+ Put_Item (PI_ENCLOSE, (char *) &s -> s_enclose);
+ Put_UData (AR_SIZE);
+ break;
+
+ case SPDU_AD:
+ start_spdu (s, &c, AD_BASE_SIZE);
+ If_Set (SMASK_AD_REASON)
+ put2spdu (PI_REASON, 1, (char *) &s -> s_ad_reason, &c);
+ break;
+
+ case SPDU_ADA:
+ start_spdu (s, &c, ADA_BASE_SIZE);
+ break;
+
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+
+ if ((end_spdu (s -> s_code, &c) == NOTOK) || (s -> s_errno != SC_ACCEPT)) {
+ if (s -> s_errno == SC_ACCEPT)
+ s -> s_errno = SC_CONGEST;
+ if (c.len) {
+ free (c.top);
+ c.len = 0;
+ }
+ *base = NULL;
+ *len = 0;
+ }
+ else {
+ *base = c.top;
+ *len = c.len;
+ s -> s_li = c.li;
+ }
+
+#ifdef DEBUG
+ if (ssap_log -> ll_events & LLOG_PDUS)
+ spkt2text (ssap_log, s, 0);
+#endif
+
+ return c.len ? OK : NOTOK;
+}
+
+/* \f */
+
+static u_long str2ssn (s, n)
+register char *s;
+register int n;
+{
+ register u_long u;
+
+ for (u = 0L; n > 0; n--)
+ u = u * 10 + *s++ - '0';
+
+ return u;
+}
+
+/* \f */
+
+/* this is used to pull PCI, not user data... */
+
+#define advance(n) \
+ if (base >= xbase) { \
+ if ((base = pullqb (qb, (n))) == NULL) { \
+ s -> s_errno = SC_PROTOCOL; \
+ break; \
+ } \
+ xbase = base + (n); \
+ nread += (n); \
+ } \
+ else
+
+static char *pullqb (qb, n)
+struct qbuf *qb;
+int n;
+{
+ register int i;
+ int once;
+ register char *cp;
+ register struct qbuf *qp;
+ static char *buffer = NULL;
+
+ if (n > SEGMENT_MAX)
+ return NULLCP;
+
+ for (once = 1, cp = buffer, qp = NULL; n > 0; once = 0, cp += i, n -= i) {
+ if (qp == NULL && (qp = qb -> qb_forw) == qb)
+ return NULLCP;
+
+ i = min (qp -> qb_len, n);
+ if (once && i == n) { /* special case */
+ cp = qp -> qb_data;
+ qp -> qb_data += i, qp -> qb_len -= i;
+ return cp;
+ }
+
+ if (buffer == NULL) {
+ if ((buffer = malloc ((unsigned) SEGMENT_MAX)) == NULL)
+ return NULLCP;
+ cp = buffer;
+ }
+ bcopy (qp -> qb_data, cp, i);
+
+ qp -> qb_data += i, qp -> qb_len -= i;
+ if (qp -> qb_len <= 0) {
+ remque (qp);
+
+ free ((char *) qp);
+ qp = NULL;
+ }
+ }
+
+ return buffer;
+}
+
+/* \f */
+
+struct ssapkt *tsdu2spkt (qb, len, cc)
+struct qbuf *qb;
+int len,
+ *cc;
+{
+ register int li;
+ int cat0,
+ nread,
+ pktlen,
+ pgilen,
+ pmask,
+ xlen;
+ register char *base;
+ char *xbase;
+ unsigned char code,
+ si;
+ register struct ssapkt *s;
+
+ if (cc) {
+ cat0 = *cc;
+ *cc = 0;
+ }
+ else
+ cat0 = 1;
+ if ((base = pullqb (qb, nread = 2)) == NULL
+ || (s = newspkt ((int) (si = *base++))) == NULL)
+ return NULLSPKT;
+
+ if (*((u_char *) base) == 255) {
+ if ((base = pullqb (qb, 2)) == NULL) {
+ s -> s_errno = SC_PROTOCOL;
+ return s;
+ }
+ nread += 2;
+ s -> s_li =
+ (*((u_char *) base) << 8) + *((u_char *) (base + 1));
+ }
+ else
+ s -> s_li = *((u_char *) base);
+ pgilen = pktlen = s -> s_li;
+
+ if (cat0)
+ switch (si) {
+ case SPDU_GT:
+ Set (SMASK_SPDU_GT);
+ break;
+
+ case SPDU_AB:
+ Set (SMASK_SPDU_AB);
+ break;
+
+ case SPDU_AA:
+ Set (SMASK_SPDU_AA);
+ break;
+
+ default:
+ break;
+ }
+
+ if ((si >= SI_TABLE_LEN)
+ || ((pmask = si_table[si]) == PMASK_NOTSUPPORTED)) {
+ s -> s_errno = SC_PROTOCOL;
+ return s;
+ }
+ if (len < pktlen + nread) {
+ s -> s_errno = SC_PROTOCOL;
+ return s;
+ }
+
+ s -> s_errno = SC_ACCEPT;
+ xbase = base;
+ while (pktlen && (s -> s_errno == SC_ACCEPT)) {
+ advance (2);
+ code = *base++;
+ if (*((u_char *) base) == 255) {
+ base++;
+ advance (2);
+ li = (*((u_char *) base) << 8) + *((u_char *) (base + 1));
+ xlen = 2;
+ }
+ else {
+ li = *((u_char *) base);
+ xlen = 1;
+ }
+ base += xlen;
+ if (xlen > 1)
+ xlen += 2;
+ else
+ xlen++;
+ switch (code) {
+ case PI_UDATA:
+ if (!(pmask & PMASK_UDATA))
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case PI_XDATA:
+ if (!(pmask & PMASK_XDATA))
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ default:
+ if (code >= PI_TABLE_LEN || !(pmask & pi_table[code]))
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ if (s -> s_errno != SC_ACCEPT)
+ break;
+ if (!pgilen)
+ pgilen = pktlen;
+ pktlen -= (xlen + li);
+ if (li > (pgilen -= xlen)) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ pgilen -= li;
+ if (li)
+ advance (li);
+ if (code < PI_TABLE_LEN) {
+ if (li) {
+ if (pi_table[code] & PMASK_VARLEN) {
+ if (li > pi_length[code]) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ }
+ else
+ if (li != pi_length[code]) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ }
+ }
+
+ switch (code) {
+ case PGI_AR_LINK:
+ Set (SMASK_AR_OID);/* HACK! */
+ goto do_pgi;
+
+ case PGI_CN_ID:
+ Set (SMASK_CN_REF);/* fall */
+ case PGI_CN_ITEMS:
+do_pgi: ;
+ pktlen += li;
+ pgilen = li;
+ li = 0;
+ break;
+
+ case PI_CALLED_SS:
+ case PI_CALLING_SS:
+#ifdef notdef
+ case PI_AR_CALLED:
+ case PI_AR_CALLING:
+#endif
+ switch (si) {
+ case SPDU_CN:
+ case SPDU_AC:
+ s -> s_cn_reference.sr_ulen = li;
+ bcopy (base, s -> s_cn_reference.sr_udata, li);
+ Set (SMASK_CN_REF);
+ break;
+ case SPDU_RF:
+ s -> s_rf_reference.sr_ulen = li;
+ bcopy (base, s -> s_rf_reference.sr_udata, li);
+ Set (SMASK_RF_REF);
+ break;
+ case SPDU_AR:
+ switch (code) {
+ case PI_AR_CALLED:
+ s -> s_ar_reference.sr_called_len = li;
+ bcopy (base, s -> s_ar_reference.sr_called,
+ li);
+ Set (SMASK_AR_REF);
+ break;
+ case PI_AR_CALLING:
+ s -> s_ar_reference.sr_calling_len = li;
+ bcopy (base, s -> s_ar_reference.sr_calling,
+ li);
+ Set (SMASK_AR_REF);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ base += li;
+ break;
+
+ case PI_COMMON_REF:
+#ifdef notdef
+ case PI_AR_COMMON:
+#endif
+ switch (si) {
+ case SPDU_CN:
+ case SPDU_AC:
+ s -> s_cn_reference.sr_clen = li;
+ bcopy (base, s -> s_cn_reference.sr_cdata, li);
+ Set (SMASK_CN_REF);
+ break;
+ case SPDU_RF:
+ s -> s_rf_reference.sr_clen = li;
+ bcopy (base, s -> s_rf_reference.sr_cdata, li);
+ Set (SMASK_RF_REF);
+ break;
+ case SPDU_AR:
+ s -> s_ar_reference.sr_clen = li;
+ bcopy (base, s -> s_ar_reference.sr_cdata, li);
+ Set (SMASK_AR_REF);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ base += li;
+ break;
+
+ case PI_ADD_INFO:
+#ifdef notdef
+ case PI_AR_ADDT:
+#endif
+ switch (si) {
+ case SPDU_CN:
+ case SPDU_AC:
+ s -> s_cn_reference.sr_alen = li;
+ bcopy (base, s -> s_cn_reference.sr_adata, li);
+ Set (SMASK_CN_REF);
+ break;
+ case SPDU_RF:
+ s -> s_rf_reference.sr_alen = li;
+ bcopy (base, s -> s_rf_reference.sr_adata, li);
+ Set (SMASK_RF_REF);
+ break;
+ case SPDU_AR:
+ s -> s_ar_reference.sr_alen = li;
+ bcopy (base, s -> s_ar_reference.sr_adata, li);
+ Set (SMASK_AR_REF);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ base += li;
+ break;
+
+ case PI_PROTOCOL_OPT:
+ if ((s -> s_options = *base++) & ~CR_OPT_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_CN_OPT);
+ break;
+
+ case PI_TSDU_MAXSIZ:
+ {
+ u_long tsdu_maxsize;
+ bcopy (base, (char *) &tsdu_maxsize,
+ pi_length[PI_TSDU_MAXSIZ]);
+ tsdu_maxsize = ntohl (tsdu_maxsize);
+ s -> s_tsdu_init = (tsdu_maxsize >> 16) & 0xffff;
+ s -> s_tsdu_resp = tsdu_maxsize & 0xffff;
+ Set (SMASK_CN_TSDU);
+ }
+ base += pi_length[PI_TSDU_MAXSIZ];
+ break;
+
+ case PI_VERSION:
+ switch (si) {
+ case SPDU_CN:
+ case SPDU_AC:
+ s -> s_cn_version = *base++;
+ Set (SMASK_CN_VRSN);
+ break;
+ case SPDU_RF:
+ s -> s_rf_version = *base++;
+ Set (SMASK_RF_VRSN);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ break;
+
+ case PI_SYNC:
+ switch (si) {
+ case SPDU_MIP:
+ if ((s -> s_mip_sync = *base++) & ~MIP_SYNC_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_MIP_SYNC);
+ break;
+ case SPDU_MAP:
+ if ((s -> s_map_sync = *base++) & ~MAP_SYNC_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_MAP_SYNC);
+ break;
+ }
+ break;
+
+ case PI_TOKEN_SET:
+ switch (si) {
+ case SPDU_CN:
+ case SPDU_AC:
+ s -> s_settings = *base++;
+ Set (SMASK_CN_SET);
+ break;
+ case SPDU_RS:
+ s -> s_rs_settings = *base++;
+ Set (SMASK_RS_SET);
+ break;
+ case SPDU_RA:
+ s -> s_ra_settings = *base++;
+ Set (SMASK_RA_SET);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ break;
+
+ case PI_TOKEN:
+ switch (si) {
+ case SPDU_AC:
+ s -> s_ac_token = *base++;
+ Set (SMASK_AC_TOKEN);
+ break;
+ case SPDU_GT:
+ If_Reset (SMASK_SPDU_GT) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ s -> s_gt_token = *base++;
+ Set (SMASK_GT_TOKEN);
+ break;
+ case SPDU_PT:
+ s -> s_pt_token = *base++;
+ Set (SMASK_PT_TOKEN);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ break;
+
+ case PI_TDISC:
+ switch (si) {
+ case SPDU_RF:
+ if ((s -> s_rf_disconnect = *base++) & ~RF_DISC_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_RF_DISC);
+ break;
+ case SPDU_FN:
+ if ((s -> s_fn_disconnect = *base++) & ~FN_DISC_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_FN_DISC);
+ break;
+ case SPDU_AB:
+ If_Reset (SMASK_SPDU_AB) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ if ((s -> s_ab_disconnect = *base++) & ~AB_DISC_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_AB_DISC);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ break;
+
+ case PI_USER_REQ:
+ {
+ u_short requirements;
+ bcopy (base, (char *) &requirements, 2);
+ requirements = ntohs (requirements);
+ if (si != SPDU_RF) {
+ s -> s_cn_require = requirements;
+ Set (SMASK_CN_REQ);
+ }
+ else {
+ s -> s_rf_require = requirements;
+ Set (SMASK_RF_REQ);
+ }
+ }
+ base += 2;
+ break;
+
+ case PI_ISN:
+ switch (si) {
+ case SPDU_CN:
+ case SPDU_AC:
+ s -> s_isn = str2ssn (base, li);
+ Set (SMASK_CN_ISN);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ case PI_ISN2: /* not supported yet */
+ base += li;
+ break;
+
+ case PI_ENCLOSE:
+ if ((si == SPDU_DT && (s -> s_mask & SMASK_SPDU_GT))
+ || (si == SPDU_AI && !(s -> s_mask & SMASK_SPDU_AB))) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ if ((s -> s_enclose = *base++) & ~ENCL_MASK)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_ENCLOSE);
+ break;
+
+ case PI_RESYNC:
+ s -> s_rs_type = *base++;
+ if (SYNC_OK (s -> s_rs_type))
+ Set (SMASK_RS_TYPE);
+ else
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case PI_ACT_ID:
+ switch (si) {
+ case SPDU_AS:
+ s -> s_as_id.sd_len = li;
+ bcopy (base, s -> s_as_id.sd_data, li);
+ Set (SMASK_AS_ID);
+ break;
+
+ case SPDU_AR:
+ if ((s -> s_mask & SMASK_AR_OID)
+ && s -> s_ar_oid.sd_len == 0) {
+ s -> s_ar_oid.sd_len = li;
+ bcopy (base, s -> s_ar_oid.sd_data, li);
+ }
+ else {
+ s -> s_ar_id.sd_len = li;
+ bcopy (base, s -> s_ar_id.sd_data, li);
+ Set (SMASK_AR_ID);
+ }
+ break;
+
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ base += li;
+ break;
+
+ case PI_SERIAL:
+ switch (si) {
+ case SPDU_MIP:
+ s -> s_mip_serial = str2ssn (base, li);
+ Set (SMASK_MIP_SERIAL);
+ break;
+ case SPDU_MAP:
+ s -> s_map_serial = str2ssn (base, li);
+ Set (SMASK_MAP_SERIAL);
+ break;
+ case SPDU_MIA:
+ s -> s_mia_serial = str2ssn (base, li);
+ Set (SMASK_MIA_SERIAL);
+ break;
+ case SPDU_MAA:
+ s -> s_maa_serial = str2ssn (base, li);
+ Set (SMASK_MAA_SERIAL);
+ break;
+ case SPDU_RS:
+ s -> s_rs_serial = str2ssn (base, li);
+ Set (SMASK_RS_SSN);
+ break;
+ case SPDU_RA:
+ s -> s_ra_serial = str2ssn (base, li);
+ Set (SMASK_RA_SSN);
+ break;
+ case SPDU_AR:
+ s -> s_ar_serial = str2ssn (base, li);
+ Set (SMASK_AR_SSN);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ base += li;
+ break;
+
+ case PI_MIA_DATA:
+ case PI_UDATA:
+ case PI_XDATA:
+ Set (SMASK_UDATA_PGI);
+ if (!li)
+ break;
+ if (si == SPDU_AB && !(s -> s_mask & SMASK_SPDU_AB)) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ else
+ if (li > (code != PI_XDATA ? SEGMENT_MAX : CONNECT_MAX)) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));
+ if (s -> s_udata == NULL) {
+ s -> s_errno = SC_CONGEST;
+ break;
+ }
+ bcopy (base, s -> s_udata, li);
+ base += li;
+ break;
+
+ case PI_REASON:
+ switch (si) {
+ case SPDU_RF:
+ s -> s_rdata = malloc ((unsigned) (s -> s_rlen = li));
+ if (s -> s_rdata == NULL) {
+ s -> s_errno = SC_CONGEST;
+ break;
+ }
+ bcopy (base, s -> s_rdata, li);
+ base += li;
+ break;
+ case SPDU_ED:
+ s -> s_ed_reason = *base++;
+ if (li == 1 && SP_OK (s -> s_ed_reason))
+ Set (SMASK_ED_REASON);
+ else
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ case SPDU_AI:
+ If_Set (SMASK_SPDU_AB) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ s -> s_ai_reason = *base++;
+ if (li == 1 && SP_OK (s -> s_ai_reason))
+ Set (SMASK_AI_REASON);
+ else
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ case SPDU_AD:
+ s -> s_ad_reason = *base++;
+ if (li == 1 && SP_OK (s -> s_ad_reason))
+ Set (SMASK_AD_REASON);
+ else
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ break;
+
+ case PI_REFLECT:
+ switch (si) {
+ case SPDU_AB:
+ If_Reset (SMASK_SPDU_AB) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ if (li > AB_REFL_SIZE) {
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ bcopy (base, (char *) s -> s_reflect, li);
+ Set (SMASK_AB_REFL);
+ break;
+ case SPDU_ER:
+ s -> s_udata = malloc ((unsigned) (s -> s_ulen = li));
+ if (s -> s_udata == NULL) {
+ s -> s_errno = SC_CONGEST;
+ break;
+ }
+ bcopy (base, s -> s_udata, li);
+ break;
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ base += li;
+ break;
+
+ case PI_SSAP_CALLING:
+ bcopy (base, s -> s_calling, s -> s_callinglen = li);
+ Set (SMASK_CN_CALLING);
+ base += li;
+ break;
+
+ case PI_SSAP_CALLED:
+ bcopy (base, s -> s_called, s -> s_calledlen = li);
+ Set (SMASK_CN_CALLED);
+ base += li;
+ break;
+
+ case PI_PREPARE:
+ if ((s -> s_pr_type = *base++) > PR_MAX)
+ s -> s_errno = SC_PROTOCOL;
+ else
+ Set (SMASK_PR_TYPE);
+ break;
+
+ default:
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+ }
+/* NB: caller responsible for mapping user info to s -> s_qbuf */
+
+ if (cc)
+ *cc = nread;
+ { /* "dangling" qbuf */
+ register struct qbuf *qp;
+
+ if ((qp = qb -> qb_forw) != qb && qp -> qb_len <= 0) {
+ remque (qp);
+
+ free ((char *) qp);
+ }
+ }
+
+ switch (s -> s_code) {
+ case SPDU_AB:
+ If_Set (SMASK_SPDU_AB) {
+ If_Reset (SMASK_AB_DISC)
+ s -> s_errno = SC_PROTOCOL;
+ }
+ break;
+
+ case SPDU_MIP:
+ If_Reset (SMASK_MIP_SERIAL)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_MAP:
+ If_Reset (SMASK_MAP_SERIAL)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_MIA:
+ If_Reset (SMASK_MIA_SERIAL)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_MAA:
+ If_Reset (SMASK_MAA_SERIAL)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_RS:
+ If_Reset (SMASK_RS_TYPE)
+ s -> s_errno = SC_PROTOCOL;
+ If_Reset (SMASK_RS_SSN)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_RA:
+ If_Reset (SMASK_RA_SSN)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_PR:
+ If_Reset (SMASK_PR_TYPE)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_ED:
+ If_Reset (SMASK_ED_REASON)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_AS:
+ If_Reset (SMASK_AS_ID)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+
+ case SPDU_AR:
+ If_Reset (SMASK_AR_OID)
+ s -> s_errno = SC_PROTOCOL;
+ If_Reset (SMASK_AR_SSN)
+ s -> s_errno = SC_PROTOCOL;
+ If_Reset (SMASK_AR_ID)
+ s -> s_errno = SC_PROTOCOL;
+ break;
+ }
+
+#ifdef DEBUG
+ if (ssap_log -> ll_events & LLOG_PDUS)
+ spkt2text (ssap_log, s, 1);
+#endif
+
+ return s;
+}
+
+/* \f */
+
+struct ssapkt *newspkt (code)
+int code;
+{
+ register struct ssapkt *s;
+
+ s = (struct ssapkt *) calloc (1, sizeof *s);
+ if (s == NULL)
+ return NULL;
+
+ s -> s_code = code;
+ s -> s_qbuf.qb_forw = s -> s_qbuf.qb_back = &s -> s_qbuf;
+
+ return s;
+}
+
+
+int freespkt (s)
+register struct ssapkt *s;
+{
+ if (s == NULL)
+ return;
+
+ switch (s -> s_code) {
+ case SPDU_RF:
+ if (s -> s_rdata)
+ free (s -> s_rdata);/* and fall... */
+
+ default:
+ if (s -> s_udata)
+ free (s -> s_udata);
+ QBFREE (&s -> s_qbuf);
+ break;
+ }
+
+ free ((char *) s);
+}
--- /dev/null
+###############################################################################
+# Instructions to Make, for compilation of ISODE support processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/Makefile,v 7.10 91/02/22 09:46:19 mrose Interim $
+#
+#
+# $Log: Makefile,v $
+# Revision 7.10 91/02/22 09:46:19 mrose
+# Interim 6.8
+#
+# Revision 7.9 91/01/24 14:50:37 mrose
+# update
+#
+# Revision 7.8 90/12/23 18:43:17 mrose
+# update
+#
+# Revision 7.7 90/11/20 15:33:04 mrose
+# update
+#
+# Revision 7.6 90/11/04 19:16:46 mrose
+# update
+#
+# Revision 7.5 90/10/15 18:19:03 mrose
+# iaed
+# zap-AET
+#
+# Revision 7.4 90/08/14 14:30:30 mrose
+# oops
+#
+# Revision 7.3 90/07/27 08:48:06 mrose
+# update
+#
+# Revision 7.2 90/07/09 14:50:34 mrose
+# sync
+#
+# Revision 7.1 90/07/01 21:07:47 mrose
+# pepsy
+#
+# Revision 7.0 89/11/23 22:27:04 mrose
+# Release 6.0
+#
+###############################################################################
+
+###############################################################################
+#
+# NOTICE
+#
+# Acquisition, use, and distribution of this module and related
+# materials are subject to the restrictions of a license agreement.
+# Consult the Preface in the User's Manual for the full terms of
+# this agreement.
+#
+###############################################################################
+
+
+PEPYPATH= -DPEPYPATH
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+
+LIBES = $(TOPDIR)librosy.a $(TOPDIR)libronot.a $(TOPDIR)librosap.a \
+ $(TOPDIR)librtsap.a $(TOPDIR)libacsap.a $(TOPDIR)libpsap2.a \
+ $(TOPDIR)libpepy.a $(TOPDIR)libpepsy.a $(TOPDIR)libpsap.a \
+ $(TOPDIR)libssap.a $(TOPDIR)libtsap.a $(TOPDIR)libdirent.a \
+ $(TOPDIR)libcompat.a \
+ $(TP4LIBES)
+
+
+LLIBS = $(TOPDIR)llib-lrosy $(TOPDIR)llib-lronot $(TOPDIR)llib-lrosap \
+ $(TOPDIR)llib-lrtsap $(TOPDIR)llib-lacsap $(TOPDIR)llib-lpsap2 \
+ $(TOPDIR)llib-lpsap $(TOPDIR)llib-lssap $(TOPDIR)llib-ltsap \
+ $(TOPDIR)llib-ldirent $(TOPDIR)llib-lcompat $(TP4LLIBS)
+
+CFILES = tsapd.c isore.c isod.c isoc.c
+HFILES = $(HDIR)rosap.h $(HDIR)rtsap.h $(HDIR)acsap.h $(HDIR)psap2.h \
+ $(HDIR)psap.h $(HDIR)ssap.h $(HDIR)tsap.h \
+ $(HDIR)isoaddrs.h $(HDIR)isoservent.h \
+ $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all: libisode tsapd isore isod isoc \
+ isoaliases isoentities isomacros isobjects isoservices
+inst-all: inst-tsapd inst-isore inst-isod inst-isoc \
+ inst-libisode aliases entities macros objects services manuals
+install: inst-all clean
+lint: l-tsapd l-isore l-isod l-isoc
+
+all-lpp: lppd isoentities
+inst-lpp: inst-lppd entities macros objects services manuals-lpp
+install-lpp: inst-lpp clean
+lint-lpp: l-lppd
+
+inst-:;
+man-:;
+l-:;
+
+
+##################################################################
+# tsapd
+##################################################################
+
+inst-tsapd: $(SBINDIR)tsapd
+
+$(SBINDIR)tsapd: xtsapd
+ -cp $@ zxtsapd
+ -rm -f $@
+ cp xtsapd $@
+ -@ls -gls $@
+ -@echo ""
+
+tsapd: xtsapd
+
+xtsapd: tsapd.o $(LIBES)
+ $(LDCC) $(LDFLAGS) -o $@ tsapd.o $(LIBISODE) $(LSOCKET)
+
+l-tsapd:; $(LINT) $(LFLAGS) tsapd.c $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+tsapd.o: $(HFILES) $(HDIR)x25.h $(HDIR)logger.h $(HDIR)tailor.h
+
+
+inst-iaed: $(SBINDIR)iaed
+
+$(SBINDIR)iaed: xiaed
+ -cp $@ zxiaed
+ -rm -f $@
+ cp xiaed $@
+ -@ls -gls $@
+ -@echo ""
+
+iaed: xiaed
+
+xiaed: iaed.o $(TOPDIR)libdsap.a $(LIBES)
+ $(LDCC) $(LDFLAGS) -o $@ iaed.o \
+ $(LIBDSAP) $(LIBISODE) $(LSOCKET) $(LIBGDBM)
+
+iaed.o: $(HFILES) $(HDIR)x25.h $(HDIR)logger.h $(HDIR)tailor.h \
+ $(HDIR)quipu/util.h $(HDIR)quipu/config.h \
+ $(HDIR)quipu/bind.h $(HDIR)quipu/name.h \
+ $(HDIR)quipu/authen.h \
+ $(HDIR)quipu/list.h $(HDIR)quipu/commonarg.h \
+ $(HDIR)quipu/ds_error.h $(HDIR)quipu/dap.h \
+ $(HDIR)quipu/ds_search.h tsapd.c
+ $(CC) -o $@ $(CFLAGS) -DIAE -c tsapd.c
+
+l-iaed:; $(LINT) $(LFLAGS) -DIAE tsapd.c $(TOPDIR)llib-ldsap $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+man-iaed:; @$(UTILDIR)inst-man.sh $(MANOPTS) iaed.8c
+ -@echo ""
+
+##################################################################
+# isore
+##################################################################
+
+inst-isore: $(SBINDIR)isore
+
+$(SBINDIR)isore: xisore
+ -cp $@ zxisore
+ -rm -f $@
+ cp xisore $@
+ -@ls -gls $@
+ -@echo ""
+
+isore: xisore
+
+xisore: isore.o
+ $(LDCC) $(LDFLAGS) -o $@ isore.o $(TOPDIR)libcompat.a \
+ $(LSOCKET)
+
+l-isore:; $(LINT) $(LFLAGS) isore.c \
+ | grep -v "warning: possible pointer alignment problem"
+
+
+##################################################################
+# isod
+##################################################################
+
+inst-isod: $(SBINDIR)isod.tsap
+
+$(SBINDIR)isod.tsap: xisod
+ -cp $@ zxisod
+ -rm -f $@ \
+ $(SBINDIR)isod.ssap \
+ $(SBINDIR)isod.psap \
+ $(SBINDIR)isod.acsap \
+ $(SBINDIR)isod.rtsap \
+ $(SBINDIR)isod.rosap
+ cp xisod $@
+ -ln $@ $(SBINDIR)isod.ssap
+ -ln $@ $(SBINDIR)isod.psap
+ -ln $@ $(SBINDIR)isod.acsap
+ -ln $@ $(SBINDIR)isod.rtsap
+ -ln $@ $(SBINDIR)isod.rosap
+ -@ls -gls $@
+ -@echo ""
+
+isod: xisod
+
+xisod: isod.o $(LIBES)
+ $(LDCC) $(LDFLAGS) -o $@ isod.o $(LIBISODE) $(LSOCKET)
+
+l-isod:; $(LINT) $(LFLAGS) isod.c $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+isod.o: $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+
+
+##################################################################
+# isoc
+##################################################################
+
+inst-isoc: $(BINDIR)isoc
+
+$(BINDIR)isoc: xisoc
+ -cp $@ zxisoc
+ -rm -f $@
+ cp xisoc $@
+ -@ls -gls $@
+ -@echo ""
+
+isoc: xisoc
+
+xisoc: isoc.o $(LIBES)
+ $(LDCC) $(LDFLAGS) -o $@ isoc.o $(LIBISODE) $(LSOCKET)
+
+l-isoc:; $(LINT) $(LFLAGS) isoc.c $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+isoc.o: $(HFILES) $(HDIR)internet.h
+
+
+################################################################
+# libisode
+################################################################
+
+inst-libisode: $(LIBDIR)libisode.a $(LINTDIR)llib-lisode
+
+$(LIBDIR)libisode.a: libisode.a
+ @for i in libisode.* ;\
+ do \
+ rm -f $(LIBDIR)$$i; \
+ echo cp $$i $(LIBDIR)$$i; \
+ cp $$i $(LIBDIR)$$i; \
+ case "$$i" in *.a) \
+ $(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib ;;\
+ esac; \
+ ls -gls $(LIBDIR)$$i ; \
+ done
+ -@echo ""
+
+$(LINTDIR)llib-lisode: llib-lisode
+ -cp $@ zllib-lisode
+ -rm -f $@
+ sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+ < llib-lisode | \
+ sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+ @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+ -@ls -gls $@ $@.ln
+ -@echo ""
+
+libisode: libisode.a libisode-$(SHAREDLIB) llib-lisode
+
+libisode.a: isodevrsn.o
+ -rm -f $@ $(TOPDIR)libisode.a
+ -rm -rf tmp
+ -mkdir tmp
+ ln isodevrsn.o tmp
+ for i in $(LIBES); do (cd tmp; ar x ../$$i; \
+ ../$(UTILDIR)make-lib.sh -quick $(SYSTEM) $(ARFLAGS) ../$@ *.o; \
+ rm -f *); done
+ $(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+ -rm -rf tmp
+ -@rm -f $(TOPDIR)libisode.a
+ -@$(LN) $@ $(TOPDIR)libisode.a
+ -@ls -l $@
+ -@echo "ISODE library built normally"
+
+libisode-:;
+
+libisode-shared: isodevrsn.o
+ @rm -f libisode.so.* $(TOPDIR)libisode.so.*
+ @$(UTILDIR)make-lib.sh $(SYSTEM) -shared \
+ -major `cat version.major``cat version.minor` \
+ -minor `cat version.local` \
+ libisode.a
+ @for i in libisode.s[ao].* ;\
+ do \
+ rm -f $(TOPDIR)$$i; \
+ $(LN) $$i $(TOPDIR)$$i; \
+ ls -l $$i; \
+ done
+ @echo "shared ISODE library built normally"
+ @touch $@
+
+
+llib-lisode: $(LLIBS)
+ -@echo '/* llib-lisode - lint library for -lisode */' > $@
+ -@echo '' >> $@
+ cat $(LLIBS) >> $@
+ -@rm -f $(TOPDIR)llib-lisode
+ -@$(LN) llib-lisode $(TOPDIR)llib-lisode
+
+isodevrsn.c: $(LIBES)
+ @$(UTILDIR)version.sh isode > $@
+
+
+################################################################
+# aliases/entities/macros/objects/services/tailor
+################################################################
+
+aliases: $(ETCDIR)isoaliases
+
+$(ETCDIR)isoaliases: isoaliases
+ -cp $@ zisoaliases
+ cp isoaliases $@
+ -@ls -gls $@
+ -@echo ""
+
+isoaliases: aliases.local aliases.db
+ cat aliases.local aliases.db > $@
+
+
+entities: $(ETCDIR)isoentities
+
+$(ETCDIR)isoentities: isoentities
+ -cp $@ zisoentities
+ cp isoentities $@
+ -@ls -gls $@
+ -@if [ -f $(SBINDIR)aetbuild ]; then \
+ rm -f $(SBINDIR)aetbuild; \
+ rm -f $@.dir $@.pag; fi
+ -@echo ""
+
+isoentities: entities.prefix entities.local entities.db
+ cat entities.prefix entities.local entities.db > $@
+
+
+macros: $(ETCDIR)isomacros
+
+$(ETCDIR)isomacros: isomacros
+ -cp $@ zisomacros
+ cp isomacros $@
+ -@ls -gls $@
+ -@echo ""
+
+isomacros: macros.prefix macros.local macros.db
+ cat macros.prefix macros.local macros.db > $@
+
+
+objects: $(ETCDIR)isobjects
+
+$(ETCDIR)isobjects: isobjects
+ -cp $@ zisobjects
+ cp isobjects $@
+ -@ls -gls $@
+ -@echo ""
+
+isobjects: objects.local objects.db
+ cat objects.local objects.db > $@
+
+
+services: $(ETCDIR)isoservices
+
+$(ETCDIR)isoservices: isoservices
+ -cp $@ zisoservices
+ cp isoservices $@
+ -@ls -gls $@
+ -@echo ""
+
+isoservices: services.local services.db
+ cat services.local services.db > $@
+
+
+tailor: $(ETCDIR)isotailor
+
+$(ETCDIR)isotailor: isotailor
+ -cp $@ zisotailor
+ cp isotailor $@
+ -@ls -gls $@
+ -@echo ""
+
+
+################################################################
+# lppd
+################################################################
+
+LPP-LIBES= $(TOPDIR)libisode-lpp.a
+LPP-LLIBS= $(TOPDIR)llib-lisode-lpp
+
+inst-lppd: $(SBINDIR)lppd
+
+$(SBINDIR)lppd: xlppd
+ -cp $@ zxlppd
+ -rm -f $@
+ cp xlppd $@
+ -@ls -gls $@
+ -@echo ""
+
+lppd: xlppd
+
+xlppd: lppd.o $(LPP-LIBES)
+ $(LDCC) $(LDFLAGS) -o $@ lppd.o $(LPP-LIBES) $(LSOCKET)
+
+l-lppd:; $(LINT) $(LFLAGS) lppd.c $(LPP-LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+lppd.o: $(HFILES)
+
+
+MANUALS-LPP= isoentities.5 isobjects.5 isoservices.5 isotailor.5 lppd.8c
+
+manuals-lpp:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS-LPP)
+ -@echo ""
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS = isoc.1c isoaliases.5 isoentities.5 isomacros.5 isobjects.5 \
+ isoservices.5 isotailor.5 tsapd.8c isore.8c isod.8c
+
+manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+ -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:; rm -f *.o *.a *.so.* x* z* _* core isodevrsn.c llib-lisode \
+ isoaliases isoentities isomacros isobjects isoservices \
+ libisode-shared
+
+grind: isoaliases isoentities isomacros isobjects isoservices \
+ isotailor true
+ iprint Makefile isoaliases isoentities isomacros isobjects \
+ isoservices isotailor
+ tgrind -lc $(CFILES)
+ @echo $(MANUALS) | \
+ tr " " "\012" | \
+ sed -e "s%.*%itroff -man &%" | \
+ sh -ve
+
+true:;
+
+
+################################################################
+# testing...
+################################################################
+
+HOST = localhost
+FILE1 = /etc/mount
+FILE2 = /etc/fstab
+
+
+test:; -xisoc $(HOST) tsap echo < $(FILE1)
+ -xisoc $(HOST) ssap echo < $(FILE1)
+ -xisoc $(HOST) psap echo < $(FILE1)
+ -xisoc $(HOST) psap isode/echo < $(FILE1)
+ -xisoc $(HOST) rtsap echo < $(FILE1)
+ -xisoc $(HOST) rtsap ros_echo < $(FILE1)
+ -xisoc $(HOST) rtsap "isode/rtse echo" < $(FILE1)
+ -xisoc $(HOST) rtsap isode/ros_echo < $(FILE1)
+ -xisoc $(HOST) rosap echo < $(FILE1)
+ -xisoc $(HOST) rosap isode/echo < $(FILE1)
+ -xisoc $(HOST) tsap sink < $(FILE1)
+ -xisoc $(HOST) ssap sink < $(FILE1)
+ -xisoc $(HOST) psap sink < $(FILE1)
+ -xisoc $(HOST) psap isode/sink < $(FILE1)
+ -xisoc $(HOST) rtsap sink < $(FILE1)
+ -xisoc $(HOST) rtsap ros_sink < $(FILE1)
+ -xisoc $(HOST) rtsap "isode/rtse sink" < $(FILE1)
+ -xisoc $(HOST) rtsap isode/ros_sink < $(FILE1)
+ -xisoc $(HOST) rosap sink < $(FILE1)
+ -xisoc $(HOST) rosap isode/sink < $(FILE1)
+ -cat $(FILE2) | xisoc $(HOST) tsap echo
+ -cat $(FILE2) | xisoc $(HOST) ssap echo
+ -cat $(FILE2) | xisoc $(HOST) psap echo
+ -cat $(FILE2) | xisoc $(HOST) psap isode/echo
+ -cat $(FILE2) | xisoc $(HOST) rtsap echo
+ -cat $(FILE2) | xisoc $(HOST) rtsap ros_echo
+ -cat $(FILE2) | xisoc $(HOST) rtsap "isode/rtse echo"
+ -cat $(FILE2) | xisoc $(HOST) rtsap isode/ros_echo
+ -cat $(FILE2) | xisoc $(HOST) rosap echo
+ -cat $(FILE2) | xisoc $(HOST) rosap isode/echo
--- /dev/null
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/aliases.db,v 7.3 91/02/22 09:46:20 mrose Interim $
+#
+#
+# $Log: aliases.db,v $
+# Revision 7.3 91/02/22 09:46:20 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/07/09 14:50:37 mrose
+# sync
+#
+# Revision 7.1 89/12/06 17:29:37 mrose
+# update
+#
+# Revision 7.0 89/11/23 22:27:07 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+# Performance Systems International
+psi "performance systems international, us"
+
+# University College London
+ucl "university college london, gb"
+hubris "hubris, cs, university college london, gb"
+dir "c=GB@o=University College London@cn=Dir"
--- /dev/null
+#!/bin/sh
+
+: assumptions
+: 1. we are bound as the manager
+: 2. we are positioned at the right part of the DIT
+
+if [ "x$1" != "x" ]; then
+ S="$1"
+ shift
+else
+ S=services
+fi
+
+echo "\
+transport echo! #128! ! isod.tsap
+transport sink! #129! ! isod.tsap
+file service! #259! iso ftam ! iso.ftam
+terminal service! #260! iso vt ! iso.vt
+isode echo! #512! ! isod.acsap
+isode rtse echo! #513! ! isod.rtsap -rtse
+isode ros_echo! #514! ! isod.rtsap -rtse -rose
+isode sink! #515! ! isod.acsap
+isode rtse sink! #516! ! isod.rtsap -rtse
+isode ros_sink! #517! ! isod.rtsap -rtse -rose
+isode miscellany! #518! ! ros.imisc" | \
+awk -F! '
+ {
+ if (firstime == 0) {
+ printf "A=\"Internet=`hostname`\"\n\n"
+ printf "rm -f /tmp/iae$$\n"
+ printf "echo \"objectClass= top & applicationProcess & quipuObject & quipuNonLeafObject\" >> /tmp/iae$$\n"
+ printf "echo \"cn= %s\" >> /tmp/iae$$\n", S
+ printf "echo \"acl= \" >> /tmp/iae$$\n"
+ printf "echo \"masterDSA= `showentry -type masterDSA -edb -nokey`\" >> /tmp/iae$$\n"
+
+ printf "add \"cn=%s\" -draft /tmp/iae$$ -noedit\n\n", S
+
+ firstime = 1;
+ }
+
+ printf "# %s\n", $1
+ printf "rm -f /tmp/iae$$\n"
+ printf "echo \"objectClass= top & applicationEntity & quipuObject & iSODEApplicationEntity\" >> /tmp/iae$$\n"
+ printf "echo \"cn= %s\" >> /tmp/iae$$\n", $1
+ printf "echo \"presentationAddress=%s/$A\" >> /tmp/iae$$\n", $2
+ printf "echo \"supportedApplicationContext=%s\" >> /tmp/iae$$\n", $3
+ printf "echo \"acl= \" >> /tmp/iae$$\n"
+ printf "echo \"execVector=%s\" >> /tmp/iae$$\n", $4
+
+ printf "add \"cn=%s@cn=%s\" -draft /tmp/iae$$ -noedit\n\n", S, $1
+ }
+END {
+ printf "rm -f /tmp/iae$$\n"
+ printf "echo \"You may wish to edit cn=%s to add l, o, ou, and description attributes.\"\n", S
+ }' S="$S" -
+
+exit 0
--- /dev/null
+###############################################################################
+#
+# isoentities - ISODE Application Entity Title Database
+#
+# Application Entity Titles as per ACSE
+#
+# This file takes the place of "real" directory services; OIDs are used
+# for AETs, rather than Distinguished Names.
+#
+#
+# $Header: /f/osi/support/RCS/entities.prefix,v 7.5 91/02/22 09:46:24 mrose Interim $
+#
+#
+# $Log: entities.prefix,v $
+# Revision 7.5 91/02/22 09:46:24 mrose
+# Interim 6.8
+#
+# Revision 7.4 91/01/14 15:10:07 mrose
+# rfa
+#
+# Revision 7.3 90/11/20 15:33:14 mrose
+# update
+#
+# Revision 7.2 90/10/29 18:37:18 mrose
+# updates
+#
+# Revision 7.1 90/07/09 14:50:40 mrose
+# sync
+#
+# Revision 7.0 89/11/23 22:27:11 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+# <host> <service> <aet> <paddr>
+#
+# Each token is separated by LWSP, though double-quotes may be
+# used to prevent separation
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Application entity titles: 1.17.4
+#
+# 1.17.4.0 templates for services
+# 1.17.4.1 templates for local services
+# 1.17.4.2 examples of specific services
+# 1.17.4.3 specific services under different administrations
+#
+###############################################################################
+
+# templates for services: 1.17.4.0
+
+default default 1.17.4.0.0
+
+# this is where ISODE 3.0 FTAM (DIS over DIS) lived
+#default filestore 1.17.4.0.1 #256/
+
+default "isode/echo" 1.17.4.0.2 #512/
+
+default "isode/rtse echo" 1.17.4.0.3 #513/
+
+default "isode/ros_echo" 1.17.4.0.4 #514/
+
+default "isode/sink" 1.17.4.0.5 #515/
+
+default "isode/rtse sink" 1.17.4.0.6 #516/
+
+default "isode/ros_sink" 1.17.4.0.7 #517/
+
+default "isode miscellany" 1.17.4.0.8 #518/
+
+#default imagestore 1.17.4.0.9 #519/
+
+default "isode callback demo" 1.17.4.0.10 #520/
+
+default "isode listen demo" 1.17.4.0.11
+
+default passwdstore 1.17.4.0.12 #521/
+
+#default dbmstore 1.17.4.0.13 #522/
+
+# temporary until the FTAM/FTP gateway is co-resident with the FTAM responder
+default ftpstore 1.17.4.0.13 #523/
+
+default directory 1.17.4.0.14 #257/
+
+# this is where ISODE 4.0 FTAM (DIS over IS) lived
+#default disfilestore 1.17.4.0.15 #258/
+
+# this is where ISODE 5.0 (and later) FTAM (IS over IS) lives
+default filestore 1.17.4.0.16 #259/
+
+default shell 1.17.4.0.17 #524/
+
+default terminal 1.17.4.0.18 #260/
+
+default "isode idist" 1.17.4.0.19 #525/
+
+default mib 1.17.4.0.20 #261/
+
+default "rfa" 1.17.4.0.21 #526/
+
+
--- /dev/null
+.TH IAED 8C "15 Oct 1990"
+.\" $Header: /f/osi/support/RCS/iaed.8c,v 7.7 91/02/22 09:46:25 mrose Interim $
+.\"
+.\"
+.\" $Log: iaed.8c,v $
+.\" Revision 7.7 91/02/22 09:46:25 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.6 90/12/19 09:16:04 mrose
+.\" touch-up
+.\"
+.\" Revision 7.5 90/12/17 22:13:26 mrose
+.\" -call
+.\"
+.\" Revision 7.4 90/12/11 10:52:18 mrose
+.\" lock-and-load
+.\"
+.\" Revision 7.3 90/10/29 18:37:20 mrose
+.\" updates
+.\"
+.\" Revision 7.2 90/10/16 11:21:02 mrose
+.\" update
+.\"
+.\" Revision 7.1 90/10/15 18:18:58 mrose
+.\" typos
+.\"
+.\" Revision 7.0 90/10/15 18:13:37 mrose
+.\" *** empty log message ***
+.\"
+.SH NAME
+iaed \- OSI transport listener (using the Directory)
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDiaed
+\%[\-d]
+\%[\-t] \%[\-x] \%[\-b] \%[\-z]
+\%[\-D\ DIT] \%[\-m]
+\%[\-c\0DSA-name-or-address]
+\%[\-u\0username] \%[\-p\0password]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIiaed\fR server listens for OSI transport connections on the local
+host.
+It is similar to the \fItsapd\fR program,
+except that it gets its configuration information from the OSI
+directory:
+\fIiaed\fR will search the OSI directory for entries with an
+objectClass of iSODEApplicationEntity.
+For each entry,
+\fIiaed\fR will listen on the appropriate transport address
+(as extracted from the presentationAddress attribute of the entry).
+Each entry also contains an execVector attribute which indicates which
+UNIX program provides the given service.
+.PP
+Approximately every twenty-four hours \fIiaed\fR will re-connect to the
+Directory to see if anything has changed.
+In addition,
+sending \fIiaed\fR a SIGHUP will cause it to check the Directory immediately.
+Note that if the local DSA is slaving the information,
+then changes may not propagate in a timely fashion.
+If the `-m' switch is given,
+then \fIiaed\fR will always talk to a master DSA when asking for the
+information by using the DAP service option \*(lqdont-use-copy\*(rq.
+.PP
+The argument given to the `-D' switch tells \fIiaed\fR where to look
+for entries.
+If the value starts with an `@',
+then this specifies an absolute location in the DIT;
+otherwise,
+the value is appended to the local_DIT position given in the
+\fIdsaptailor\fR file.
+By default,
+\fIdased\fR will use non-authentication when binding to the Directory.
+If desired,
+a username (DN) and a password can be supplied using the `\-u' and `\-p'
+switches can be used (respectively).
+Further,
+\fIiaed\fR will connect to the default local DSA
+(the first entry in the \fIdsaptailor\fR file).
+If desired,
+the name or address of another DSA can be suppoed using the `\-c' switch.
+.PP
+Note that \fIiaed\fR will only handle those entries whose
+presentationAddress attribute contains a non-null transport selector
+and null session and presentation selectors.
+.PP
+By default,
+all network services are enabled
+(if defined in the configuration).
+The `\-t' option specifies TCP\-only operation,
+the `\-x' option specifies X.25\-only operation,
+the `\-b' option specifies tp0bridge\-only operation,
+and the `\-z' option specifies TP4\-only operation.
+.PP
+\fIiaed\fR runs the program with permissions set to the owner and
+group of the program.
+Hence,
+unpriviledged programs can be invoked directly under \fIiaed\fR.
+.SH "DEBUG OPERATION"
+If \fIiaed\fR is started interactively,
+or if the `\-d' switch is given,
+then debug mode is entered.
+In this case,
+all logging activity is displayed on the user's terminal,
+the logging information is more verbose,
+and \fIiaed\fR will terminate after it handles the first incoming connection
+(this allows \fIiaed\fR to be run under a debugger).
+.SH EXAMPLES
+For most installations,
+.sp
+.in +.5i
+\*(SDiaed -D cn=`hostname` &
+.in -.5i
+.sp
+run under /etc/rc.local is sufficient.
+This runs TCP\-, X.25\-based and/or TP4\-based services,
+depending on the configuration.
+.SH FILES
+.nf
+.ta \w'\*(LDiaed.log 'u
+\*(LDiaed.log log file
+.re
+.fi
+.SH "SEE ALSO"
+tsapd(8c)
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+.TH ISOALIASES 5 "11 Jun 1988"
+.\" $Header: /f/osi/support/RCS/isoaliases.5,v 7.2 91/02/22 09:46:26 mrose Interim $
+.\"
+.\"
+.\" $Log: isoaliases.5,v $
+.\" Revision 7.2 91/02/22 09:46:26 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.1 90/07/09 14:50:41 mrose
+.\" sync
+.\"
+.\" Revision 7.0 89/11/23 22:27:12 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+.B isoaliases
+\- ISODE aliases database
+.SH DESCRIPTION
+The \fIisoaliases\fR
+file contains information regarding local aliases for either
+user-friendly names or distinguished names for use with the OSI Directory.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+The first item is the alias, a simple string.
+The second item is the value.
+.SH "USER-SPECIFIC ALIASES"
+By default
+a user-specific aliases database is consulted before the system\-wide
+aliases file.
+The user-specific file is called \fB\&.isode_aliases\fR in the user's
+home directory.
+.SH FILES
+.nf
+.ta \w'$HOME/.isode_aliases 'u
+\*(EDisoaliases ISODE aliases database
+$HOME/.isode_aliases user-specific aliases database
+.re
+.fi
+.SH "SEE ALSO"
+dsabuild(8c),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Aliases Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+.TH ISOBJECTS 5 "23 Jul 1987"
+.\" $Header: /f/osi/support/RCS/isobjects.5,v 7.1 91/02/22 09:46:27 mrose Interim $
+.\"
+.\"
+.\" $Log: isobjects.5,v $
+.\" Revision 7.1 91/02/22 09:46:27 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:27:13 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+.B isobjects
+\- ISODE objects database
+.SH DESCRIPTION
+The \fIisobjects\fR
+file contains information regarding the known objects on the host.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+The first item is the descriptor of the object, a simple string.
+The second item is the corresponding object identifier.
+.SH FILES
+.nf
+.ta \w'\*(EDisobjects 'u
+\*(EDisobjects ISODE objects database
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5), isoservices(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Objects Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+.TH ISOC 1C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isoc.1c,v 7.1 91/02/22 09:46:28 mrose Interim $
+.\"
+.\"
+.\" $Log: isoc.1c,v $
+.\" Revision 7.1 91/02/22 09:46:28 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:27:14 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+isoc \- minimal ISODE client for testing
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B isoc
+host provider entity
+.in -.5i
+.SH DESCRIPTION
+The \fIisoc\fR program requests a few minimal ISODE services
+and is useful primarily for debugging purposes.
+Currently,
+several entities can be requested, depending on the provider selected.
+The echo entities will verify that the data they send is received correctly.
+The \fIisode/\fR entities use association control (when applicable)
+in order to test out these newer facilities.
+.PP
+Further,
+to measure raw TCP performance, the \fIsink\fR entity can be requested of
+the \fIraw\fR provider.
+This option depends on the target system already having a TCP sink server in
+place.
+Berkeley UNIX sites usually have such a server.
+.PP
+To summarize:
+.sp
+.in +.5i
+.nf
+.ta \w'\fIprovider\fR 'u
+\fIprovider\fR \fIentity\fR
+raw sink
+tsap echo, sink
+ssap echo, sink
+psap echo, sink,
+ isode/echo, isode/sink
+rtsap echo, sink,
+ ros_echo, ros_sink,
+ \*(lqisode/rtse echo\*(rq, \*(rqisode/rtse sink\*(rq
+ isode/ros_echo, isode/ros_sink
+rosap echo, sink,
+ isode/echo, isode/sink
+.re
+.fi
+.in -.5i
+.sp
+.PP
+Finally,
+on those hosts with sub\-second timing facilities,
+by redirecting \fIisoc\fR's standard input to a file,
+raw performance at a given layer can be measured.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices 'u
+\*(EDisoservices ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoservices(5), isore(8c)
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+/* isoc.c - "minimal" ISODE client for testing */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/support/RCS/isoc.c,v 7.5 91/02/22 09:46:29 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/support/RCS/isoc.c,v 7.5 91/02/22 09:46:29 mrose Interim $
+ *
+ *
+ * $Log: isoc.c,v $
+ * Revision 7.5 91/02/22 09:46:29 mrose
+ * Interim 6.8
+ *
+ * Revision 7.4 90/12/11 10:52:20 mrose
+ * lock-and-load
+ *
+ * Revision 7.3 90/11/11 10:53:16 mrose
+ * update
+ *
+ * Revision 7.2 90/10/16 12:56:05 mrose
+ * stuff
+ *
+ * Revision 7.1 89/12/07 21:19:51 mrose
+ * stuff
+ *
+ * Revision 7.0 89/11/23 22:27:15 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include <varargs.h>
+#include "rosap.h"
+#include "rtsap.h"
+#include "acsap.h"
+#include "psap2.h"
+#include "ssap.h"
+#include "tsap.h"
+#ifdef TCP
+#include "internet.h"
+#ifdef BSD42
+#include <sys/ioctl.h>
+#endif
+#ifdef SVR3
+#include <fcntl.h>
+#endif
+#endif
+#include "isoservent.h"
+#include "tailor.h"
+#include <sys/stat.h>
+
+#undef TIMER
+#undef TMS
+#ifdef BSD42
+#define TIMER
+#endif
+#ifdef SYS5
+#define TIMER
+#ifndef HPUX
+#include <sys/times.h>
+#define TMS
+#endif
+#endif
+
+#if defined (TCP) && (defined (FIONBIO) || defined (O_NDELAY))
+#define ASYNC
+#endif
+
+/* \f DATA */
+
+#define ISN(req) \
+ (req & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)) \
+ ? (long) ((getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN) \
+ : SERIAL_NONE
+
+static enum { echo, sink, XXX } mode = XXX;
+
+static int testing_queued_writes = 0;
+
+static char *isacs = NULL;
+static int isrts = 0;
+
+static int status = 0;
+
+static char *myname = "isoc";
+
+
+void adios (), advise ();
+void ts_adios (), ts_advise ();
+void ss_adios (), ss_advise ();
+void ps_adios (), ps_advise ();
+void acs_adios (), acs_advise ();
+void rts_adios (), rts_advise ();
+void ros_adios (), ros_advise ();
+
+
+long lseek ();
+
+/* \f MAIN */
+
+#define chkacs() if (isacs) \
+ adios (NULLCP, "no association control for %s", \
+ argv[2])
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int argc;
+char **argv,
+ **envp;
+{
+ register struct isoservent *is;
+
+ if (myname = rindex (argv[0], '/'))
+ myname++;
+ if (myname == NULL || *myname == NULL)
+ myname = argv[0];
+
+ isodetailor (myname, 1);
+
+ if (argc != 4)
+ adios (NULLCP, "usage: %s host provider entity", myname);
+
+#ifdef TCP
+ if (strcmp (argv[2], "raw") == 0) {
+ raw_main (argv[3], argv[1]);
+ exit (0);
+ }
+#endif
+
+ if (index (argv[3], '/')) {
+ mode = strcmp (isacs = argv[3], "isode/sink") ? echo : sink;
+ }
+ else {
+ if ((is = getisoserventbyname (argv[3], argv[2])) == NULL)
+ adios (NULLCP, "%s/%s: unknown provider/entity pair",
+ argv[2], argv[3]);
+
+ mode = strcmp (is -> is_entity, "sink") ? echo : sink;
+ }
+
+ if (strcmp (argv[2], "tsap") == 0) {
+ chkacs ();
+ ts_main (is, argv[1]);
+ }
+ else
+ if (strcmp (argv[2], "ssap") == 0) {
+ chkacs ();
+ ss_main (is, argv[1]);
+ }
+ else
+ if (strcmp (argv[2], "psap") == 0)
+ ps_main (is, argv[1]);
+ else
+ if (strcmp (argv[2], "rtsap") == 0) {
+ isrts = 1;
+ rts_main (is, argv[1]);
+ }
+ else
+ if (strcmp (argv[2], "rosap") == 0)
+ ros_main (is, argv[1]);
+ else
+ adios (NULLCP, "unknown provider: \"%s\"", argv[2]);
+
+ exit (status); /* NOTREACHED */
+}
+
+/* \f RAW */
+
+#ifdef TCP
+static int raw_main (service, addr)
+char *service,
+ *addr;
+{
+ int sd,
+ cc,
+ i,
+ j;
+ char *cp,
+ *dp;
+ register struct hostent *hp;
+ register struct servent *sp;
+ struct sockaddr_in in_socket;
+ register struct sockaddr_in *isock = &in_socket;
+ struct stat st;
+
+ if (strcmp (service, "sink"))
+ adios (NULLCP, "only sink on raw tcp is supported");
+ if ((sp = getservbyname (service, "tcp")) == NULL)
+ adios (NULLCP, "%s/%s: unknown service", "tcp", service);
+ if ((hp = gethostbystring (addr)) == NULL)
+ adios (NULLCP, "%s: unknown host", addr);
+
+ bzero ((char *) isock, sizeof *isock);
+ isock -> sin_family = hp -> h_addrtype;
+ isock -> sin_port = sp -> s_port;
+ inaddr_copy (hp, isock);
+
+ if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK)
+ adios ("socket", "unable to start");
+ fprintf (stderr, "%s... ", hp -> h_name);
+ (void) fflush (stderr);
+ if (join_tcp_server (sd, isock) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ adios ("socket", "unable to connect");
+ }
+ fprintf (stderr, "connected\n");
+
+ if (fstat (fileno (stdin), &st) == NOTOK
+ || (st.st_mode & S_IFMT) != S_IFREG
+ || (cc = st.st_size) == 0)
+ adios (NULLCP, "standard input not a regular file");
+ (void) lseek (fileno (stdin), 0L, 0);
+
+ if ((cp = malloc ((unsigned) cc)) == NULL)
+ adios (NULLCP, "no memory");
+ for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+ switch (i = read (fileno (stdin), dp, j)) {
+ case NOTOK:
+ adios ("on stdin", "read failed");
+
+ case OK:
+ adios (NULLCP, "premature end-of-file");
+
+ default:
+ break;
+ }
+
+#ifdef TIMER
+ timer (0);
+#endif
+ if (write_tcp_socket (sd, cp, cc) != cc)
+ adios ("writing", "error");
+ (void) close_tcp_socket (sd);
+#ifdef TIMER
+ timer (cc);
+#endif
+}
+#endif
+
+/* \f TSAP */
+
+static int ts_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+ int sd,
+ cc,
+ i,
+ j,
+ expedited,
+ expd;
+ char *cp,
+ *dp,
+ buffer[BUFSIZ];
+ struct TSAPaddr *ta;
+ struct TSAPconnect tcs;
+ register struct TSAPconnect *tc = &tcs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+ struct stat st;
+
+ if ((ta = is2taddr (addr, NULLCP, is)) == NULL)
+ adios (NULLCP, "address translation failed");
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+#ifndef ASYNC
+ if (TConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ts_adios (td, "T-CONNECT.REQUEST");
+ }
+ sd = tc -> tc_sd;
+#else
+ if ((i = TAsynConnRequest (NULLTA, ta, 1, NULLCP, 0, NULLQOS, tc, td, 1))
+ == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ts_adios (td, "T-(ASYN-)CONNECT.REQUEST");
+ }
+ sd = tc -> tc_sd, cc = 0;
+ while (i == CONNECTING_1 || i == CONNECTING_2) {
+ int nfds;
+ fd_set mask,
+ *rmask,
+ *wmask;
+
+ nfds = 0;
+ FD_ZERO (&mask);
+ if (TSelectMask (sd, &mask, &nfds, td) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ts_adios (td, "T-(ASYN-)CONNECT.REQUEST(TSelectMask)");
+ }
+ rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+ wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+ fprintf (stderr, ".");
+ (void) fflush (stderr);
+ if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ adios ("failed", "select");
+ }
+
+ if ((rmask && FD_ISSET (sd, rmask) == 0)
+ || (wmask && FD_ISSET (sd, wmask) == 0))
+ continue;
+
+ if ((i = TAsynRetryRequest (sd, tc, td)) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ts_adios (td, "T-ASYN-RETRY.REQUEST");
+ }
+ }
+#endif
+ fprintf (stderr, "connected\n");
+
+
+ if (getenv ("TEST_QUEUED_WRITES")) {
+ if (TSetQueuesOK (tc -> tc_sd, 1, td) == NOTOK)
+ ts_adios (td, "T-SET-QUEUES-OK");
+
+ tsap_log -> ll_events |= LLOG_EXCEPTIONS;
+ tsap_log -> ll_file = "-";
+ (void) ll_close (tsap_log);
+
+ testing_queued_writes = 1;
+ }
+
+ expd = tc -> tc_expedited;
+#ifdef DEBUG
+ {
+ advise (NULLCP, "responding TSAP address: %s",
+ taddr2str (&tc -> tc_responding));
+
+ if (tc -> tc_cc > 0)
+ advise (NULLCP, "greetings: %d octets", tc -> tc_cc);
+ }
+#endif
+
+ if (fstat (fileno (stdin), &st) != NOTOK
+ && (st.st_mode & S_IFMT) == S_IFREG
+ && (cc = st.st_size) != 0) {
+ (void) lseek (fileno (stdin), 0L, 0);
+
+ if ((cp = malloc ((unsigned) cc)) == NULL)
+ adios (NULLCP, "no memory");
+ for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+ switch (i = read (fileno (stdin), dp, j)) {
+ case NOTOK:
+ adios ("on stdin", "read failed");
+
+ case OK:
+ adios (NULLCP, "premature end-of-file");
+
+ default:
+ break;
+ }
+ for (i = 10; i > 0; i--) {
+#ifdef TIMER
+ timer (0);
+#endif
+ ts_datarequest (sd, cp, cc, 0);
+#ifdef TIMER
+ timer (cc);
+#endif
+ }
+ free (cp);
+ }
+ else
+ for (expedited = 0;
+ fgets (buffer, sizeof buffer, stdin);
+ expedited = !expedited) {
+ if ((cc = strlen (buffer) + 1) > TX_SIZE && expedited)
+ expedited = 0;
+
+ ts_datarequest (sd, buffer, cc, expd ? expedited : 0);
+ }
+
+ if (TDiscRequest (sd, NULLCP, 0, td) == NOTOK)
+ ts_adios (td, "T-DISCONNECT.REQUEST");
+}
+
+/* \f */
+
+static int ts_datarequest (sd, data, cc, expedited)
+int sd;
+char *data;
+int cc,
+ expedited;
+{
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if ((expedited ? TExpdRequest (sd, data, cc, td)
+ : TDataRequest (sd, data, cc, td)) == NOTOK)
+ if (expedited)
+ ts_adios (td, "T-EXPEDITED-DATA.REQUEST");
+ else
+ ts_adios (td, "T-DATA.REQUEST");
+
+ if (mode == echo) {
+ if (testing_queued_writes) {
+ int vecp;
+ char *vec[4];
+ fd_set rfds;
+
+ FD_ZERO (&rfds);
+ FD_SET (sd, &rfds);
+ if (TNetAccept (&vecp, vec, sd + 1, &rfds, NULLFD, NULLFD, NOTOK,
+ td) == NOTOK)
+ ts_adios (td, "T-NET-ACCEPT");
+ }
+
+ if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
+ ts_adios (td, "T-READ.REQUEST");
+ if (cc != tx -> tx_cc) {
+ advise (NULLCP, "length mismatch, orig=%d echo=%d",
+ cc, tx -> tx_cc);
+ status++;
+ }
+ else
+ if (qcmp (data, &tx -> tx_qbuf, cc))
+ status++;
+ TXFREE (tx)
+ }
+}
+
+/* \f */
+
+static void ts_adios (td, event)
+register struct TSAPdisconnect *td;
+char *event;
+{
+ ts_advise (td, event);
+
+ _exit (1);
+}
+
+
+static void ts_advise (td, event)
+register struct TSAPdisconnect *td;
+char *event;
+{
+ char data[BUFSIZ];
+
+ if (td -> td_cc > 0) {
+ (void) sprintf (data, "[%s] %*.*s",
+ TErrString (td -> td_reason),
+ td -> td_cc, td -> td_cc, td -> td_data);
+ }
+ else
+ (void) sprintf (data, "[%s]", TErrString (td -> td_reason));
+
+ advise (NULLCP, "%s: %s", event, data);
+}
+
+/* \f SSAP */
+
+static int requirements = SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
+ | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
+ | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
+
+static int owned = 0;
+static int avail = 0;
+
+static long ssn;
+
+static int nmodes;
+static int datamodes[4];
+
+static char userdata[1024];
+
+/* \f */
+
+static int ss_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+ int sd,
+ cc,
+ i,
+ j,
+ k,
+ l,
+ tokens;
+ char *cp,
+ *dp,
+ buffer[BUFSIZ];
+ struct SSAPactid ids;
+ register struct SSAPactid *id = &ids;
+ register struct SSAPaddr *sz;
+ struct SSAPref sfs;
+ register struct SSAPref *sf;
+ struct SSAPconnect scs;
+ register struct SSAPconnect *sc = &scs;
+ struct SSAPrelease srs;
+ register struct SSAPrelease *sr = &srs;
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+ struct stat st;
+
+ bzero (userdata, sizeof userdata);
+
+ if ((sz = is2saddr (addr, NULLCP, is)) == NULL)
+ adios (NULLCP, "address translation failed");
+ if ((sf = addr2ref (SLocalHostName ())) == NULL) {
+ sf = &sfs;
+ (void) bzero ((char *) sf, sizeof *sf);
+ }
+
+ tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ tokens |= ST_CALL_VALUE << shift; \
+}
+ dotokens ();
+#undef dotoken
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+#ifndef ASYNC
+ if (SConnRequest (sf, NULLSA, sz, requirements, tokens, ISN (requirements),
+ userdata, sizeof userdata /*SS_SIZE*/, NULLQOS, sc, si) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ss_adios (sa, "S-CONNECT.REQUEST");
+ }
+ sd = sc -> sc_sd;
+#else
+ if ((i = SAsynConnRequest (sf, NULLSA, sz, requirements, tokens,
+ ISN (requirements), userdata, sizeof userdata /*SS_SIZE*/, NULLQOS,
+ sc, si, 1))
+ == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST");
+ }
+ sd = sc -> sc_sd, cc = 0;
+ while (i == CONNECTING_1 || i == CONNECTING_2) {
+ int nfds;
+ fd_set mask,
+ *rmask,
+ *wmask;
+
+ nfds = 0;
+ FD_ZERO (&mask);
+ if (SSelectMask (sd, &mask, &nfds, si) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ss_adios (sa, "S-(ASYN-)CONNECT.REQUEST(SSelectMask)");
+ }
+ rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+ wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+ fprintf (stderr, ".");
+ if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ adios ("failed", "select");
+ }
+
+ if ((rmask && FD_ISSET (sd, rmask) == 0)
+ || (wmask && FD_ISSET (sd, wmask) == 0))
+ continue;
+
+ if ((i = SAsynRetryRequest (sd, sc, si)) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ss_adios (sa, "S-ASYN-RETRY.REQUEST");
+ }
+ }
+#endif
+
+ if (sc -> sc_result != SC_ACCEPT) {
+ fprintf (stderr, "failed\n");
+ if (sc -> sc_cc > 0)
+ adios (NULLCP, "connection rejected: [%s] %*.*s",
+ SErrString (sc -> sc_result),
+ sc -> sc_cc, sc -> sc_cc, sc -> sc_data);
+ else
+ adios (NULLCP, "connection rejected: [%s]",
+ SErrString (sc -> sc_result));
+ }
+ fprintf (stderr, "connected\n");
+
+#ifdef DEBUG
+ {
+ advise (NULLCP, "responding SSAP address: %s",
+ saddr2str (&sc -> sc_responding));
+
+ if (sc -> sc_cc > 0)
+ advise (NULLCP, "greetings: %d octets", sc -> sc_cc);
+ }
+#endif
+ requirements = sc -> sc_requirements;
+ nmodes = 0;
+ datamodes[nmodes++] = SX_NORMAL;
+ if (requirements & SR_EXPEDITED)
+ datamodes[nmodes++] = SX_EXPEDITED;
+ if ((requirements & SR_CAPABILITY) && (requirements & SR_ACTIVITY))
+ datamodes[nmodes++] = SX_CAPDIND;
+ if (requirements & SR_TYPEDATA)
+ datamodes[nmodes++] = SX_TYPED;
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ switch (sc -> sc_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE: \
+ adios (NULLCP, "%s token: choice", type); \
+ \
+ case ST_INIT_VALUE: \
+ owned |= bit, avail |= bit; \
+ break; \
+ \
+ case ST_RESP_VALUE: \
+ avail |= bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ } \
+}
+ dotokens ();
+#undef dotoken
+
+ if (requirements & SR_ACTIVITY) {
+ (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
+ id -> sd_len = strlen (id -> sd_data);
+ if (SActStartRequest (sd, id, userdata, SV_SIZE, si) == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-START.REQUEST");
+ }
+
+ if (fstat (fileno (stdin), &st) != NOTOK
+ && (st.st_mode & S_IFMT) == S_IFREG
+ && (cc = st.st_size) != 0) {
+ (void) lseek (fileno (stdin), 0L, 0);
+
+ if ((cp = malloc ((unsigned) cc)) == NULL)
+ adios (NULLCP, "no memory");
+ for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+ switch (i = read (fileno (stdin), dp, j)) {
+ case NOTOK:
+ adios ("on stdin", "read failed");
+
+ case OK:
+ adios (NULLCP, "premature end-of-file");
+
+ default:
+ break;
+ }
+ for (i = 10; i > 0; i--) {
+#ifdef TIMER
+ timer (0);
+#endif
+ ss_datarequest (sd, cp, cc, SX_NORMAL, 0);
+#ifdef TIMER
+ timer (cc);
+#endif
+ }
+ free (cp);
+ }
+ else {
+ for (j = l = 0; fgets (buffer, sizeof buffer, stdin); ) {
+ k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
+ if ((cc = strlen (buffer) + 1) > SX_EXSIZE && k == SX_EXPEDITED) {
+ if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
+ k = datamodes[j++ % nmodes];
+ }
+
+ switch (k) {
+ case SX_CAPDIND:
+ if (!(requirements & SR_RESYNC) || l++ & 0x01) {
+ ss_waitfor (sd, ST_ACT_TOKEN);
+ if (l & 0x03) {
+ if (SActIntrRequest (sd, SP_SEQUENCE, si)
+ == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-INTERRUPT.REQUEST");
+ }
+ else {
+ if (SActDiscRequest (sd, SP_SEQUENCE, si)
+ == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-DISCARD.REQUEST");
+ }
+ ss_waitfor (sd, -1);
+ goto push_data;
+ }
+ if (!(requirements & SR_RESYNC))
+ break;
+ tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ tokens |= ST_CALL_VALUE << shift; \
+}
+ dotokens ();
+#undef dotoken
+ if (SReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
+ userdata, SN_SIZE, si) == NOTOK)
+ ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
+ ss_waitfor (sd, -1);
+ break;
+
+ case SX_EXPEDITED:
+ if (j >= nmodes)
+ j = j % nmodes;/* fall... */
+ if (!(requirements & SR_EXPEDITED))
+ k = SX_NORMAL; /* fall... */
+ default:
+push_data: ;
+ ss_datarequest (sd, buffer, cc, k, 1);
+ if (k == SX_CAPDIND
+ && SActResumeRequest (sd, id, id,
+ (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
+ + SERIAL_MIN, sf, userdata, SV_SIZE, si)
+ == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-RESUME.REQUEST");
+ break;
+ }
+ }
+
+ if (requirements & SR_EXCEPTIONS) {
+ if (owned & ST_DAT_TOKEN)
+ if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
+ ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~ST_DAT_TOKEN;
+ if (SUReportRequest (sd, SP_NOREASON, userdata, SP_SIZE, si)
+ == NOTOK)
+ ss_adios (sa, "S-U-EXCEPTION-REPORT.REQUEST");
+ ss_waitfor (sd, -1);
+ }
+ }
+
+ if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
+ if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+ | ST_MAJ_TOKEN);
+ if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
+ == OK)
+ break; /* else fall */
+
+ default:
+ ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
+ }
+
+ ss_waitfor (sd, -1);
+ }
+
+ if (requirements & SR_ACTIVITY) {
+ if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, avail);
+ if (SActEndRequest (sd, &ssn, userdata, SV_SIZE, si) == OK)
+ break; /* else fall */
+
+ default:
+ ss_adios (sa, "S-ACTIVITY-END.REQUEST");
+ }
+
+ ss_waitfor (sd, -1);
+
+ if (SGControlRequest (sd, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, avail);
+ if (SGControlRequest (sd, si) == OK)
+ break; /* else fall */
+
+ default:
+ ss_adios (sa, "S-CONTROL-GIVE.REQUEST");
+ }
+
+ owned = 0;
+
+ ss_waitfor (sd, -1);
+ }
+
+ if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ case SC_WAITING:
+ ss_waitfor (sd, avail);
+ if (SRelRequest (sd, userdata, SF_SIZE, NOTOK, sr, si) == OK)
+ break; /* else fall */
+
+ default:
+ ss_adios (sa, "S-RELEASE.REQUEST");
+ }
+
+ if (!sr -> sr_affirmative) {
+ (void) SUAbortRequest (sd, NULLCP, 0, si);
+
+ if (sr -> sr_cc > 0)
+ adios (NULLCP, "release rejected by peer: %*.*s",
+ sr -> sr_cc, sr -> sr_cc, sr -> sr_data);
+ else
+ adios (NULLCP, "release rejected by peer");
+ }
+ SRFREE (sr);
+}
+
+/* \f */
+
+static int ss_datarequest (sd, data, cc, dm, sync)
+int sd;
+char *data;
+int cc,
+ dm,
+ sync;
+{
+ int result;
+ struct SSAPdata sxs;
+ register struct SSAPdata *sx = &sxs;
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ switch (dm) {
+ default:
+ if (SDataRequest (sd, data, cc, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, ST_DAT_TOKEN);
+ if (SDataRequest (sd, data, cc, si) == OK)
+ break;/* else fall */
+
+ default:
+ ss_adios (sa, "S-DATA.REQUEST");
+ }
+ break;
+
+ case SX_EXPEDITED:
+ if (SExpdRequest (sd, data, cc, si) == NOTOK)
+ ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
+ break;
+
+ case SX_CAPDIND:
+ if (SCapdRequest (sd, data, cc, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, avail & ~ST_RLS_TOKEN);
+ if (SCapdRequest (sd, data, cc, si) == OK)
+ break;/* else fall */
+
+ default:
+ ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
+ }
+ break;
+
+ case SX_TYPED:
+ if (STypedRequest (sd, data, cc, si) == NOTOK)
+ ss_adios (sa, "S-TYPED-DATA.REQUEST");
+ break;
+ }
+
+ if (mode == echo || dm == SX_CAPDIND)
+ for (;;) {
+ switch (result = SReadRequest (sd, sx, NOTOK, si)) {
+ case NOTOK:
+ ss_adios (sa, "S-READ.REQUEST");
+
+ case OK:
+ if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
+ != sx -> sx_type) {
+ advise (NULLCP,
+ "data indication type mismatch, orig=%d echo=%d",
+ dm, sx -> sx_type);
+ status++;
+ }
+ if (cc != sx -> sx_cc) {
+ advise (NULLCP, "length mismatch, orig=%d echo=%d",
+ cc, sx -> sx_cc);
+ status++;
+ }
+ else
+ if (qcmp (data, &sx -> sx_qbuf, cc))
+ status++;
+ SXFREE (sx)
+ break;
+
+ case DONE:
+ ss_event (sd, si);
+ continue;
+
+ default:
+ adios (NULLCP, "unknown return from SReadRequest=%d",
+ result);
+ }
+ break;
+ }
+
+ if (sync &&
+ (requirements & SR_MINORSYNC) && !(requirements & SR_ACTIVITY)) {
+ if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata, SN_SIZE, si)
+ == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
+ if (SMinSyncRequest (sd, SYNC_CONFIRM, &ssn, userdata,
+ SN_SIZE, si) == OK)
+ break; /* else fall */
+
+ default:
+ ss_adios (sa, "S-MINOR-SYNC.REQUEST");
+ }
+
+ ss_waitfor (sd, -1);
+ }
+ else
+ if (sync
+ && (requirements & SR_ACTIVITY)
+ && (requirements & SR_MAJORSYNC)
+ && dm == SX_NORMAL) {
+ if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si) == NOTOK)
+ switch (sa -> sa_reason) {
+ case SC_OPERATION:
+ ss_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+ | ST_MAJ_TOKEN);
+ if (SMajSyncRequest (sd, &ssn, userdata, SN_SIZE, si)
+ == OK)
+ break;/* else fall */
+
+ default:
+ ss_adios (sa, "S-MAJOR-SYNC.REQUEST");
+ }
+
+ ss_waitfor (sd, -1);
+ }
+}
+
+/* \f */
+
+static int ss_waitfor (sd, want)
+int sd,
+ want;
+{
+ int result,
+ tokens;
+ char buffer[BUFSIZ];
+ struct SSAPdata sxs;
+ register struct SSAPdata *sx = &sxs;
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ for (;;) {
+ if (want == -1) {
+ want = avail;
+ goto read_it;
+ }
+
+ tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if ((want & bit) && !(owned & bit)) \
+ tokens |= bit; \
+}
+ dotokens ();
+#undef dotoken
+ if (tokens == 0)
+ return;
+
+ if (SPTokenRequest (sd, tokens, userdata, ST_SIZE, si) == NOTOK)
+ ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
+
+read_it: ;
+ switch (result = SReadRequest (sd, sx, NOTOK, si)) {
+ case NOTOK:
+ ss_adios (sa, "S-READ.REQUEST");
+
+ case OK:
+ (void) strcpy (buffer, "protocol screw-up");
+ if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
+ ss_adios (sa, "S-U-ABORT.REQUEST");
+ adios (NULLCP, "%s, data indication type=0x%x",
+ buffer, sx -> sx_type);
+
+ case DONE:
+ ss_event (sd, si);
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from SReadRequest=%d",
+ result);
+ }
+ }
+}
+
+/* \f */
+
+static ss_event (sd, si)
+int sd;
+register struct SSAPindication *si;
+{
+ register struct SSAPabort *sa = &si -> si_abort;
+ register struct SSAPactivity *sv = &si -> si_activity;
+ register struct SSAPfinish *sf = &si -> si_finish;
+ register struct SSAPreport *sp = &si -> si_report;
+ register struct SSAPsync *sn = &si -> si_sync;
+ register struct SSAPtoken *st = &si -> si_token;
+
+ switch (si -> si_type) {
+ case SI_TOKEN:
+ switch (st -> st_type) {
+ case ST_GIVE:
+ case ST_CONTROL:
+ owned = st -> st_owned;
+ break;
+
+ case ST_PLEASE:
+ if (SGTokenRequest (sd,
+ (int) st -> st_tokens, si)
+ == NOTOK)
+ ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~st -> st_tokens;
+ break;
+
+ default:
+ adios (NULLCP,
+ "unknown token indication type=0x%x, %d bytes",
+ st -> st_type, st -> st_cc);
+ }
+ STFREE (st);
+ break;
+
+ case SI_SYNC:
+ switch (sn -> sn_type) {
+ case SN_MAJORIND:
+ adios (NULLCP, "majorsync indication %d, %d bytes",
+ sn -> sn_ssn, sn -> sn_cc);
+ break;
+
+ case SN_MAJORCNF:
+ break;
+
+ case SN_MINORIND:
+ adios (NULLCP, "minorsync indication %d%s, %d bytes",
+ sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
+ ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
+ break;
+
+ case SN_MINORCNF:
+ break;
+
+ case SN_RESETIND:
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ switch (sn -> sn_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ sn -> sn_settings &= ~(ST_MASK << shift); \
+ sn -> sn_settings |= ST_RESP_VALUE << shift; \
+ case ST_RESP_VALUE << shift: \
+ owned &= ~bit; \
+ break; \
+ \
+ case ST_INIT_VALUE << shift: \
+ owned |= bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ break; \
+ } \
+}
+ dotokens ();
+#undef dotoken
+ if (SReSyncResponse (sd, sn -> sn_ssn, sn -> sn_settings,
+ userdata, SN_SIZE, si) == NOTOK)
+ ss_adios (sa, "S-RESYNCHRONIZE.RESPONSE");
+ break;
+
+ case SN_RESETCNF:
+ break;
+
+ default:
+ adios (NULLCP,
+ "unknown sync indication=0x%x, ssn=%d, %d bytes",
+ sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
+ }
+ SNFREE (sn);
+ break;
+
+ case SI_ACTIVITY:
+ switch (sv -> sv_type) {
+ case SV_START:
+ adios (NULLCP,
+ "activity start indication: %*.*s, %d bytes",
+ sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+ sv -> sv_id.sd_data, sv -> sv_cc);
+
+ case SV_RESUME:
+ adios (NULLCP,
+ "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
+ sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+ sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
+ sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
+ sprintref (&sv -> sv_connect), sv -> sv_ssn,
+ sv -> sv_cc);
+
+ case SV_INTRIND:
+ adios (NULLCP,
+ "activity interrupt indication %d, %d bytes",
+ sv -> sv_reason, sv -> sv_cc);
+
+ case SV_INTRCNF:
+ break;
+
+ case SV_DISCIND:
+ adios (NULLCP,
+ "activity discard indication %d, %d bytes",
+ sv -> sv_reason, sv -> sv_cc);
+
+ case SV_DISCCNF:
+ break;
+
+ case SV_ENDIND:
+ adios (NULLCP, "activity end indication %d, %d bytes",
+ sv -> sv_ssn, sv -> sv_cc);
+
+ case SV_ENDCNF:
+ break;
+
+ default:
+ adios (NULLCP,
+ "unknown activity indication=0x%x, %d bytes",
+ sv -> sv_type, sv -> sv_cc);
+ }
+ SVFREE (sv);
+ break;
+
+ case SI_REPORT:
+ if (requirements & SR_DAT_EXISTS) {
+ if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
+ ss_adios (sa, "S-TOKEN-GIVE.REQUEST (to clear exception)");
+ else
+ owned &= ~ST_DAT_TOKEN;
+ }
+ else
+ if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
+ ss_adios (sa, "S-U-ABORT.REQUEST");
+ else
+ adios (NULLCP, "aborted");
+ SPFREE (sp);
+ break;
+
+ case SI_FINISH:
+ if (SRelResponse (sd, SC_REJECTED, NULLCP, 0, si) == NOTOK)
+ ss_adios (sa, "S-RELEASE.RESPONSE");
+ SFFREE (sf);
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=0x%x",
+ si -> si_type);
+ }
+}
+
+/* \f */
+
+static void ss_adios (sa, event)
+register struct SSAPabort *sa;
+char *event;
+{
+ ss_advise (sa, event);
+
+ _exit (1);
+}
+
+
+static void ss_advise (sa, event)
+register struct SSAPabort *sa;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (sa -> sa_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ SErrString (sa -> sa_reason),
+ sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
+ else
+ (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
+
+ advise (NULLCP, "%s: %s%s", event, buffer,
+ sa -> sa_peer ? " (peer initiated)" : "");
+
+ SAFREE (sa);
+}
+
+/* \f PSAP */
+
+static int prequirements = 0;
+#define srequirements requirements
+
+static int nctxs;
+static int datactxs[NPCTX];
+
+/* \f */
+
+static int ps_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+ int sd,
+ cc,
+ i,
+ j,
+ k,
+ l,
+ m,
+ tokens;
+ char *cp,
+ *dp,
+ buffer[BUFSIZ];
+ register struct PSAPaddr *pz;
+ struct SSAPactid ids;
+ register struct SSAPactid *id = &ids;
+ struct SSAPref sfs;
+ register struct SSAPref *sf;
+ struct PSAPconnect pcs;
+ register struct PSAPconnect *pc = &pcs;
+ struct PSAPctxlist pls;
+ register struct PSAPctxlist *pl = &pls;
+ struct PSAPrelease prs;
+ register struct PSAPrelease *pr = &prs;
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+ struct AcSAPconnect accs;
+ register struct AcSAPconnect *acc = &accs;
+ struct AcSAPrelease acrs;
+ register struct AcSAPrelease *acr = &acrs;
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+ register PE pe;
+ PE udata[NPDATA];
+ AEI aei;
+ OID oid,
+ ode;
+ struct stat st;
+
+ if (isacs) {
+ if ((aei = str2aei (addr, isacs)) == NULLAEI)
+ adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
+ if ((pz = aei2addr (aei)) == NULLPA)
+ adios (NULLCP, "address translation failed");
+
+ cp = mode == echo ? "isode echo pci" : "isode sink pci";
+ if ((ode = ode2oid (cp)) == NULLOID)
+ adios (NULLCP, "%s: unknown object descriptor", cp);
+ ode = oid_cpy (ode);
+ }
+ else
+ if ((pz = is2paddr (addr, NULLCP, is)) == NULL)
+ adios (NULLCP, "address translation failed");
+ if ((sf = addr2ref (PLocalHostName ())) == NULL) {
+ sf = &sfs;
+ (void) bzero ((char *) sf, sizeof *sf);
+ }
+
+ tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (srequirements & requires) \
+ tokens |= ST_CALL_VALUE << shift; \
+}
+ dotokens ();
+#undef dotoken
+
+ for (i = (pl -> pc_nctx = NPCTX - (isacs ? 1 : 0)) - 1; i >= 0; i--) {
+ pl -> pc_ctx[i].pc_id = i * 2 + 1;
+ if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
+ adios (NULLCP, "iso asn.1 abstract syntax: unknown");
+ pl -> pc_ctx[i].pc_asn = oid_cpy (oid);
+ pl -> pc_ctx[i].pc_atn = NULLOID;
+ }
+
+ for (i = 0; i < NPDATA; i++) {
+ if ((pe = int2prim (i)) == NULLPE)
+ adios (NULLCP, "unable to allocate hello");
+ pe -> pe_context = (i % pl -> pc_nctx) * 2 + 1;
+ udata[i] = pe;
+ }
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+ if (isacs) {
+#ifndef ASYNC
+ if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
+ prequirements, srequirements, ISN (srequirements), tokens, sf,
+ udata, NACDATA, NULLQOS, acc, aci)
+ == NOTOK) {
+ fprintf (stderr, "failed\n");
+ acs_adios (aca, "A-ASSOCIATE.REQUEST");
+ }
+ sd = acc -> acc_sd;
+#else
+ if ((i = AcAsynAssocRequest (ode, NULLAEI, aei, NULLPA, pz, pl, ode,
+ prequirements, srequirements, ISN (srequirements), tokens, sf,
+ udata, NACDATA, NULLQOS, acc, aci, 1)) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST");
+ }
+ sd = acc -> acc_sd, cc = 0;
+ while (i == CONNECTING_1 || i == CONNECTING_2) {
+ int nfds;
+ fd_set mask,
+ *rmask,
+ *wmask;
+
+ nfds = 0;
+ FD_ZERO (&mask);
+ if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ acs_adios (aca, "A-(ASYN-)ASSOCIATE.REQUEST(PSelectMask)");
+ }
+ rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+ wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+ fprintf (stderr, ".");
+ if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ adios ("failed", "select");
+ }
+
+ if ((rmask && FD_ISSET (sd, rmask) == 0)
+ || (wmask && FD_ISSET (sd, wmask) == 0))
+ continue;
+
+ if ((i = AcAsynRetryRequest (sd, acc, aci)) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ acs_adios (aca, "A-ASYN-RETRY.REQUEST");
+ }
+ }
+#endif
+
+ if (acc -> acc_result != ACS_ACCEPT) {
+ fprintf (stderr, "failed\n");
+ adios (NULLCP, "connection rejected: [%s], %d elements",
+ AcErrString (acc -> acc_result), acc -> acc_ninfo);
+ }
+ }
+ else {
+#ifndef ASYNC
+ if (PConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
+ srequirements, srequirements
+ & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY)
+ ? (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1)) + SERIAL_MIN
+ : SERIAL_NONE, tokens, sf, udata, NPDATA, NULLQOS, pc, pi) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ps_adios (pa, "P-CONNECT.REQUEST");
+ }
+ sd = pc -> pc_sd;
+#else
+ if ((i = PAsynConnRequest (NULLPA, pz, pl, NULLOID, prequirements,
+ srequirements, ISN (srequirements), tokens, sf, udata, NPDATA,
+ NULLQOS, pc, pi, 1)) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ps_adios (pa, "P-CONNECT.REQUEST");
+ }
+ sd = pc -> pc_sd, cc = 0;
+ while (i == CONNECTING_1 || i == CONNECTING_2) {
+ int nfds;
+ fd_set mask,
+ *rmask,
+ *wmask;
+
+ nfds = 0;
+ FD_ZERO (&mask);
+ if (PSelectMask (sd, &mask, &nfds, pi) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ps_adios (pa, "P-CONNECT.REQUEST(PSelectMask)");
+ }
+ rmask = (i == CONNECTING_2) ? &mask : NULLFD;
+ wmask = (i == CONNECTING_2) ? NULLFD : &mask;
+
+ fprintf (stderr, ".");
+ if (xselect (nfds, rmask, wmask, NULLFD, 1) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ adios ("failed", "select");
+ }
+
+ if ((rmask && FD_ISSET (sd, rmask) == 0)
+ || (wmask && FD_ISSET (sd, wmask) == 0))
+ continue;
+
+ if ((i = PAsynRetryRequest (sd, pc, pi)) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ps_adios (pa, "P-ASYN-RETRY.REQUEST");
+ }
+ }
+#endif
+
+ if (pc -> pc_result != PC_ACCEPT) {
+ fprintf (stderr, "failed\n");
+ adios (NULLCP, "connection rejected: [%s], %d elements",
+ PErrString (pc -> pc_result), pc -> pc_ninfo);
+ }
+ }
+ fprintf (stderr, "connected\n");
+
+ if (isacs) {
+ pc = &acc -> acc_connect;
+
+#ifdef DEBUG
+ {
+ advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
+
+ advise (NULLCP,
+ "responding AE title: %s, responding PSAP address: %s",
+ sprintaei (&acc -> acc_respondtitle),
+ paddr2str (&pc -> pc_responding, NULLNA));
+
+ advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
+
+ pl = &pc -> pc_ctxlist;
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+ pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ advise (NULLCP, "default %d", pc -> pc_defctxresult);
+ advise (NULLCP, "p/s requirements 0x%x/0x%x",
+ pc -> pc_prequirements, pc -> pc_srequirements);
+ }
+#endif
+
+ pl = &pc -> pc_ctxlist;
+
+ if (mode == echo) {
+ if (acc -> acc_ninfo != NACDATA)
+ adios (NULLCP, "expecting %d hellos, got %d elements",
+ NACDATA, acc -> acc_ninfo);
+ for (i = 0; i < NACDATA; i++) {
+ if ((pe = acc -> acc_info[i]) == NULLPE)
+ adios (NULLCP, "hello %d: NULL", i);
+ if ((j = prim2num (pe)) == NOTOK
+ && pe -> pe_errno != PE_ERR_NONE)
+ adios (NULLCP, "hello %d: %s", i,
+ pe_error (pe -> pe_errno));
+ if (j != i)
+ adios (NULLCP, "hello %d: value %d", i, j);
+ if (pe -> pe_context != udata[i] -> pe_context)
+ adios (NULLCP, "hello %d: context of %d instead of %d",
+ i, pe -> pe_context, udata[i] -> pe_context);
+ }
+ }
+
+ goto do_release;
+ }
+ else {
+#ifdef DEBUG
+ {
+ advise (NULLCP, "responding PSAP address: %s",
+ paddr2str (&pc -> pc_responding, NULLNA));
+
+ advise (NULLCP, "greetings: %d elements", pc -> pc_ninfo);
+
+ pl = &pc -> pc_ctxlist;
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+ pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ advise (NULLCP, "default %d", pc -> pc_defctxresult);
+ advise (NULLCP, "p/s requirements 0x%x/0x%x",
+ pc -> pc_prequirements, pc -> pc_srequirements);
+ }
+#endif
+
+ if (mode == echo) {
+ if (pc -> pc_ninfo != NPDATA)
+ adios (NULLCP, "expecting %d hellos, got %d elements",
+ NPDATA, pc -> pc_ninfo);
+ for (i = 0; i < NPDATA; i++) {
+ if ((pe = pc -> pc_info[i]) == NULLPE)
+ adios (NULLCP, "hello %d: NULL", i);
+ if ((j = prim2num (pe)) == NOTOK
+ && pe -> pe_errno != PE_ERR_NONE)
+ adios (NULLCP, "hello %d: %s", i,
+ pe_error (pe -> pe_errno));
+ if (j != i)
+ adios (NULLCP, "hello %d: value %d", i, j);
+ if (pe -> pe_context != udata[i] -> pe_context)
+ adios (NULLCP, "hello %d: context of %d instead of %d",
+ i, pe -> pe_context, udata[i] -> pe_context);
+ }
+ }
+ }
+
+ nctxs = 0;
+ pl = &pc -> pc_ctxlist;
+ for (i = 0; i < pl -> pc_nctx; i++)
+ if (pl -> pc_ctx[i].pc_result == PC_ACCEPT)
+ datactxs[nctxs++] = pl -> pc_ctx[i].pc_id;
+
+ srequirements = pc -> pc_srequirements;
+ nmodes = 0;
+ datamodes[nmodes++] = SX_NORMAL;
+ if (srequirements & SR_EXPEDITED)
+ datamodes[nmodes++] = SX_EXPEDITED;
+ if ((srequirements & SR_CAPABILITY) && (srequirements & SR_ACTIVITY))
+ datamodes[nmodes++] = SX_CAPDIND;
+ if (srequirements & SR_TYPEDATA)
+ datamodes[nmodes++] = SX_TYPED;
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (srequirements & requires) \
+ switch (pc -> pc_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE: \
+ adios (NULLCP, "%s token: choice", type); \
+ \
+ case ST_INIT_VALUE: \
+ owned |= bit, avail |= bit; \
+ break; \
+ \
+ case ST_RESP_VALUE: \
+ avail |= bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ } \
+}
+ dotokens ();
+#undef dotoken
+
+ if (isacs)
+ ACCFREE (acc)
+ else
+ PCFREE (pc);
+
+ if (srequirements & SR_ACTIVITY) {
+ (void) strcpy (id -> sd_data, mode == echo ? "echo" : "sink");
+ id -> sd_len = strlen (id -> sd_data);
+ if (PActStartRequest (sd, id, udata, NPDATA, pi) == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-START.REQUEST");
+ }
+
+ if (fstat (fileno (stdin), &st) != NOTOK
+ && (st.st_mode & S_IFMT) == S_IFREG
+ && (cc = st.st_size) != 0) {
+ (void) lseek (fileno (stdin), 0L, 0);
+
+ if ((cp = malloc ((unsigned) cc)) == NULL)
+ adios (NULLCP, "no memory");
+ for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+ switch (i = read (fileno (stdin), dp, j)) {
+ case NOTOK:
+ adios ("on stdin", "read failed");
+
+ case OK:
+ adios (NULLCP, "premature end-of-file");
+
+ default:
+ break;
+ }
+ if ((pe = oct2prim (cp, cc)) == NULLPE)
+ adios (NULLCP, "unable to allocate PSDU");
+ free (cp);
+ if (nctxs)
+ pe -> pe_context = datactxs[0];
+ for (i = 10; i > 0; i--) {
+#ifdef TIMER
+ timer (0);
+#endif
+ ps_datarequest (sd, pe, SX_NORMAL, 0);
+#ifdef TIMER
+ timer (cc);
+#endif
+ }
+ pe_free (pe);
+ }
+ else {
+ for (j = l = m = 0; fgets (buffer, sizeof buffer, stdin); ) {
+ k = j >= nmodes ? SX_EXPEDITED : datamodes[j++ % nmodes];
+ if ((cc = strlen (buffer) + 1) > SX_EXSIZE - 7
+ && k == SX_EXPEDITED) {
+ if ((k = datamodes[j++ % nmodes]) == SX_EXPEDITED)
+ k = datamodes[j++ % nmodes];
+ }
+
+ switch (k) {
+ case SX_CAPDIND:
+ if (!(requirements & SR_RESYNC) || l++ & 0x01) {
+ ps_waitfor (sd, ST_ACT_TOKEN);
+ if (l & 0x03) {
+ if (PActIntrRequest (sd, SP_SEQUENCE, pi)
+ == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-INTERRUPT.REQUEST");
+ }
+ else {
+ if (PActDiscRequest (sd, SP_SEQUENCE, pi)
+ == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-DISCARD.REQUEST");
+ }
+ ps_waitfor (sd, -1);
+ goto push_data;
+ }
+ tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ tokens |= ST_CALL_VALUE << shift; \
+}
+ dotokens ();
+#undef dotoken
+ if (PReSyncRequest (sd, SYNC_SET, ssn - 1, tokens,
+ udata, NPDATA, pi) == NOTOK)
+ ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
+ ps_waitfor (sd, -1);
+ break;
+
+ case SX_EXPEDITED:
+ if (j >= nmodes)
+ j = j % nmodes;
+ if (!(srequirements & SR_EXPEDITED))
+ k = SX_NORMAL; /* fall... */
+ default:
+push_data: ;
+ if ((pe = oct2prim (buffer, cc)) == NULLPE)
+ adios (NULLCP, "unable to allocate PSDU");
+ if (nctxs && k != SX_EXPEDITED)
+ pe -> pe_context = datactxs[m++ % nctxs];
+ ps_datarequest (sd, pe, k, 1);
+ pe_free (pe);
+ if (k == SX_CAPDIND
+ && PActResumeRequest (sd, id, id,
+ (long) (getpid () % (SERIAL_MAX - SERIAL_MIN + 1))
+ + SERIAL_MIN, sf, udata, NPDATA, pi)
+ == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-RESUME.REQUEST");
+ break;
+ }
+ }
+
+ if (requirements & SR_EXCEPTIONS) {
+ if (owned & ST_DAT_TOKEN)
+ if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
+ ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~ST_DAT_TOKEN;
+ if (PUReportRequest (sd, SP_NOREASON, udata, NPDATA, pi) == NOTOK)
+ ps_adios (pa, "P-U-EXCEPTION-REPORT.REQUEST");
+ ps_waitfor (sd, -1);
+ }
+ }
+
+ if ((requirements & SR_MAJORSYNC) && !(requirements & SR_ACTIVITY)) {
+ if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+ | ST_MAJ_TOKEN);
+ if (PMajSyncRequest (sd, &ssn, udata, NPDATA, pi) == OK)
+ break; /* else fall */
+
+ default:
+ ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
+ }
+
+ ps_waitfor (sd, -1);
+ }
+
+ if (requirements & SR_ACTIVITY) {
+ if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, avail);
+ if (PActEndRequest (sd, &ssn, udata, NPDATA, pi) == OK)
+ break; /* else fall */
+
+ default:
+ ps_adios (pa, "P-ACTIVITY-END.REQUEST");
+ }
+
+ ps_waitfor (sd, -1);
+
+ if (PGControlRequest (sd, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, avail);
+ if (PGControlRequest (sd, pi) == OK)
+ break; /* else fall */
+
+ default:
+ ps_adios (pa, "P-CONTROL-GIVE.REQUEST");
+ }
+
+ owned = 0;
+
+ ps_waitfor (sd, -1);
+ }
+
+do_release: ;
+ if (isacs) {
+ if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK, acr, aci)
+ == NOTOK)
+ switch (aca -> aca_reason) {
+ case ACS_OPERATION:
+ ps_waitfor (sd, avail);
+ if (AcRelRequest (sd, ACF_NORMAL, udata, NACDATA, NOTOK,
+ acr, aci) == OK)
+ break; /* else fall */
+
+ default:
+ acs_adios (aca, "A-RELEASE.REQUEST");
+ }
+
+ if (!acr -> acr_affirmative) {
+ (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
+ adios (NULLCP, "release rejected by peer: %d, %d elements",
+ acr -> acr_reason, acr -> acr_ninfo);
+ }
+
+#ifdef DEBUG
+ advise (NULLCP, "A-RELEASE.CONFIRMATION: %d, %d elements",
+ acr -> acr_reason, acr -> acr_ninfo);
+#endif
+ ACRFREE (acr);
+ }
+ else {
+ if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ case PC_WAITING:
+ ps_waitfor (sd, avail);
+ if (PRelRequest (sd, udata, NPDATA, NOTOK, pr, pi) == OK)
+ break; /* else fall */
+
+ default:
+ ps_adios (pa, "P-RELEASE.REQUEST");
+ }
+
+ if (!pr -> pr_affirmative) {
+ (void) PUAbortRequest (sd, NULLPEP, 0, pi);
+ adios (NULLCP, "release rejected by peer: %d elements",
+ pr -> pr_ninfo);
+ }
+ PRFREE (pr);
+ }
+
+ for (i = 0; i < NPDATA; i++)
+ pe_free (udata[i]);
+}
+
+/* \f */
+
+static int ps_datarequest (sd, pe, dm, sync)
+int sd;
+PE pe;
+int dm,
+ sync;
+{
+ int result;
+ struct PSAPdata pxs;
+ register struct PSAPdata *px = &pxs;
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+ switch (dm) {
+ default:
+ if (PDataRequest (sd, &pe, 1, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, ST_DAT_TOKEN);
+ if (PDataRequest (sd, &pe, 1, pi) == OK)
+ break;/* else fall */
+
+ default:
+ ps_adios (pa, "P-DATA.REQUEST");
+ }
+ break;
+
+ case SX_EXPEDITED:
+ if (PExpdRequest (sd, &pe, 1, pi) == NOTOK)
+ ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
+ break;
+
+ case SX_CAPDIND:
+ if (PCapdRequest (sd, &pe, 1, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, avail & ~ST_RLS_TOKEN);
+ if (PCapdRequest (sd, &pe, 1, pi) == OK)
+ break;/* else fall */
+
+ default:
+ ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
+ }
+ break;
+
+ case SX_TYPED:
+ if (PTypedRequest (sd, &pe, 1, pi) == NOTOK)
+ ps_adios (pa, "P-TYPED-DATA.REQUEST");
+ break;
+ }
+
+ if (mode == echo || dm == SX_CAPDIND)
+ for (;;) {
+ switch (result = PReadRequest (sd, px, NOTOK, pi)) {
+ case NOTOK:
+ ps_adios (pa, "P-READ.REQUEST");
+
+ case OK:
+ if ((dm != SX_CAPDIND ? dm : SX_CAPDCNF)
+ != px -> px_type) {
+ advise (NULLCP,
+ "data indication type mismatch, orig=%d echo=%d",
+ dm, px -> px_type);
+ status++;
+ }
+ if (px -> px_ninfo != 1) {
+ advise (NULLCP, "length mismatch, orig=%d echo=%d",
+ 1, px -> px_ninfo);
+ status++;
+ }
+ if (pe -> pe_context != (*px -> px_info) -> pe_context) {
+ advise (NULLCP, "context mismatch, orig=%d echo=%d",
+ pe -> pe_context,
+ (*px -> px_info) -> pe_context);
+ status++;
+ }
+ if (pe_cmp (pe, *px -> px_info)) {
+ advise (NULLCP, "data mismatch (1)");
+ vunknown (pe);
+ advise (NULLCP, "---------");
+ vunknown (*px -> px_info);
+ advise (NULLCP, "---------");
+ status++;
+ }
+ PXFREE (px)
+ break;
+
+ case DONE:
+ ps_event (sd, pi);
+ continue;
+
+ default:
+ adios (NULLCP, "unknown return from PReadRequest=%d",
+ result);
+ }
+ break;
+ }
+
+ if (sync &&
+ (srequirements & SR_MINORSYNC) && !(srequirements & SR_ACTIVITY)) {
+ if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN);
+ if (PMinSyncRequest (sd, SYNC_CONFIRM, &ssn, NULLPEP, 0,
+ pi) == OK)
+ break; /* else fall */
+
+ default:
+ ps_adios (pa, "P-MINOR-SYNC.REQUEST");
+ }
+
+ ps_waitfor (sd, -1);
+ }
+ else
+ if (sync
+ && (srequirements & SR_ACTIVITY)
+ && (srequirements & SR_MAJORSYNC)
+ && dm == SX_NORMAL) {
+ if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == NOTOK)
+ switch (pa -> pa_reason) {
+ case PC_OPERATION:
+ ps_waitfor (sd, ST_DAT_TOKEN | ST_MIN_TOKEN
+ | ST_MAJ_TOKEN);
+ if (PMajSyncRequest (sd, &ssn, NULLPEP, 0, pi) == OK)
+ break;/* else fall */
+
+ default:
+ ps_adios (pa, "P-MAJOR-SYNC.REQUEST");
+ }
+
+ ps_waitfor (sd, -1);
+ }
+}
+
+/* \f */
+
+static int ps_waitfor (sd, want)
+int sd,
+ want;
+{
+ int result,
+ tokens;
+ struct PSAPdata pxs;
+ register struct PSAPdata *px = &pxs;
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+ for (;;) {
+ if (want == -1) {
+ want = avail;
+ goto read_it;
+ }
+
+ tokens = 0;
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if ((want & bit) && !(owned & bit)) \
+ tokens |= bit; \
+}
+ dotokens ();
+#undef dotoken
+ if (tokens == 0)
+ return;
+
+ if (PPTokenRequest (sd, tokens, NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
+
+read_it: ;
+ switch (result = PReadRequest (sd, px, NOTOK, pi)) {
+ case NOTOK:
+ ps_adios (pa, "P-READ.REQUEST");
+
+ case OK:
+ ps_abort (sd, "protocol screw-up");
+
+ case DONE:
+ ps_event (sd, pi);
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from PReadRequest=%d",
+ result);
+ }
+ }
+}
+
+/* \f */
+
+static ps_event (sd, pi)
+int sd;
+register struct PSAPindication *pi;
+{
+ register struct PSAPabort *pa = &pi -> pi_abort;
+ register struct PSAPactivity *pv = &pi -> pi_activity;
+ register struct PSAPfinish *pf = &pi -> pi_finish;
+ register struct PSAPreport *pp = &pi -> pi_report;
+ register struct PSAPsync *pn = &pi -> pi_sync;
+ register struct PSAPtoken *pt = &pi -> pi_token;
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+ register struct AcSAPfinish *acf = &aci -> aci_finish;
+
+ switch (pi -> pi_type) {
+ case PI_TOKEN:
+ switch (pt -> pt_type) {
+ case ST_GIVE:
+ case ST_CONTROL:
+ owned = pt -> pt_owned;
+ break;
+
+ case ST_PLEASE:
+ if (PGTokenRequest (sd,
+ (int) pt -> pt_tokens, pi)
+ == NOTOK)
+ ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~pt -> pt_tokens;
+ break;
+
+ default:
+ adios (NULLCP,
+ "unknown token indication type=0x%x",
+ pt -> pt_type);
+ }
+ PTFREE (pt);
+ break;
+
+ case PI_SYNC:
+ switch (pn -> pn_type) {
+ case SN_MAJORIND:
+ adios (NULLCP, "majorsync indication %d",
+ pn -> pn_ssn);
+ break;
+
+ case SN_MAJORCNF:
+ break;
+
+ case SN_MINORIND:
+ adios (NULLCP, "minorsync indication %d%s",
+ pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
+ ? " (wants confirmation)" : NULLCP);
+ break;
+
+ case SN_MINORCNF:
+ break;
+
+ case SN_RESETIND:
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (srequirements & requires) \
+ switch (pn -> pn_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ pn -> pn_settings &= ~(ST_MASK << shift); \
+ pn -> pn_settings |= ST_RESP_VALUE << shift; \
+ case ST_RESP_VALUE << shift: \
+ owned &= ~bit; \
+ break; \
+ \
+ case ST_INIT_VALUE << shift: \
+ owned |= bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ break; \
+ } \
+}
+ dotokens ();
+#undef dotoken
+ if (PReSyncResponse (sd, pn -> pn_ssn, pn -> pn_settings,
+ NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-RESYNCHRONIZE.RESPONSE");
+ break;
+
+ case SN_RESETCNF:
+ break;
+
+ default:
+ adios (NULLCP, "unknown sync indication=0x%x, ssn=%d",
+ pn -> pn_type, pn -> pn_ssn);
+ }
+ PNFREE (pn);
+ break;
+
+ case PI_ACTIVITY:
+ switch (pv -> pv_type) {
+ case SV_START:
+ adios (NULLCP, "activity start indication: %*.*s",
+ pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+ pv -> pv_id.sd_data);
+
+ case SV_RESUME:
+ adios (NULLCP,
+ "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
+ pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+ pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
+ pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
+ sprintref (&pv -> pv_connect), pv -> pv_ssn);
+
+ case SV_INTRIND:
+ adios (NULLCP, "activity interrupt indication %d",
+ pv -> pv_reason);
+
+ case SV_INTRCNF:
+ break;
+
+ case SV_DISCIND:
+ adios (NULLCP, "activity discard indication %d",
+ pv -> pv_reason);
+
+ case SV_DISCCNF:
+ break;
+
+ case SV_ENDIND:
+ adios (NULLCP, "activity end indication %d",
+ pv -> pv_ssn);
+
+ case SV_ENDCNF:
+ break;
+
+ default:
+ adios (NULLCP, "unknown activity indication=0x%x",
+ pv -> pv_type);
+ }
+ PVFREE (pv);
+ break;
+
+ case PI_REPORT:
+ advise (NULLCP, "%s report %d",
+ pp -> pp_peer ? "user" : "provider", pp -> pp_reason);
+ if (srequirements & SR_DAT_EXISTS) {
+ if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
+ ps_adios (pa, "P-TOKEN-GIVE.REQUEST (to clear exception)");
+ else
+ owned &= ~ST_DAT_TOKEN;
+ }
+ else
+ ps_abort (sd, "aborted");
+ PPFREE (pp);
+ break;
+
+ case PI_FINISH:
+ if (isacs) {
+ if (AcFINISHser (sd, pf, aci) == NOTOK)
+ acs_adios (aca, "AcFINISHser");
+#ifdef DEBUG
+ advise (NULLCP, "A-RELEASE.INDICATION %d, %d elements",
+ acf -> acf_reason, acf -> acf_ninfo);
+ if (AcRelResponse (sd, ACS_USER_NOREASON, ACR_NOTFINISHED,
+ NULLPEP, 0, aci) == NOTOK)
+ acs_adios (aca, "A-RELEASE.RESPONSE");
+#endif
+
+ ACFFREE (acf);
+ }
+ else {
+ if (PRelResponse (sd, PC_REJECTED, NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-RELEASE.RESPONSE");
+
+ PFFREE (pf);
+ }
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=0x%x", pi -> pi_type);
+ }
+}
+
+/* \f */
+
+static ps_abort (sd, reason)
+int sd;
+char *reason;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+
+ if (isacs) {
+ if (AcUAbortRequest (sd, NULLPEP, 0, aci) == NOTOK)
+ acs_adios (aca, "A-U-ABORT.REQUEST");
+ }
+ else {
+ if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-U-ABORT.REQUEST");
+ }
+
+ adios (NULLCP, "%s", reason);
+}
+
+/* \f */
+
+static void ps_adios (pa, event)
+register struct PSAPabort *pa;
+char *event;
+{
+ ps_advise (pa, event);
+
+ _exit (1);
+}
+
+
+static void ps_advise (pa, event)
+register struct PSAPabort *pa;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (pa -> pa_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ PErrString (pa -> pa_reason),
+ pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
+ else
+ (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
+
+ advise (NULLCP, "%s: %s%s", event, buffer,
+ pa -> pa_peer ? " (peer initiated)" : "");
+}
+
+/* \f AcSAP */
+
+static void acs_adios (aca, event)
+register struct AcSAPabort *aca;
+char *event;
+{
+ acs_advise (aca, event);
+
+ _exit (1);
+}
+
+
+static void acs_advise (aca, event)
+register struct AcSAPabort *aca;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (aca -> aca_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ AcErrString (aca -> aca_reason),
+ aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
+ else
+ (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
+
+ advise (NULLCP, "%s: %s (source %d)", event, buffer,
+ aca -> aca_source);
+}
+
+/* \f RtSAP */
+
+static int turn = 0;
+
+/* \f */
+
+static int rts_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+ int sd,
+ cc,
+ i,
+ j,
+ ros;
+ char *cp,
+ *dp,
+ buffer[BUFSIZ];
+ register struct PSAPaddr *pa;
+ struct PSAPctxlist pls;
+ register struct PSAPctxlist *pl = &pls;
+ struct AcSAPrelease acrs;
+ register struct AcSAPrelease *acr = &acrs;
+ struct RtSAPaddr rtzs;
+ register struct RtSAPaddr *rtz = &rtzs;
+ struct RtSAPconnect rtcs;
+ register struct RtSAPconnect *rtc = &rtcs;
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+#ifdef DEBUG
+ struct AcSAPconnect *acc= &rtc -> rtc_connect;
+ struct PSAPconnect *pc = &acc -> acc_connect;
+#endif
+ register PE pe;
+ AEI aei;
+ OID oid,
+ ode;
+ struct stat st;
+
+ if ((pe = int2prim (i = getpid ())) == NULLPE)
+ adios (NULLCP, "unable to allocate hello");
+
+ turn = mode == sink;
+
+ if (isacs) {
+ if (ros = strncmp (isacs, "isode/ros_", strlen ("isode/ros_")) == 0)
+ mode = strcmp (isacs, "isode/ros_sink") ? echo : sink;
+ else
+ mode = strcmp (isacs, "isode/rtse sink") ? echo : sink;
+ turn = mode == sink;
+
+ if ((aei = str2aei (addr, isacs)) == NULLAEI)
+ adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
+ if ((pa = aei2addr (aei)) == NULLPA)
+ adios (NULLCP, "address translation failed");
+
+ cp = mode == echo ? "isode echo pci" : "isode sink pci";
+ if ((ode = ode2oid (cp)) == NULLOID)
+ adios (NULLCP, "%s: unknown object descriptor", cp);
+ ode = oid_cpy (ode);
+
+ for (j = (pl -> pc_nctx = NPCTX - 2) - 1; j >= 0; j--) {
+ pl -> pc_ctx[j].pc_id = j * 2 + 1;
+ if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
+ adios (NULLCP, "iso asn.1 abstract syntax: unknown");
+ pl -> pc_ctx[j].pc_asn = oid_cpy (oid);
+ pl -> pc_ctx[j].pc_atn = NULLOID;
+ }
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+ if (RtOpenRequest (RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
+ ode, NULLAEI, aei, NULLPA, pa, pl, ode, pe,
+ NULLQOS, rtc, rti) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ rts_adios (rta, "RT-OPEN.REQUEST");
+ }
+ }
+ else {
+ register struct SSAPaddr *sa;
+
+ if (ros = strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0) {
+ mode = strcmp (is -> is_entity, "ros_sink") ? echo : sink;
+ turn = mode == sink;
+ }
+
+ rtz -> rta_port = is -> is_port; /* yikes! */
+ if ((is = getisoserventbyname ("rts", "ssap")) == NULL)
+ adios (NULLCP, "ssap/rts: unknown entity");
+ if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
+ adios (NULLCP, "address translation failed");
+ rtz -> rta_addr = *sa; /* struct copy */
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+ if (RtBeginRequest (rtz, RTS_TWA, turn ? RTS_INITIATOR : RTS_RESPONDER,
+ pe, rtc, rti) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ rts_adios (rta, "RT-BEGIN.REQUEST");
+ }
+ }
+
+ pe_free (pe);
+
+ if (rtc -> rtc_result != RTS_ACCEPT) {
+ fprintf (stderr, "failed\n");
+ adios (NULLCP, "association rejected: [%s]",
+ RtErrString (rtc -> rtc_result));
+ }
+ fprintf (stderr, "connected\n");
+
+#ifdef DEBUG
+ advise (NULLCP, "sent greetings of %d", i);
+#endif
+
+ sd = rtc -> rtc_sd;
+ if (rtc -> rtc_data) {
+ if ((i = prim2num (rtc -> rtc_data)) == NOTOK
+ && rtc -> rtc_data -> pe_errno != PE_ERR_NONE)
+ adios (NULLCP, "error decoding hello: %s (%d)",
+ pe_error (rtc -> rtc_data -> pe_errno), i);
+#ifdef DEBUG
+ advise (NULLCP, "received greetings of %d", i);
+#endif
+ }
+
+#ifdef DEBUG
+ if (isacs) {
+ advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
+
+ advise (NULLCP,
+ "responding AE title: %s, responding PSAP address: %s",
+ sprintaei (&acc -> acc_respondtitle),
+ paddr2str (&pc -> pc_responding, NULLNA));
+
+ advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
+
+ pl = &pc -> pc_ctxlist;
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+ pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ advise (NULLCP, "default %d", pc -> pc_defctxresult);
+ advise (NULLCP, "p/s requirements 0x%x/0x%x",
+ pc -> pc_prequirements, pc -> pc_srequirements);
+ }
+#endif
+
+ RTCFREE (rtc);
+
+ if (ros) {
+ struct RoSAPindication rois;
+ register struct RoSAPpreject *rop = &rois.roi_preject;
+
+ if (RoSetService (sd, RoRtService, &rois) == NOTOK)
+ ros_adios (rop, "set RO/PT fails");
+
+ do_ros (sd);
+ return;
+ }
+
+ if (fstat (fileno (stdin), &st) != NOTOK
+ && (st.st_mode & S_IFMT) == S_IFREG
+ && (cc = st.st_size) != 0) {
+ (void) lseek (fileno (stdin), 0L, 0);
+
+ if ((cp = malloc ((unsigned) cc)) == NULL)
+ adios (NULLCP, "no memory");
+ for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+ switch (i = read (fileno (stdin), dp, j)) {
+ case NOTOK:
+ adios ("on stdin", "read failed");
+
+ case OK:
+ adios (NULLCP, "premature end-of-file");
+
+ default:
+ break;
+ }
+ if ((pe = oct2prim (cp, cc)) == NULLPE)
+ adios (NULLCP, "unable to allocate APDU");
+ free (cp);
+ for (i = 10; i > 0; i--) {
+#ifdef TIMER
+ timer (0);
+#endif
+ rts_transferequest (sd, pe);
+#ifdef TIMER
+ timer (cc);
+#endif
+ }
+ pe_free (pe);
+ }
+ else
+ while (fgets (buffer, sizeof buffer, stdin)) {
+ if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
+ adios (NULLCP, "unable to allocate APDU");
+ rts_transferequest (sd, pe);
+ pe_free (pe);
+ }
+
+ if (isacs) {
+ if ((pe = int2prim (i = getpid ())) == NULLPE)
+ adios (NULLCP, "unable to allocate hello");
+
+ if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti) == NOTOK)
+ switch (rta -> rta_reason) {
+ case RTS_OPERATION:
+ case RTS_WAITING:
+ rts_waitfor (sd);
+ if (RtCloseRequest (sd, ACF_NORMAL, pe, acr, rti)
+ == OK)
+ break; /* else fall */
+
+ default:
+ rts_adios (rta, "RT-CLOSE.REQUEST");
+ }
+
+ if (!acr -> acr_affirmative) {
+ (void) RtUAbortRequest (sd, NULLPE, rti);
+ adios (NULLCP, "release rejected by peer: %d, %d elements",
+ acr -> acr_reason, acr -> acr_ninfo);
+ }
+
+ if (mode == echo) {
+ if (acr -> acr_ninfo != 1)
+ advise (NULLCP, "got %d elements returned on close",
+ acr -> acr_ninfo);
+ if (pe_cmp (pe, acr -> acr_info[0])) {
+ advise (NULLCP, "data mismatch (2)");
+ vunknown (pe);
+ advise (NULLCP, "---------");
+ vunknown (acr -> acr_info[0]);
+ advise (NULLCP, "---------");
+ status++;
+ }
+ }
+
+ ACRFREE (acr);
+
+ pe_free (pe);
+ }
+ else
+ if (RtEndRequest (sd, rti) == NOTOK)
+ switch (rta -> rta_reason) {
+ case RTS_OPERATION:
+ case RTS_WAITING:
+ rts_waitfor (sd);
+ if (RtEndRequest (sd, rti) == OK)
+ break; /* else fall */
+
+ default:
+ rts_adios (rta, "RT-END.REQUEST");
+ }
+}
+
+/* \f */
+
+static int rts_transferequest (sd, pe)
+int sd;
+register PE pe;
+{
+ int result;
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+ register struct RtSAPtransfer *rtt = &rti -> rti_transfer;
+
+ if (RtTransferRequest (sd, pe, NOTOK, rti) == NOTOK)
+ switch (rta -> rta_reason) {
+ case RTS_OPERATION:
+ rts_waitfor (sd);
+ if (RtTransferRequest (sd, pe, NOTOK, rti) == OK)
+ break; /* else fall */
+
+ default:
+ if (RTS_FATAL (rta -> rta_reason))
+ rts_adios (rta, "RT-TRANSFER.REQUEST");
+ rts_advise (rta, "RT-TRANSFER.REQUEST");
+ return;
+ }
+
+ if (mode == echo)
+ for (;;)
+ switch (result = RtWaitRequest (sd, NOTOK, rti)) {
+ case NOTOK:
+ rts_adios (rta, "RT-WAIT.REQUEST");
+
+ case OK:
+ if (pe_cmp (pe, rtt -> rtt_data)) {
+ advise (NULLCP, "data mismatch (3)");
+ vunknown (pe);
+ advise (NULLCP, "---------");
+ vunknown (rtt -> rtt_data);
+ advise (NULLCP, "---------");
+ status++;
+ }
+ RTTFREE (rtt);
+ return;
+
+ case DONE:
+ rts_event (sd, rti);
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from RtWaitRequest=%d",
+ result);
+ }
+}
+
+/* \f */
+
+static int rts_waitfor (sd)
+int sd;
+{
+ int result;
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+ static int priority = 1;
+
+ if (turn)
+ return;
+
+ if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
+ rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
+
+ while (!turn)
+ switch (result = RtWaitRequest (sd, NOTOK, rti)) {
+ case NOTOK:
+ rts_adios (rta, "RT-WAIT.REQUEST");
+
+ case OK:
+ adios (NULLCP, "protocol screw-up");
+
+ case DONE:
+ rts_event (sd, rti);
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from RtWaitRequest=%d",
+ result);
+ }
+}
+
+/* \f */
+
+static int rts_event (sd, rti)
+int sd;
+register struct RtSAPindication *rti;
+{
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+ register struct RtSAPturn *rtu = &rti -> rti_turn;
+
+ switch (rti -> rti_type) {
+ case RTI_TURN:
+ if (rtu -> rtu_please) {
+ if (RtGTurnRequest (sd, rti) == NOTOK)
+ rts_adios (rta, "RT-TURN-GIVE.REQUEST");
+ turn = 0;
+ }
+ else
+ turn = 1;
+ break;
+
+ case RTI_CLOSE:
+ adios (NULLCP, "got RT-END.INDICATION");
+
+ case RTI_FINISH:
+ adios (NULLCP, "got RT-CLOSE.INDICATION");
+
+ default:
+ adios (NULLCP, "unknown indication type=0x%x",
+ rti -> rti_type);
+ }
+}
+
+/* \f */
+
+static void rts_adios (rta, event)
+register struct RtSAPabort *rta;
+char *event;
+{
+ rts_advise (rta, event);
+
+ _exit (1);
+}
+
+
+static void rts_advise (rta, event)
+register struct RtSAPabort *rta;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (rta -> rta_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason),
+ rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
+ else
+ (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason));
+
+ advise (NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f RoSAP */
+
+static int ros_main (is, addr)
+struct isoservent *is;
+char *addr;
+{
+ int sd,
+ i;
+ char *cp;
+ struct SSAPref sfs;
+ register struct SSAPref *sf;
+ register struct PSAPaddr *pa;
+ struct AcSAPconnect accs;
+ register struct AcSAPconnect *acc = &accs;
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+ struct RoSAPaddr roas;
+ register struct RoSAPaddr *roa = &roas;
+ struct RoSAPconnect rocs;
+ register struct RoSAPconnect *roc = &rocs;
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+#ifdef DEBUG
+ struct PSAPconnect *pc = &acc -> acc_connect;
+#endif
+ struct PSAPctxlist pls;
+ register struct PSAPctxlist *pl = &pls;
+ AEI aei;
+ OID oid,
+ ode;
+ register PE pe;
+
+ if (isacs) {
+ if ((aei = str2aei (addr, isacs)) == NULLAEI)
+ adios (NULLCP, "%s-%s: unknown application-entity", addr, isacs);
+ if ((pa = aei2addr (aei)) == NULLPA)
+ adios (NULLCP, "address translation failed");
+
+ cp = mode == echo ? "isode echo pci" : "isode sink pci";
+ if ((ode = ode2oid (cp)) == NULLOID)
+ adios (NULLCP, "%s: unknown object descriptor", cp);
+ ode = oid_cpy (ode);
+
+ if ((sf = addr2ref (PLocalHostName ())) == NULL) {
+ sf = &sfs;
+ (void) bzero ((char *) sf, sizeof *sf);
+ }
+ pl -> pc_nctx = 1;
+ pl -> pc_ctx[0].pc_id = 1;
+ if ((oid = ode2oid ("iso asn.1 abstract syntax")) == NULLOID)
+ adios (NULLCP, "iso asn.1 abstract syntax: unknown");
+ pl -> pc_ctx[0].pc_asn = oid_cpy (oid);
+ pl -> pc_ctx[0].pc_atn = NULLOID;
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+ if (AcAssocRequest (ode, NULLAEI, aei, NULLPA, pa, pl, ode,
+ 0, ROS_MYREQUIRE, SERIAL_NONE, 0, sf, NULLPEP, 0, NULLQOS,
+ acc, aci)
+ == NOTOK)
+ acs_adios (aca, "A-ASSOCIATE.REQUEST");
+
+ if (acc -> acc_result != ACS_ACCEPT) {
+ fprintf (stderr, "failed\n");
+ adios (NULLCP, "association rejected: [%s]",
+ AcErrString (acc -> acc_result));
+ }
+ fprintf (stderr, "connected\n");
+
+ sd = acc -> acc_sd;
+
+#ifdef DEBUG
+ pa = &pc -> pc_responding;
+ {
+ advise (NULLCP, "context: %s", oid2ode (acc -> acc_context));
+
+ advise (NULLCP,
+ "responding AE title: %s, responding PSAP address: %s",
+ sprintaei (&acc -> acc_respondtitle),
+ paddr2str (&pc -> pc_responding, NULLNA));
+
+ advise (NULLCP, "greetings: %d elements", acc -> acc_ninfo);
+
+ pl = &pc -> pc_ctxlist;
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (NULLCP, "ctx %d: 0x%x 0x%x %d",
+ pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ advise (NULLCP, "default %d", pc -> pc_defctxresult);
+ advise (NULLCP, "p/s requirements 0x%x/0x%x",
+ pc -> pc_prequirements, pc -> pc_srequirements);
+ }
+#endif
+
+ ACCFREE (acc);
+
+ if (RoSetService (sd, RoPService, roi) == NOTOK)
+ ros_adios (rop, "set RO/PT fails");
+ }
+ else {
+ register struct SSAPaddr *sa;
+
+ roa -> roa_port = is -> is_port; /* yikes! */
+ if ((is = getisoserventbyname ("ros", "ssap")) == NULL)
+ adios (NULLCP, "ssap/ros: unknown entity");
+ if ((sa = is2saddr (addr, NULLCP, is)) == NULLSA)
+ adios (NULLCP, "address translation failed");
+ roa -> roa_addr = *sa; /* struct copy */
+
+ if ((pe = int2prim (i = getpid ())) == NULLPE)
+ adios (NULLCP, "unable to allocate hello");
+
+ fprintf (stderr, "%s... ", addr);
+ (void) fflush (stderr);
+ if (RoBeginRequest (roa, pe, roc, roi) == NOTOK) {
+ fprintf (stderr, "failed\n");
+ ros_adios (rop, "RO-BEGIN.REQUEST");
+ }
+
+ pe_free (pe);
+
+ if (roc -> roc_result != ROS_ACCEPT) {
+ fprintf (stderr, "failed\n");
+ adios (NULLCP, "association rejected: [%s]",
+ RoErrString (roc -> roc_result));
+ }
+ fprintf (stderr, "connected\n");
+
+#ifdef DEBUG
+ advise (NULLCP, "sent greetings of %d", i);
+#endif
+
+ sd = roc -> roc_sd;
+ if (roc -> roc_data) {
+ if ((i = prim2num (roc -> roc_data)) == NOTOK
+ && roc -> roc_data -> pe_errno != PE_ERR_NONE)
+ adios (NULLCP, "error decoding hello: %s (%d)",
+ pe_error (roc -> roc_data -> pe_errno), i);
+#ifdef DEBUG
+ advise (NULLCP, "received greetings of %d", i);
+#endif
+ }
+ ROCFREE (roc);
+ }
+
+ do_ros (sd);
+}
+
+/* \f */
+
+static int do_ros (sd)
+int sd;
+{
+ int cc,
+ i,
+ j;
+ char *cp,
+ *dp,
+ buffer[BUFSIZ];
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+ struct AcSAPrelease acrs;
+ register struct AcSAPrelease *acr = &acrs;
+ register PE pe;
+ struct stat st;
+
+ if (fstat (fileno (stdin), &st) != NOTOK
+ && (st.st_mode & S_IFMT) == S_IFREG
+ && (cc = st.st_size) != 0) {
+ (void) lseek (fileno (stdin), 0L, 0);
+
+ if ((cp = malloc ((unsigned) cc)) == NULL)
+ adios (NULLCP, "no memory");
+ for (dp = cp, j = cc; j > 0; dp += i, j -= i)
+ switch (i = read (fileno (stdin), dp, j)) {
+ case NOTOK:
+ adios ("on stdin", "read failed");
+
+ case OK:
+ adios (NULLCP, "premature end-of-file");
+
+ default:
+ break;
+ }
+ if ((pe = oct2prim (cp, cc)) == NULLPE)
+ adios (NULLCP, "unable to allocate invocation argument");
+ free (cp);
+ for (i = 10; i > 0; i--) {
+#ifdef TIMER
+ timer (0);
+#endif
+ ros_invokerequest (sd, pe);
+#ifdef TIMER
+ timer (cc);
+#endif
+ }
+ pe_free (pe);
+ }
+ else
+ while (fgets (buffer, sizeof buffer, stdin)) {
+ if ((pe = oct2prim (buffer, strlen (buffer) + 1)) == NULLPE)
+ adios (NULLCP, "unable to allocate invocation argument");
+ ros_invokerequest (sd, pe);
+ pe_free (pe);
+ }
+
+ if (isrts) {
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+
+ if (isacs) {
+ if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti) == NOTOK)
+ switch (rta -> rta_reason) {
+ case RTS_OPERATION:
+ case RTS_WAITING:
+ rts_waitfor (sd);
+ if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, acr, rti)
+ == OK)
+ break; /* else fall */
+
+ default:
+ rts_adios (rta, "RT-CLOSE.REQUEST");
+ }
+
+ if (!acr -> acr_affirmative) {
+ (void) RtUAbortRequest (sd, NULLPE, rti);
+ adios (NULLCP, "release rejected by peer: %d, %d elements",
+ acr -> acr_reason, acr -> acr_ninfo);
+ }
+ }
+ else
+ if (RtEndRequest (sd, rti) == NOTOK)
+ switch (rta -> rta_reason) {
+ case RTS_OPERATION:
+ case RTS_WAITING:
+ rts_waitfor (sd);
+ if (RtEndRequest (sd, rti) == OK)
+ break; /* else fall */
+
+ default:
+ rts_adios (rta, "RT-END.REQUEST");
+ }
+ }
+ else
+ if (isacs) {
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+
+ if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
+ == NOTOK)
+ acs_adios (aca, "A-RELEASE.REQUEST");
+
+ if (!acr -> acr_affirmative) {
+ (void) AcUAbortRequest (sd, NULLPEP, 0, aci);
+ adios (NULLCP, "release rejected by peer: %d, %d elements",
+ acr -> acr_reason, acr -> acr_ninfo);
+ }
+ ACRFREE (acr);
+ }
+ else
+ if (RoEndRequest (sd, ROS_NOPRIO, roi) == NOTOK)
+ ros_adios (rop, "RO-END.REQUEST");
+}
+
+/* \f */
+
+static int ros_invokerequest (sd, pe)
+int sd;
+PE pe;
+{
+ int result;
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+ static int id = 0;
+ static int op = 0;
+
+ switch (result = RoInvokeRequest (sd, op++, ROS_SYNC, pe, ++id, NULLIP,
+ ROS_NOPRIO, roi)) {
+ case NOTOK:
+ if (ROS_FATAL (rop -> rop_reason))
+ ros_adios (rop, "RO-INVOKE.REQUEST");
+ ros_advise (rop, "RO-INVOKE.REQUEST");
+ break;
+
+ case OK:
+ switch (roi -> roi_type) {
+ case ROI_INVOKE:
+ adios (NULLCP, "got RO-INVOKE.INDICATION");
+
+ case ROI_RESULT:
+ {
+ register struct RoSAPresult *ror = &roi -> roi_result;
+
+ if (ror -> ror_id != id) {
+ advise (NULLCP, "id mismatch (wanted %d, got %d)",
+ id, ror -> ror_id);
+ status++;
+ if (RoURejectRequest (sd, &ror -> ror_id,
+ ROS_RRP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
+ ros_adios (rop, "RO-REJECT-U.REQUEST");
+ }
+ else
+ if (mode == echo
+ && pe_cmp (pe, ror -> ror_result)) {
+ advise (NULLCP, "data mismatch (4)");
+ vunknown (pe);
+ advise (NULLCP, "---------");
+ vunknown (ror -> ror_result);
+ advise (NULLCP, "---------");
+ status++;
+ }
+
+ RORFREE (ror);
+ }
+ break;
+
+ case ROI_ERROR:
+ {
+ register struct RoSAPerror *roe = &roi -> roi_error;
+
+ if (roe -> roe_id != id) {
+ advise (NULLCP, "id mismatch (wanted %d, got %d)",
+ id, roe -> roe_id);
+ status++;
+ if (RoURejectRequest (sd, &roe -> roe_id,
+ ROS_REP_UNRECOG, ROS_NOPRIO, roi) == NOTOK)
+ ros_adios (rop, "RO-REJECT-U.REQUEST");
+ }
+ else
+ if (mode == echo
+ && pe_cmp (pe, roe -> roe_param)) {
+ advise (NULLCP, "data mismatch (5)");
+ vunknown (pe);
+ advise (NULLCP, "---------");
+ vunknown (roe -> roe_param);
+ advise (NULLCP, "---------");
+ status++;
+ }
+
+ ROEFREE (roe);
+ }
+ break;
+
+ case ROI_UREJECT:
+ {
+ register struct RoSAPureject *rou = &roi -> roi_ureject;
+
+ if (rou -> rou_noid)
+ advise (NULLCP, "RO-REJECT-U.INDICATION: %s",
+ RoErrString (rou -> rou_reason));
+ else
+ advise (NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
+ RoErrString (rou -> rou_reason),
+ rou -> rou_id);
+ if (!rou -> rou_noid && rou -> rou_id != id) {
+ advise (NULLCP, "id mismatch (wanted %d, got %d)",
+ id, rou -> rou_id);
+ status++;
+ }
+ }
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=%d",
+ roi -> roi_type);
+ }
+ if (isrts)
+ turn = 0;
+ break;
+
+ case DONE:
+ adios (NULLCP, "got RO-END.INDICATION");
+
+ default:
+ adios (NULLCP, "unknown return from RoInvokeRequest=%d", result);
+ }
+}
+
+
+/* \f */
+
+static void ros_adios (rop, event)
+register struct RoSAPpreject *rop;
+char *event;
+{
+ ros_advise (rop, event);
+
+ _exit (1);
+}
+
+
+static void ros_advise (rop, event)
+register struct RoSAPpreject *rop;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (rop -> rop_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
+ rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
+ else
+ (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
+
+ advise (NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f TIMER */
+
+#ifdef TIMER
+
+#ifndef NBBY
+#define NBBY 8
+#endif
+
+
+#ifndef TMS
+static timer (cc)
+int cc;
+{
+ int bytes;
+ long ms;
+ float bs;
+ struct timeval stop,
+ td;
+ static struct timeval start;
+
+ if (cc == 0) {
+ (void) gettimeofday (&start, (struct timezone *) 0);
+ return;
+ }
+ else
+ (void) gettimeofday (&stop, (struct timezone *) 0);
+
+ tvsub (&td, &stop, &start);
+ ms = (td.tv_sec * 1000) + (td.tv_usec / 1000);
+ bytes = mode == echo ? cc * 2 : cc;
+ bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
+
+ advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f Kbytes/s)",
+ cc, mode == echo ? "echoed" : "sunk",
+ td.tv_sec, td.tv_usec / 10000, bs / 1024);
+}
+
+
+static tvsub (tdiff, t1, t0)
+register struct timeval *tdiff,
+ *t1,
+ *t0;
+{
+
+ tdiff -> tv_sec = t1 -> tv_sec - t0 -> tv_sec;
+ tdiff -> tv_usec = t1 -> tv_usec - t0 -> tv_usec;
+ if (tdiff -> tv_usec < 0)
+ tdiff -> tv_sec--, tdiff -> tv_usec += 1000000;
+}
+#else
+long times ();
+
+
+static timer (cc)
+int cc;
+{
+ int bytes;
+ long ms;
+ float bs;
+ long stop,
+ td,
+ secs,
+ msecs;
+ struct tms tm;
+ static long start;
+
+ if (cc == 0) {
+ start = times (&tm);
+ return;
+ }
+ else
+ stop = times (&tm);
+
+ td = stop - start;
+ secs = td / 60, msecs = (td % 60) * 1000 / 60;
+ ms = (secs * 1000) + msecs;
+ bytes = mode == echo ? cc * 2 : cc;
+ bs = (((float) bytes * NBBY * 1000) / (float) (ms ? ms : 1)) / NBBY;
+
+ advise (NULLCP, "%d bytes %s in %d.%02d seconds (%.2f KBytes/s)",
+ cc, mode == echo ? "echoed" : "sunk",
+ secs, msecs / 10, bs / 1024);
+}
+#endif
+#endif
+
+/* \f QBUF */
+
+static int qcmp (b, qb, l)
+register char *b;
+register struct qbuf *qb;
+register int l;
+{
+ register struct qbuf *qp;
+
+ for (qp = qb -> qb_forw; qp != qb; qp = qp -> qb_forw) {
+ if ((l -= qp -> qb_len) < 0) {
+ advise (NULLCP, "length mismatch(1)");
+ return NOTOK;
+ }
+
+ if (bcmp (b, qp -> qb_data, qp -> qb_len)) {
+ advise (NULLCP, "data mismatch (6)");
+ return NOTOK;
+ }
+
+ b += qp -> qb_len;
+ }
+
+ if (l != 0) {
+ advise (NULLCP, "length mismatch(2)");
+ return NOTOK;
+ }
+
+ return OK;
+}
+
+/* \f ERRORS */
+
+#ifndef lint
+void _advise ();
+
+
+void adios (va_alist)
+va_dcl
+{
+ va_list ap;
+
+ va_start (ap);
+
+ _advise (ap);
+
+ va_end (ap);
+
+ _exit (1);
+}
+#else
+/* VARARGS */
+
+void adios (what, fmt)
+char *what,
+ *fmt;
+{
+ adios (what, fmt);
+}
+#endif
+
+
+#ifndef lint
+void advise (va_alist)
+va_dcl
+{
+ va_list ap;
+
+ va_start (ap);
+
+ _advise (ap);
+
+ va_end (ap);
+}
+
+
+static void _advise (ap)
+va_list ap;
+{
+ char buffer[BUFSIZ];
+
+ asprintf (buffer, ap);
+
+ (void) fflush (stdout);
+
+ fprintf (stderr, "%s: ", myname);
+ (void) fputs (buffer, stderr);
+ (void) fputc ('\n', stderr);
+
+ (void) fflush (stderr);
+}
+#else
+/* VARARGS */
+
+void advise (what, fmt)
+char *what,
+ *fmt;
+{
+ advise (what, fmt);
+}
+#endif
--- /dev/null
+.TH ISOD 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isod.8c,v 7.1 91/02/22 09:46:34 mrose Interim $
+.\"
+.\"
+.\" $Log: isod.8c,v $
+.\" Revision 7.1 91/02/22 09:46:34 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:27:26 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+isod \- minimal ISODE server for testing
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDisod.\fIprovider\fP
+\%[\-async] \%[\-sync] ...
+\fImagic\0arguments\fR
+.in -.5i
+(under \fI\*(SDtsapd\fR\0)
+.SH DESCRIPTION
+The \fIisod\fR server implements a few minimal ISODE services
+and is useful primarily for debugging purposes.
+Currently,
+two services are implemented:
+\fIecho\fR, which simply echoes back everything it receives;
+and,
+\fIsink\fR, which simply tosses anything it receives.
+Both services have support for expedited data.
+.PP
+The providers supported are \fItsap\fR, \fIssap\fR, \fIpsap\fR, \fIacsap\fR,
+\fIrtsap\fR, and, \fIrosap\fR.
+.SH FILES
+.nf
+.ta \w'\*(LDisod.log 'u
+\*(EDisoservices ISODE services database
+\*(LDisod.log logfile
+.re
+.fi
+.SH "SEE ALSO"
+isoc(1c), isoservices(5)
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+/* isod.c - "minimal" ISODE server for testing */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/support/RCS/isod.c,v 7.2 91/02/22 09:46:37 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/support/RCS/isod.c,v 7.2 91/02/22 09:46:37 mrose Interim $
+ *
+ *
+ * $Log: isod.c,v $
+ * Revision 7.2 91/02/22 09:46:37 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/07/01 21:07:50 mrose
+ * pepsy
+ *
+ * Revision 7.0 89/11/23 22:27:27 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include <varargs.h>
+#include "rosap.h"
+#include "rtsap.h"
+#include "acsap.h"
+#include "psap2.h"
+#include "ssap.h"
+#include "tsap.h"
+#include "isoservent.h"
+#include "tailor.h"
+#include "OACS-types.h"
+
+/* \f DATA */
+
+static int debug = 0;
+static int isacs = 0;
+static int isrts = 0;
+
+static LLog _pgm_log = {
+ "isod.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
+ LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *pgm_log = &_pgm_log;
+
+static char *myname = "isod";
+
+
+static enum mode { echo, sink, XXX } mymode = XXX;
+
+struct dispatch {
+ char *ds_entity;
+
+ enum mode ds_mode;
+};
+
+
+void adios (), advise ();
+
+
+void ts_adios (), ts_advise ();
+int ts_dataindication (), ts_discindication ();
+
+static struct dispatch ts_dispatches[] = {
+ "echo", echo,
+ "sink", sink,
+
+ NULLCP, XXX
+};
+
+
+void ss_adios (), ss_advise ();
+int ss_dataindication (), ss_tokenindication (), ss_syncindication (),
+ ss_actindication (), ss_reportindication (), ss_finishindication (),
+ ss_abortindication ();
+
+static struct dispatch *ss_dispatches = ts_dispatches;
+
+
+void ps_adios (), ps_advise ();
+int ps_dataindication (), ps_tokenindication (), ps_syncindication (),
+ ps_actindication (), ps_reportindication (), ps_finishindication (),
+ ps_abortindication ();
+
+static struct dispatch *ps_dispatches = ts_dispatches;
+
+
+void acs_adios (), acs_advise ();
+
+static struct dispatch acs_dispatches[] = {
+ "isode echo", echo,
+ "isode sink", sink,
+
+ NULLCP, XXX
+};
+
+
+void rts_adios (), rts_advise ();
+int rts_indication ();
+
+static struct dispatch rts_dispatches[] = {
+ "echo", echo,
+ "sink", sink,
+ "ros_echo", echo,
+ "ros_sink", sink,
+
+ NULLCP, XXX
+};
+
+static struct dispatch rtse_dispatches[] = {
+ "isode rtse echo", echo,
+ "isode rtse sink", sink,
+ "isode ros_echo", echo,
+ "isode ros_sink", sink,
+
+ NULLCP, XXX
+};
+
+static PE apdupe = NULLPE;
+
+
+void ros_adios (), ros_advise ();
+int ros_indication ();
+
+static struct dispatch *ros_dispatches = ts_dispatches;
+
+static PE nullpe = NULLPE;
+
+
+extern int errno;
+
+/* \f MAIN */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int argc;
+char **argv,
+ **envp;
+{
+ register char *cp;
+
+ if (myname = rindex (argv[0], '/'))
+ myname++;
+ if (myname == NULL || *myname == NULL)
+ myname = argv[0];
+
+ isodetailor (myname, 0);
+ if (debug = isatty (fileno (stderr)))
+ ll_dbinit (pgm_log, myname);
+ else
+ ll_hdinit (pgm_log, myname);
+
+ advise (LLOG_NOTICE, NULLCP, "starting");
+
+ if (cp = rindex (*argv, '.'))
+ *cp++ = NULL;
+
+/* cheat! should do this after calling the init function (sigh!) */
+ if (argc > 1 && strcmp (argv[1], "-rtse") == 0)
+ isacs++;
+
+ if (cp == NULL || strcmp (cp, "tsap") == 0)
+ ts_main (argc, argv);
+ else
+ if (strcmp (cp, "ssap") == 0)
+ ss_main (argc, argv);
+ else
+ if (strcmp (cp, "psap") == 0)
+ ps_main (argc, argv);
+ else
+ if (strcmp (cp, "acsap") == 0) {
+ isacs++;
+ ps_main (argc, argv);
+ }
+ else
+ if (strcmp (cp, "rtsap") == 0) {
+ isrts++;
+ rts_main (argc, argv);
+ }
+ else
+ if (strcmp (cp, "rosap") == 0)
+ ros_main (argc, argv);
+ else
+ adios (NULLCP, "unknown provider: \"%s\"", cp);
+
+ exit (0); /* NOTREACHED */
+}
+
+/* \f TSAP */
+
+static int ts_main (argc, argv)
+int argc;
+char **argv;
+{
+ int async,
+ sd;
+ char buffer[BUFSIZ];
+ register struct dispatch *ds;
+ register struct isoservent *is;
+ struct TSAPstart tss;
+ register struct TSAPstart *ts = &tss;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if (TInit (argc, argv, ts, td) == NOTOK)
+ ts_adios (td, "(T)initialization fails");
+ advise (LLOG_NOTICE, NULLCP,
+ "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",
+ ts -> ts_sd,
+ taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called),
+ ts -> ts_expedited, ts -> ts_tsdusize);
+#ifdef DEBUG
+ if (ts -> ts_cc > 0)
+ advise (LLOG_DEBUG, NULLCP, "greetings: %d octets", ts -> ts_cc);
+#endif
+
+ sd = ts -> ts_sd;
+
+ if (is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector,
+ ts -> ts_called.ta_selectlen))
+ for (ds = ts_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+
+ async = 0;
+ for (argv++; *argv; argv++) {
+ if (strcmp (*argv, "-async") == 0) {
+ async++;
+ continue;
+ }
+ if (strcmp (*argv, "-sync") == 0) {
+ async = 0;
+ continue;
+ }
+
+ advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+ }
+
+ switch (mymode) {
+ case echo:
+ case sink:
+ if (TConnResponse (sd, NULLTA, ts -> ts_expedited,
+ mymode == echo ? ts -> ts_data : NULLCP,
+ mymode == echo ? ts -> ts_cc : 0, NULLQOS, td) == NOTOK)
+ ts_adios (td, "T-CONNECT.RESPONSE");
+ break;
+
+ default:
+ (void) strcpy (buffer, "entity unknown or unavailable");
+ if (TDiscRequest (sd, buffer, strlen (buffer) + 1, td) == NOTOK)
+ ts_adios (td, "T-DISCONNECT.REQUEST");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+ }
+
+ if (async) {
+ if (TSetIndications (sd, ts_dataindication, ts_discindication, td)
+ == NOTOK)
+ ts_adios (td, "set ASYNC fails");
+
+ for (;;)
+ pause ();
+ }
+
+ for (;;) {
+ if (TReadRequest (sd, tx, NOTOK, td) == NOTOK)
+ ts_discindication (sd, td);
+
+ ts_dataindication (sd, tx);
+ }
+}
+
+/* \f */
+
+static int ts_dataindication (sd, tx)
+int sd;
+register struct TSAPdata *tx;
+{
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ if (mymode == echo) {
+ register char *p = qb2str (&tx -> tx_qbuf);
+
+ if ((tx -> tx_expedited
+ ? TExpdRequest (sd, p, tx -> tx_cc, td)
+ : TDataRequest (sd, p, tx -> tx_cc, td))
+ == NOTOK) {
+ if (td -> td_reason == DR_NORMAL)
+ ts_discindication (sd, td);
+
+ ts_adios (td, tx -> tx_expedited ? "T-EXPEDITED-DATA.REQUEST"
+ : "T-DATA.REQUEST");
+ }
+
+ free (p);
+ }
+
+ TXFREE (tx);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int ts_discindication (sd, td)
+int sd;
+register struct TSAPdisconnect *td;
+{
+ if (td -> td_reason != DR_NORMAL)
+ ts_adios (td, "T-DISCONNECT.INDICATION");
+
+ if (td -> td_cc > 0)
+ ts_advise (td, "T-DISCONNECT.INDICATION");
+ else
+ advise (LLOG_NOTICE, NULLCP, "T-DISCONNECT.INDICATION");
+
+ exit (0);
+}
+
+/* \f */
+
+static void ts_adios (td, event)
+register struct TSAPdisconnect *td;
+char *event;
+{
+ ts_advise (td, event);
+
+ _exit (1);
+}
+
+
+static void ts_advise (td, event)
+register struct TSAPdisconnect *td;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (td -> td_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ TErrString (td -> td_reason),
+ td -> td_cc, td -> td_cc, td -> td_data);
+ else
+ (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
+
+ advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f SSAP */
+
+#define RMASK \
+ "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
+\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+
+#define TMASK "\020\01DATA\03SYNC\05ACTIVITY\07RELEASE"
+
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ switch (ss -> ss_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ advise (LLOG_DEBUG, NULLCP, "%s token: choice", type); \
+ ss -> ss_settings &= ~(ST_MASK << shift); \
+ ss -> ss_settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_INIT_VALUE: \
+ advise (LLOG_DEBUG, NULLCP, "%s token: initiator", type); \
+ break; \
+ \
+ case ST_RESP_VALUE: \
+ advise (LLOG_DEBUG, NULLCP, "%s token: responder", type); \
+ owned |= bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ break; \
+ } \
+}
+
+
+static int requirements = 0;
+static int owned = 0;
+
+static struct SSAPdata hxs;
+static struct SSAPdata *hx = &hxs;
+
+/* \f */
+
+static int ss_main (argc, argv)
+int argc;
+char **argv;
+{
+ int async,
+ result,
+ sd;
+ char buffer[BUFSIZ];
+ register struct dispatch *ds;
+ register struct isoservent *is;
+ struct SSAPstart sss;
+ register struct SSAPstart *ss = &sss;
+ struct SSAPdata sxs;
+ register struct SSAPdata *sx = &sxs;
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if (SInit (argc, argv, ss, si) == NOTOK)
+ ss_adios (sa, "(S)initialization fails");
+ advise (LLOG_NOTICE, NULLCP,
+ "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>",
+ ss -> ss_sd, sprintref (&ss -> ss_connect),
+ saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called),
+ sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn,
+ ss -> ss_ssdusize);
+#ifdef DEBUG
+ if (ss -> ss_cc > 0)
+ advise (LLOG_DEBUG, NULLCP, "greetings: %d octets", ss -> ss_cc);
+#endif
+
+ sd = ss -> ss_sd;
+ ss -> ss_requirements &= SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
+ | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
+ | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
+ if ((ss -> ss_requirements & SR_HALFDUPLEX)
+ && (ss -> ss_requirements & SR_DUPLEX))
+ ss -> ss_requirements &= ~SR_DUPLEX;
+ requirements = ss -> ss_requirements;
+ advise (LLOG_DEBUG, NULLCP, "new requirements: %s",
+ sprintb (ss -> ss_requirements, RMASK));
+ dotokens ();
+ advise (LLOG_DEBUG, NULLCP, "initial tokens: %s", sprintb (owned, TMASK));
+ if (!(ss -> ss_requirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)))
+ ss -> ss_isn = SERIAL_NONE;
+
+ if (is = getisoserventbyselector ("ssap", ss -> ss_called.sa_selector,
+ ss -> ss_called.sa_selectlen))
+ for (ds = ss_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+
+ async = 0;
+ for (argv++; *argv; argv++) {
+ if (strcmp (*argv, "-async") == 0) {
+ async++;
+ continue;
+ }
+ if (strcmp (*argv, "-sync") == 0) {
+ async = 0;
+ continue;
+ }
+
+ advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+ }
+
+ switch (mymode) {
+ case echo:
+ case sink:
+ if (SConnResponse (sd, &ss -> ss_connect, NULLSA,
+ SC_ACCEPT, ss -> ss_requirements, ss -> ss_settings,
+ ss -> ss_isn, mymode == echo ? ss -> ss_data : NULLCP,
+ mymode == echo ? ss -> ss_cc : 0, si) == NOTOK)
+ ss_adios (sa, "S-CONNECT.RESPONSE (accept)");
+ break;
+
+ default:
+ (void) strcpy (buffer, "entity unknown or unavailable");
+ if (SConnResponse (sd, &ss -> ss_connect, NULLSA,
+ SC_REJECTED, 0, 0, SERIAL_NONE, buffer,
+ strlen (buffer + 1), si)
+ == NOTOK)
+ ss_adios (sa, "S-CONNECT.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+ }
+
+ if (async) {
+ if (SSetIndications (sd, ss_dataindication, ss_tokenindication,
+ ss_syncindication, ss_actindication, ss_reportindication,
+ ss_finishindication, ss_abortindication, si) == NOTOK)
+ ss_adios (sa, "set ASYNC fails");
+
+ for (;;)
+ pause ();
+ }
+
+ for (;;)
+ switch (result = SReadRequest (sd, sx, NOTOK, si)) {
+ case NOTOK:
+ ss_abortindication (sd, sa);
+
+ case OK:
+ ss_dataindication (sd, sx);
+ break;
+
+ case DONE:
+ switch (si -> si_type) {
+ case SI_TOKEN:
+ ss_tokenindication (sd, &si -> si_token);
+ break;
+
+ case SI_SYNC:
+ ss_syncindication (sd, &si -> si_sync);
+ break;
+
+ case SI_ACTIVITY:
+ ss_actindication (sd, &si -> si_activity);
+ break;
+
+ case SI_REPORT:
+ ss_reportindication (sd, &si -> si_report);
+ break;
+
+ case SI_FINISH:
+ ss_finishindication (sd, &si -> si_finish);
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=0x%x",
+ si -> si_type);
+ }
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from SReadRequest=%d", result);
+ }
+}
+
+#undef dotoken
+
+/* \f */
+
+static int ss_dataindication (sd, sx)
+int sd;
+register struct SSAPdata *sx;
+{
+ char *p,
+ buffer[BUFSIZ];
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+#ifdef DEBUG
+ switch (sx -> sx_type) {
+ case SX_NORMAL:
+ advise (LLOG_DEBUG, NULLCP, "normal data, %d bytes", sx -> sx_cc);
+ break;
+
+ case SX_EXPEDITED:
+ advise (LLOG_DEBUG, NULLCP, "expedited data, %d bytes",
+ sx -> sx_cc);
+ break;
+
+ case SX_TYPED:
+ advise (LLOG_DEBUG, NULLCP, "typed data, %d bytes", sx -> sx_cc);
+ break;
+
+ case SX_CAPDIND:
+ advise (LLOG_DEBUG, NULLCP, "capability data, %d bytes",
+ sx -> sx_cc);
+ break;
+
+ case SX_CAPDCNF:
+ advise (LLOG_DEBUG, NULLCP, "capability data ack, %d bytes",
+ sx -> sx_cc);
+
+ default:
+ advise (LLOG_DEBUG, NULLCP,
+ "unknown data indication type=0x%x, %d bytes",
+ sx -> sx_type, sx -> sx_cc);
+ }
+#endif
+
+ p = NULL;
+
+ switch (sx -> sx_type) {
+ case SX_NORMAL:
+ if (mymode == sink)
+ break;
+ if (requirements & SR_HALFDUPLEX) {
+ if (hx -> sx_cc > 0) {
+ (void) strcpy (buffer, "protocol screw-up");
+ if (SUAbortRequest (sd, buffer, strlen (buffer) + 1, si) == NOTOK)
+ ss_adios (sa, "S-U-ABORT.REQUEST");
+ else
+ adios (NULLCP, "protocol screw-up");
+ }
+ else {
+ *hx = *sx; /* struct copy */
+ hx -> sx_qbuf.qb_forw -> qb_back =
+ hx -> sx_qbuf.qb_back -> qb_forw = &hx -> sx_qbuf;
+ bzero ((char *) sx, sizeof *sx);
+ sx -> sx_qbuf.qb_forw =
+ sx -> sx_qbuf.qb_back = &sx -> sx_qbuf;
+ if (!(owned & ST_DAT_TOKEN)
+ && SPTokenRequest (sd, ST_DAT_TOKEN, NULLCP,
+ 0, si) == NOTOK)
+ ss_adios (sa, "S-TOKEN-PLEASE.REQUEST");
+ }
+ }
+ else
+ if (SDataRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+ si) == NOTOK)
+ ss_adios (sa, "S-DATA.REQUEST");
+ break;
+
+ case SX_EXPEDITED:
+ if (mymode == sink)
+ break;
+ if (SExpdRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+ si) == NOTOK)
+ ss_adios (sa, "S-EXPEDITED-DATA.REQUEST");
+ break;
+
+ case SX_TYPED:
+ if (mymode == sink)
+ break;
+ if (STypedRequest (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+ si) == NOTOK)
+ ss_adios (sa, "S-TYPED-DATA.REQUEST");
+ break;
+
+ case SX_CAPDIND:
+ if (SCapdResponse (sd, p = qb2str (&sx -> sx_qbuf), sx -> sx_cc,
+ si) == NOTOK)
+ ss_adios (sa, "S-CAPABILITY-DATA.REQUEST");
+ break;
+
+ case SX_CAPDCNF:
+ adios (NULLCP, "got capability data response");
+
+ default:
+ adios (NULLCP, "unknown data indication type=0x%x", sx -> sx_type);
+ }
+
+ SXFREE (sx);
+ if (p)
+ free (p);
+}
+
+/* \f */
+
+static int ss_tokenindication (sd, st)
+int sd;
+register struct SSAPtoken *st;
+{
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+#ifdef DEBUG
+ advise (LLOG_DEBUG, NULLCP, "%s tokens: %s, %d bytes",
+ st -> st_type == ST_PLEASE ? "please"
+ : st -> st_type == ST_GIVE ? "give" : "control",
+ sprintb ((int) st -> st_tokens, TMASK), st -> st_cc);
+#endif
+
+ switch (st -> st_type) {
+ case ST_GIVE:
+ case ST_CONTROL:
+ owned = st -> st_owned;
+ break;
+
+ case ST_PLEASE:
+ break;
+
+ default:
+ adios (NULLCP, "unknown token indication type=0x%x",
+ st -> st_type);
+ }
+
+ if ((owned & ST_DAT_TOKEN) && hx -> sx_cc > 0) {
+ char *p;
+
+ if (SDataRequest (sd, p = qb2str (&hx -> sx_qbuf), hx -> sx_cc, si)
+ == NOTOK)
+ ss_adios (sa, "S-DATA.REQUEST");
+ SXFREE (hx);
+ free (p);
+ bzero ((char *) hx, sizeof *hx);
+ hx -> sx_qbuf.qb_forw =
+ hx -> sx_qbuf.qb_back = &hx -> sx_qbuf;
+ }
+
+ switch (st -> st_type) {
+ case ST_GIVE:
+ break;
+
+ default:
+ if (SGTokenRequest (sd, (int) st -> st_tokens, si) == NOTOK)
+ ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~st -> st_tokens;
+ break;
+ }
+
+ STFREE (st);
+}
+
+/* \f */
+
+static int ss_syncindication (sd, sn)
+int sd;
+register struct SSAPsync *sn;
+{
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+#ifdef DEBUG
+ switch (sn -> sn_type) {
+ case SN_MAJORIND:
+ advise (LLOG_DEBUG, NULLCP, "majorsync indication %d, %d bytes",
+ sn -> sn_ssn, sn -> sn_cc);
+ break;
+
+ case SN_MAJORCNF:
+ advise (LLOG_DEBUG, NULLCP, "majorsync confirmation %d, %d bytes",
+ sn -> sn_ssn, sn -> sn_cc);
+ break;
+
+ case SN_MINORIND:
+ advise (LLOG_DEBUG, NULLCP, "minorsync indication %d%s, %d bytes",
+ sn -> sn_ssn, sn -> sn_options == SYNC_CONFIRM
+ ? " (wants confirmation)" : NULLCP, sn -> sn_cc);
+ break;
+
+ case SN_MINORCNF:
+ advise (LLOG_DEBUG, NULLCP, "minorsync confirmation %d, %d bytes",
+ sn -> sn_ssn, sn -> sn_cc);
+ break;
+
+ case SN_RESETIND:
+ advise (LLOG_DEBUG, NULLCP,
+ "resync indication type=%d %d, %d bytes",
+ sn -> sn_options, sn -> sn_ssn, sn -> sn_cc);
+ break;
+
+ case SN_RESETCNF:
+ advise (LLOG_DEBUG, NULLCP, "resync confirmation %d, %d bytes",
+ sn -> sn_ssn, sn -> sn_cc);
+ break;
+
+ default:
+ advise (LLOG_DEBUG, NULLCP,
+ "unknown sync indication=0x%x, ssn=%d, %d bytes",
+ sn -> sn_type, sn -> sn_ssn, sn -> sn_cc);
+ break;
+ }
+#endif
+
+ switch (sn -> sn_type) {
+ case SN_MAJORIND:
+ if (SMajSyncResponse (sd,
+ mymode == echo ? sn -> sn_data : NULL,
+ mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
+ ss_adios (sa, "S-MAJOR-SYNC.RESPONSE");
+ break;
+
+ case SN_MAJORCNF:
+ adios (NULLCP, "got majorsync confirmation");
+
+ case SN_MINORIND:
+ if (sn -> sn_options == SYNC_CONFIRM)
+ if (SMinSyncResponse (sd, sn -> sn_ssn,
+ mymode == echo ? sn -> sn_data : NULL,
+ mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
+ ss_adios (sa, "S-MINOR-SYNC.RESPONSE");
+ break;
+
+ case SN_MINORCNF:
+ adios (NULLCP, "got minorsync confirmation");
+
+ case SN_RESETIND:
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (requirements & requires) \
+ switch (sn -> sn_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ sn -> sn_settings &= ~(ST_MASK << shift); \
+ sn -> sn_settings |= ST_RESP_VALUE << shift; \
+ case ST_RESP_VALUE << shift: \
+ owned |= bit; \
+ break; \
+ \
+ case ST_INIT_VALUE << shift: \
+ owned &= ~bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ break; \
+ } \
+}
+ dotokens ();
+#undef dotoken
+ if (SReSyncRequest (sd, SYNC_ABANDON, SERIAL_NONE,
+ sn -> sn_settings,
+ mymode == echo ? sn -> sn_data : NULL,
+ mymode == echo ? sn -> sn_cc : 0, si) == NOTOK)
+ ss_adios (sa, "S-RESYNCHRONIZE.REQUEST");
+ break;
+
+ case SN_RESETCNF:
+ break;
+
+ default:
+ adios (NULLCP, "unknown sync indication type=0x%x", sn -> sn_type);
+ }
+
+ SNFREE (sn);
+}
+
+/* \f */
+
+static int ss_actindication (sd, sv)
+int sd;
+register struct SSAPactivity *sv;
+{
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+#ifdef DEBUG
+ switch (sv -> sv_type) {
+ case SV_START:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity start indication: %*.*s, %d bytes",
+ sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+ sv -> sv_id.sd_data, sv -> sv_cc);
+ break;
+
+ case SV_RESUME:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d, %d bytes",
+ sv -> sv_id.sd_len, sv -> sv_id.sd_len,
+ sv -> sv_id.sd_data, sv -> sv_oid.sd_len,
+ sv -> sv_oid.sd_len, sv -> sv_oid.sd_data,
+ sprintref (&sv -> sv_connect), sv -> sv_ssn, sv -> sv_cc);
+ break;
+
+ case SV_INTRIND:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity interrupt indication %d, %d bytes",
+ sv -> sv_reason, sv -> sv_cc);
+ break;
+
+ case SV_INTRCNF:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity interrupt confirmation, %d bytes", sv -> sv_cc);
+ break;
+
+ case SV_DISCIND:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity discard indication %d, %d bytes",
+ sv -> sv_reason, sv -> sv_cc);
+ break;
+
+ case SV_DISCCNF:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity discard confirmation, %d bytes", sv -> sv_cc);
+ break;
+
+ case SV_ENDIND:
+ advise (LLOG_DEBUG, NULLCP, "activity end indication %d, %d bytes",
+ sv -> sv_ssn, sv -> sv_cc);
+ break;
+
+ case SV_ENDCNF:
+ advise (LLOG_DEBUG, NULLCP, "activity end confirmation, %d bytes",
+ sv -> sv_cc);
+ break;
+
+ default:
+ advise (LLOG_DEBUG, NULLCP,
+ "unknown activity indication=0x%x, %d bytes",
+ sv -> sv_type, sv -> sv_cc);
+ break;
+ }
+#endif
+
+ switch (sv -> sv_type) {
+ case SV_START:
+ case SV_RESUME:
+ break;
+
+ case SV_INTRIND:
+ if (SActIntrResponse (sd, si) == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-INTERRUPT.RESPONSE");
+ owned = 0;
+ break;
+
+ case SV_INTRCNF:
+ adios (NULLCP, "got activity interrupt confirmation");
+
+ case SV_DISCIND:
+ if (SActDiscResponse (sd, si) == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-DISCARD.RESPONSE");
+ owned = 0;
+ break;
+
+ case SV_DISCCNF:
+ adios (NULLCP, "got activity discard confirmation");
+
+ case SV_ENDIND:
+ if (SActEndResponse (sd, mymode == echo ? sv -> sv_data : NULLCP,
+ mymode == echo ? sv -> sv_cc : 0, si) == NOTOK)
+ ss_adios (sa, "S-ACTIVITY-END.RESPONSE");
+ break;
+
+ case SV_ENDCNF:
+ adios (NULLCP, "got activity end confirmation");
+
+ default:
+ adios (NULLCP, "unknown activity indication=0x%x", sv -> sv_type);
+ }
+
+ SVFREE (sv);
+}
+
+/* \f */
+
+static int ss_reportindication (sd, sp)
+int sd;
+struct SSAPreport *sp;
+{
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+#ifdef DEBUG
+ advise (LLOG_DEBUG, NULLCP, "%s report %d, %d bytes",
+ sp -> sp_peer ? "user" : "provider", sp -> sp_reason, sp -> sp_cc);
+#endif
+
+ if (requirements & SR_DAT_EXISTS) {
+ if (SGTokenRequest (sd, ST_DAT_TOKEN, si) == NOTOK)
+ ss_adios (sa, "S-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~ST_DAT_TOKEN;
+#ifdef DEBUG
+ advise (LLOG_DEBUG, NULLCP, "cleared");
+#endif
+ }
+ else
+ if (SUAbortRequest (sd, NULLCP, 0, si) == NOTOK)
+ ss_adios (sa, "S-U-ABORT.REQUEST");
+ else
+ adios (NULLCP, "aborted");
+
+ SPFREE (sp);
+}
+
+/* \f */
+
+static int ss_finishindication (sd, sf)
+int sd;
+register struct SSAPfinish *sf;
+{
+ struct SSAPindication sis;
+ register struct SSAPindication *si = &sis;
+ register struct SSAPabort *sa = &si -> si_abort;
+
+ if (sf -> sf_cc > 0)
+ advise (LLOG_NOTICE, NULLCP, "S-RELEASE.INDICATION: %d bytes",
+ sf -> sf_cc);
+ else
+ advise (LLOG_NOTICE, NULLCP, "S-RELEASE.INDICATION");
+
+ if (SRelResponse (sd, SC_ACCEPT, mymode == echo ? sf -> sf_data : NULL,
+ mymode == echo ? sf -> sf_cc : 0, si) == NOTOK)
+ ss_adios (sa, "S-RELEASE.RESPONSE");
+
+ SFFREE (sf);
+
+ exit (0);
+}
+
+
+/* ARGSUSED */
+
+static int ss_abortindication (sd, sa)
+int sd;
+register struct SSAPabort *sa;
+{
+ if (!sa -> sa_peer)
+ ss_adios (sa, "S-P-ABORT.INDICATION");
+
+ if (sa -> sa_cc > 0)
+ ss_advise (sa, "S-U-ABORT.INDICATION");
+ else
+ advise (LLOG_NOTICE, NULLCP, "S-U-ABORT.INDICATION");
+
+ exit (1);
+}
+
+/* \f */
+
+static void ss_adios (sa, event)
+register struct SSAPabort *sa;
+char *event;
+{
+ ss_advise (sa, event);
+
+ _exit (1);
+}
+
+
+static void ss_advise (sa, event)
+register struct SSAPabort *sa;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (sa -> sa_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ SErrString (sa -> sa_reason),
+ sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
+ else
+ (void) sprintf (buffer, "[%s]", SErrString (sa -> sa_reason));
+
+ advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+
+ SAFREE (sa);
+}
+
+/* \f PSAP */
+
+#define PMASK \
+ "\020\01MANAGEMENT\02RESTORATION"
+
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (srequirements & requires) \
+ switch (ps -> ps_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ advise (LLOG_DEBUG, NULLCP, "%s token: choice", type); \
+ ps -> ps_settings &= ~(ST_MASK << shift); \
+ ps -> ps_settings |= ST_INIT_VALUE << shift; \
+ break; \
+ \
+ case ST_INIT_VALUE: \
+ advise (LLOG_DEBUG, NULLCP, "%s token: initiator", type); \
+ break; \
+ \
+ case ST_RESP_VALUE: \
+ advise (LLOG_DEBUG, NULLCP, "%s token: responder", type); \
+ owned |= bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ break; \
+ } \
+}
+
+
+static int prequirements = 0;
+#define srequirements requirements
+
+static struct PSAPdata ixs;
+static struct PSAPdata *ix = &ixs;
+
+/* \f */
+
+static int ps_main (argc, argv)
+int argc;
+char **argv;
+{
+ int async,
+ result,
+ sd;
+#ifdef DEBUG
+ int i;
+#endif
+ register struct dispatch *ds;
+ register struct isoservent *is;
+ struct PSAPdata pxs;
+ register struct PSAPdata *px = &pxs;
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+ struct AcSAPstart acss;
+ register struct AcSAPstart *acs = &acss;
+ register struct PSAPstart *ps = &acs -> acs_start;
+ register struct PSAPctxlist *pl = &ps -> ps_ctxlist;
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+
+ if (isacs) {
+ if (AcInit (argc, argv, acs, aci) == NOTOK)
+ acs_adios (aca, "(Ac)initialization fails");
+
+ advise (LLOG_NOTICE, NULLCP,
+ "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
+ acs -> acs_sd, oid2ode (acs -> acs_context),
+ sprintaei (&acs -> acs_callingtitle),
+ sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
+
+ advise (LLOG_NOTICE, NULLCP,
+ "PSAP: <%d, %s, %s, %d, %s,",
+ ps -> ps_sd,
+ paddr2str (&ps -> ps_calling, NULLNA),
+ paddr2str (&ps -> ps_called, NULLNA),
+ pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
+ advise (LLOG_NOTICE, NULLCP,
+ " %s, %d, %d>",
+ sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+ ps -> ps_ssdusize);
+
+ sd = acs -> acs_sd;
+ }
+ else {
+ if (PInit (argc, argv, ps, pi) == NOTOK)
+ ps_adios (pa, "(P)initialization fails");
+ advise (LLOG_NOTICE, NULLCP,
+ "P-CONNECT.INDICATION: <%d, %s, %s, %d, %s,",
+ ps -> ps_sd,
+ paddr2str (&ps -> ps_calling, NULLNA),
+ paddr2str (&ps -> ps_called, NULLNA),
+ pl -> pc_nctx,
+ sprintb (ps -> ps_prequirements, PMASK));
+ advise (LLOG_NOTICE, NULLCP,
+ " %s, %d, %d>",
+ sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+ ps -> ps_ssdusize);
+
+ sd = ps -> ps_sd;
+ }
+#ifdef DEBUG
+ if (ps -> ps_ninfo > 0)
+ advise (LLOG_DEBUG, NULLCP, "greetings: %d elements", ps -> ps_ninfo);
+
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (LLOG_DEBUG, NULLCP, " ctx %d: %d %s 0x%x %d",
+ i, pl -> pc_ctx[i].pc_id, sprintoid (pl -> pc_ctx[i].pc_asn),
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ if (ps -> ps_defctx)
+ advise (LLOG_DEBUG, NULLCP, " default: %s %d",
+ sprintoid (ps -> ps_defctx), ps -> ps_defctxresult);
+#endif
+
+ ps -> ps_prequirements &= PR_MANAGEMENT | PR_RESTORATION;
+ prequirements = ps -> ps_prequirements;
+ advise (LLOG_DEBUG, NULLCP, "new presentation requirements: %s",
+ sprintb (ps -> ps_prequirements, PMASK));
+ ps -> ps_srequirements &= SR_HALFDUPLEX | SR_DUPLEX | SR_EXPEDITED
+ | SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC | SR_ACTIVITY
+ | SR_NEGOTIATED | SR_CAPABILITY | SR_EXCEPTIONS | SR_TYPEDATA;
+ if ((ps -> ps_srequirements & SR_HALFDUPLEX)
+ && (ps -> ps_srequirements & SR_DUPLEX))
+ ps -> ps_srequirements &= ~SR_DUPLEX;
+ srequirements = ps -> ps_srequirements;
+ advise (LLOG_DEBUG, NULLCP, "new session requirements: %s",
+ sprintb (ps -> ps_srequirements, RMASK));
+ dotokens ();
+ advise (LLOG_DEBUG, NULLCP, "initial tokens: %s", sprintb (owned, TMASK));
+ if (!(ps -> ps_srequirements & (SR_MINORSYNC | SR_MAJORSYNC | SR_RESYNC)))
+ ps -> ps_isn = SERIAL_NONE;
+
+ if (isacs) {
+ struct TSAPaddr *ta = &ps -> ps_called.pa_addr.sa_addr;
+
+ if (is = getisoserventbyselector ("tsap", ta -> ta_selector,
+ ta -> ta_selectlen))
+ for (ds = acs_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+ }
+ else
+ if (is = getisoserventbyselector ("psap", ps -> ps_called.pa_selector,
+ ps -> ps_called.pa_selectlen))
+ for (ds = ps_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+
+ async = 0;
+ for (argv++; *argv; argv++) {
+ if (strcmp (*argv, "-async") == 0) {
+ async++;
+ continue;
+ }
+ if (strcmp (*argv, "-sync") == 0) {
+ async = 0;
+ continue;
+ }
+
+ advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+ }
+
+ if (isacs) {
+ switch (mymode) {
+ case echo:
+ if (AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL,
+ NULLOID, NULLAEI, NULLPA, pl,
+ ps -> ps_defctxresult, ps -> ps_prequirements,
+ ps -> ps_srequirements, ps -> ps_isn,
+ ps -> ps_settings, &ps -> ps_connect,
+ acs -> acs_info, acs -> acs_ninfo, aci) == NOTOK)
+ acs_adios (aca, "A-ASSOCIATE.RESPONSE (accept)");
+ break;
+
+ case sink:
+ if (AcAssocResponse (sd, ACS_ACCEPT, ACS_USER_NULL,
+ NULLOID, NULLAEI, NULLPA, pl,
+ ps -> ps_defctxresult, ps -> ps_prequirements,
+ ps -> ps_srequirements, ps -> ps_isn,
+ ps -> ps_settings, &ps -> ps_connect,
+ NULLPEP, 0, aci) == NOTOK)
+ acs_adios (aca, "A-ASSOCIATE.RESPONSE (accept)");
+ break;
+
+ default:
+ if (AcAssocResponse (sd, ACS_PERMANENT, ACS_CONTEXT,
+ NULLOID, NULLAEI, NULLPA, pl,
+ ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0,
+ &ps -> ps_connect, NULLPEP, 0, aci) == NOTOK)
+ acs_adios (aca, "A-ASSOCIATE.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+ }
+
+ ACSFREE (acs);
+
+ {
+ struct RoSAPindication rois;
+ register struct RoSAPpreject *rop = &rois.roi_preject;
+
+ if (RoSetService (sd, RoPService, &rois) == NOTOK)
+ ros_adios (rop, "set RO/PS fails");
+ }
+
+ do_ros (sd, async);
+ return;
+ }
+ else {
+ switch (mymode) {
+ case echo:
+ if (PConnResponse (sd, PC_ACCEPT, NULLPA,
+ pl, ps -> ps_defctxresult,
+ ps -> ps_prequirements, ps -> ps_srequirements,
+ ps -> ps_isn, ps -> ps_settings, &ps -> ps_connect,
+ ps -> ps_info, ps -> ps_ninfo, pi) == NOTOK)
+ ps_adios (pa, "P-CONNECT.RESPONSE (accept)");
+ break;
+
+ case sink:
+ if (PConnResponse (sd, PC_ACCEPT, NULLPA,
+ pl, ps -> ps_defctxresult,
+ ps -> ps_prequirements, ps -> ps_srequirements,
+ ps -> ps_isn, ps -> ps_settings, &ps -> ps_connect,
+ NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-CONNECT.RESPONSE (accept)");
+ break;
+
+ default:
+ if (PConnResponse (sd, PC_REJECTED, NULLPA,
+ pl, ps -> ps_defctxresult, 0, 0, SERIAL_NONE, 0,
+ &ps -> ps_connect, NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-CONNECT.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+ }
+
+ PSFREE (ps);
+ }
+
+ if (async) {
+ if (PSetIndications (sd, ps_dataindication, ps_tokenindication,
+ ps_syncindication, ps_actindication, ps_reportindication,
+ ps_finishindication, ps_abortindication, pi) == NOTOK)
+ ps_adios (pa, "set ASYNC fails");
+
+ for (;;)
+ pause ();
+ }
+
+ for (;;)
+ switch (result = PReadRequest (sd, px, NOTOK, pi)) {
+ case NOTOK:
+ ps_abortindication (sd, pa);
+
+ case OK:
+ ps_dataindication (sd, px);
+ break;
+
+ case DONE:
+ switch (pi -> pi_type) {
+ case PI_TOKEN:
+ ps_tokenindication (sd, &pi -> pi_token);
+ break;
+
+ case PI_SYNC:
+ ps_syncindication (sd, &pi -> pi_sync);
+ break;
+
+ case PI_ACTIVITY:
+ ps_actindication (sd, &pi -> pi_activity);
+ break;
+
+ case PI_REPORT:
+ ps_reportindication (sd, &pi -> pi_report);
+ break;
+
+ case PI_FINISH:
+ ps_finishindication (sd, &pi -> pi_finish);
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=0x%x",
+ pi -> pi_type);
+ }
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from PReadRequest=%d", result);
+ }
+}
+
+#undef dotoken
+
+/* \f */
+
+static int ps_dataindication (sd, px)
+int sd;
+register struct PSAPdata *px;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+ switch (px -> px_type) {
+ case SX_NORMAL:
+ advise (LLOG_DEBUG, NULLCP, "normal data, %d elements",
+ px -> px_ninfo);
+ break;
+
+ case SX_EXPEDITED:
+ advise (LLOG_DEBUG, NULLCP, "expedited data, %d elements",
+ px -> px_ninfo);
+ break;
+
+ case SX_TYPED:
+ advise (LLOG_DEBUG, NULLCP, "typed data, %d elements",
+ px -> px_ninfo);
+ break;
+
+ case SX_CAPDIND:
+ advise (LLOG_DEBUG, NULLCP, "capability data, %d elements",
+ px -> px_ninfo);
+ break;
+
+ case SX_CAPDCNF:
+ advise (LLOG_DEBUG, NULLCP, "capability data ack, %d elements",
+ px -> px_ninfo);
+
+ default:
+ advise (LLOG_DEBUG, NULLCP,
+ "unknown data indication type=0x%x, %d elements",
+ px -> px_type, px -> px_ninfo);
+ }
+#endif
+
+ switch (px -> px_type) {
+ case SX_NORMAL:
+ if (mymode == sink)
+ break;
+ if (srequirements & SR_HALFDUPLEX) {
+ if (ix -> px_ninfo) {
+ if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-U-ABORT.REQUEST");
+ else
+ adios (NULLCP, "protocol screw-up");
+ }
+ else {
+ *ix = *px; /* struct copy */
+ bzero ((char *) px, sizeof *px);
+ if (!(owned & ST_DAT_TOKEN)
+ && PPTokenRequest (sd, ST_DAT_TOKEN, NULLPEP,
+ 0, pi) == NOTOK)
+ ps_adios (pa, "P-TOKEN-PLEASE.REQUEST");
+ }
+ }
+ else
+ if (PDataRequest (sd, px -> px_info, px -> px_ninfo, pi)
+ == NOTOK)
+ ps_adios (pa, "P-DATA.REQUEST");
+ break;
+
+ case SX_EXPEDITED:
+ if (mymode == sink)
+ break;
+ if (PExpdRequest (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
+ ps_adios (pa, "P-EXPEDITED-DATA.REQUEST");
+ break;
+
+ case SX_TYPED:
+ if (mymode == sink)
+ break;
+ if (PTypedRequest (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
+ ps_adios (pa, "P-TYPED-DATA.REQUEST");
+ break;
+
+ case SX_CAPDIND:
+ if (PCapdResponse (sd, px -> px_info, px -> px_ninfo, pi) == NOTOK)
+ ps_adios (pa, "P-CAPABILITY-DATA.REQUEST");
+ break;
+
+ case SX_CAPDCNF:
+ adios (NULLCP, "got capability data response");
+
+ default:
+ adios (NULLCP, "unknown data indication type=0x%x", px -> px_type);
+ }
+
+ PXFREE (px);
+}
+
+/* \f */
+
+static int ps_tokenindication (sd, pt)
+int sd;
+register struct PSAPtoken *pt;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+ advise (LLOG_DEBUG, NULLCP, "%s tokens: %s, %d elements",
+ pt -> pt_type == ST_PLEASE ? "please"
+ : pt -> pt_type == ST_GIVE ? "give" : "control",
+ sprintb ((int) pt -> pt_tokens, TMASK),
+ pt -> pt_ninfo);
+#endif
+
+ switch (pt -> pt_type) {
+ case ST_GIVE:
+ case ST_CONTROL:
+ owned = pt -> pt_owned;
+ break;
+
+ case ST_PLEASE:
+ break;
+
+ default:
+ adios (NULLCP, "unknown token indication type=0x%x",
+ pt -> pt_type);
+ }
+
+ if ((owned & ST_DAT_TOKEN) && ix -> px_ninfo)
+ if (PDataRequest (sd, ix -> px_info, ix -> px_ninfo, pi) == NOTOK)
+ ps_adios (pa, "P-DATA.REQUEST");
+ else {
+ PXFREE (ix);
+ bzero ((char *) ix, sizeof *ix);
+ }
+
+ switch (pt -> pt_type) {
+ case ST_GIVE:
+ break;
+
+ default:
+ if (PGTokenRequest (sd, (int) pt -> pt_tokens, pi) == NOTOK)
+ ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~pt -> pt_tokens;
+ break;
+ }
+
+ PTFREE (pt);
+}
+
+/* \f */
+
+static int ps_syncindication (sd, pn)
+int sd;
+register struct PSAPsync *pn;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+ switch (pn -> pn_type) {
+ case SN_MAJORIND:
+ advise (LLOG_DEBUG, NULLCP, "majorsync indication %d",
+ pn -> pn_ssn);
+ break;
+
+ case SN_MAJORCNF:
+ advise (LLOG_DEBUG, NULLCP, "majorsync confirmation %d",
+ pn -> pn_ssn);
+ break;
+
+ case SN_MINORIND:
+ advise (LLOG_DEBUG, NULLCP, "minorsync indication %d%s",
+ pn -> pn_ssn, pn -> pn_options == SYNC_CONFIRM
+ ? " (wants confirmation)" : NULLCP);
+ break;
+
+ case SN_MINORCNF:
+ advise (LLOG_DEBUG, NULLCP, "minorsync confirmation %d",
+ pn -> pn_ssn);
+ break;
+
+ case SN_RESETIND:
+ advise (LLOG_DEBUG, NULLCP, "resync indication type=%d %d",
+ pn -> pn_options, pn -> pn_ssn);
+ break;
+
+ case SN_RESETCNF:
+ advise (LLOG_DEBUG, NULLCP, "resync confirmation %d",
+ pn -> pn_ssn);
+ break;
+
+ default:
+ advise (LLOG_DEBUG, NULLCP, "unknown sync indication=0x%x, ssn=%d",
+ pn -> pn_type, pn -> pn_ssn);
+ break;
+ }
+ advise (LLOG_DEBUG, NULLCP, "%d elements", pn -> pn_ninfo);
+#endif
+
+ switch (pn -> pn_type) {
+ case SN_MAJORIND:
+ if (PMajSyncResponse (sd,
+ mymode == echo ? pn -> pn_info : NULLPEP,
+ mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
+ ps_adios (pa, "P-MAJOR-SYNC.RESPONSE");
+ break;
+
+ case SN_MAJORCNF:
+ adios (NULLCP, "got majorsync confirmation");
+
+ case SN_MINORIND:
+ if (pn -> pn_options == SYNC_CONFIRM)
+ if (PMinSyncResponse (sd, pn -> pn_ssn,
+ mymode == echo ? pn -> pn_info : NULLPEP,
+ mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
+ ps_adios (pa, "P-MINOR-SYNC.RESPONSE");
+ break;
+
+ case SN_MINORCNF:
+ adios (NULLCP, "got minorsync confirmation");
+
+ case SN_RESETIND:
+#define dotoken(requires,shift,bit,type) \
+{ \
+ if (srequirements & requires) \
+ switch (pn -> pn_settings & (ST_MASK << shift)) { \
+ case ST_CALL_VALUE << shift: \
+ pn -> pn_settings &= ~(ST_MASK << shift); \
+ pn -> pn_settings |= ST_RESP_VALUE << shift; \
+ case ST_RESP_VALUE << shift: \
+ owned |= bit; \
+ break; \
+ \
+ case ST_INIT_VALUE << shift: \
+ owned &= ~bit; \
+ break; \
+ \
+ default: \
+ adios (NULLCP, "%s token: reserved", type); \
+ break; \
+ } \
+}
+ dotokens ();
+#undef dotoken
+ if (PReSyncRequest (sd, SYNC_ABANDON, SERIAL_NONE,
+ pn -> pn_settings,
+ mymode == echo ? pn -> pn_info : NULLPEP,
+ mymode == echo ? pn -> pn_ninfo : 0, pi) == NOTOK)
+ ps_adios (pa, "P-RESYNCHRONIZE.REQUEST");
+ break;
+
+ case SN_RESETCNF:
+ break;
+
+ default:
+ adios (NULLCP, "unknown sync indication type=0x%x", pn -> pn_type);
+ }
+
+ PNFREE (pn);
+}
+
+/* \f */
+
+static int ps_actindication (sd, pv)
+int sd;
+register struct PSAPactivity *pv;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+ switch (pv -> pv_type) {
+ case SV_START:
+ advise (LLOG_DEBUG, NULLCP, "activity start indication: %*.*s",
+ pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+ pv -> pv_id.sd_data);
+ break;
+
+ case SV_RESUME:
+ advise (LLOG_DEBUG, NULLCP,
+ "activity resume indication: id=%*.*s oid=%*.*s connect=%s ssn=%d",
+ pv -> pv_id.sd_len, pv -> pv_id.sd_len,
+ pv -> pv_id.sd_data, pv -> pv_oid.sd_len,
+ pv -> pv_oid.sd_len, pv -> pv_oid.sd_data,
+ sprintref (&pv -> pv_connect), pv -> pv_ssn);
+ break;
+
+ case SV_INTRIND:
+ advise (LLOG_DEBUG, NULLCP, "activity interrupt indication %d",
+ pv -> pv_reason);
+ break;
+
+ case SV_INTRCNF:
+ advise (LLOG_DEBUG, NULLCP, "activity interrupt confirmation");
+ break;
+
+ case SV_DISCIND:
+ advise (LLOG_DEBUG, NULLCP, "activity discard indication %d",
+ pv -> pv_reason);
+ break;
+
+ case SV_DISCCNF:
+ advise (LLOG_DEBUG, NULLCP, "activity discard confirmation");
+ break;
+
+ case SV_ENDIND:
+ advise (LLOG_DEBUG, NULLCP, "activity end indication %d",
+ pv -> pv_ssn);
+ break;
+
+ case SV_ENDCNF:
+ advise (LLOG_DEBUG, NULLCP, "activity end confirmation");
+ break;
+
+ default:
+ advise (LLOG_DEBUG, NULLCP, "unknown activity indication=0x%x",
+ pv -> pv_type);
+ break;
+ }
+ advise (LLOG_DEBUG, NULLCP, "%d elements", pv -> pv_ninfo);
+#endif
+
+ switch (pv -> pv_type) {
+ case SV_START:
+ case SV_RESUME:
+ break;
+
+ case SV_INTRIND:
+ if (PActIntrResponse (sd, pi) == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-INTERRUPT.RESPONSE");
+ owned = 0;
+ break;
+
+ case SV_INTRCNF:
+ adios (NULLCP, "got activity interrupt confirmation");
+
+ case SV_DISCIND:
+ if (PActDiscResponse (sd, pi) == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-DISCARD.RESPONSE");
+ owned = 0;
+ break;
+
+ case SV_DISCCNF:
+ adios (NULLCP, "got activity discard confirmation");
+
+ case SV_ENDIND:
+ if (PActEndResponse (sd, mymode == echo ? pv -> pv_info : NULLPEP,
+ mymode == echo ? pv -> pv_ninfo : 0, pi) == NOTOK)
+ ps_adios (pa, "P-ACTIVITY-END.RESPONSE");
+ break;
+
+ case SV_ENDCNF:
+ adios (NULLCP, "got activity end confirmation");
+
+ default:
+ adios (NULLCP, "unknown activity indication=0x%x", pv -> pv_type);
+ }
+
+ PVFREE (pv);
+}
+
+/* \f */
+
+static int ps_reportindication (sd, pp)
+int sd;
+register struct PSAPreport *pp;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+
+#ifdef DEBUG
+ advise (LLOG_NOTICE, NULLCP, "%s report %d, %d elements",
+ pp -> pp_peer ? "user" : "provider", pp -> pp_reason,
+ pp -> pp_ninfo);
+#endif
+
+ if (srequirements & SR_DAT_EXISTS) {
+ if (PGTokenRequest (sd, ST_DAT_TOKEN, pi) == NOTOK)
+ ps_adios (pa, "P-TOKEN-GIVE.REQUEST");
+ else
+ owned &= ~ST_DAT_TOKEN;
+#ifdef DEBUG
+ advise (LLOG_DEBUG, NULLCP, "cleared");
+#endif
+ }
+ else
+ if (PUAbortRequest (sd, NULLPEP, 0, pi) == NOTOK)
+ ps_adios (pa, "P-U-ABORT.REQUEST");
+ else
+ adios (NULLCP, "aborted");
+
+ PPFREE (pp);
+}
+
+/* \f */
+
+static int ps_finishindication (sd, pf)
+int sd;
+register struct PSAPfinish *pf;
+{
+ struct PSAPindication pis;
+ register struct PSAPindication *pi = &pis;
+ register struct PSAPabort *pa = &pi -> pi_abort;
+ struct AcSAPindication acis;
+ register struct AcSAPabort *aca = &acis.aci_abort;
+ register struct AcSAPfinish *acf = &acis.aci_finish;
+
+ if (isacs) {
+ if (AcFINISHser (sd, pf, &acis) == NOTOK)
+ acs_adios (aca, "AcFINISHser");
+ ros_finish (sd, acf);
+ return;
+ }
+
+ advise (LLOG_NOTICE, NULLCP, "P-RELEASE.INDICATION: %d elements",
+ pf -> pf_ninfo);
+
+ if (PRelResponse (sd, SC_ACCEPT, mymode == echo ? pf -> pf_info : NULLPEP,
+ mymode == echo ? pf -> pf_ninfo : 0, pi) == NOTOK)
+ ps_adios (pa, "P-RELEASE.RESPONSE");
+
+ PFFREE (pf);
+
+ exit (0);
+}
+
+
+/* ARGSUSED */
+
+static int ps_abortindication (sd, pa)
+int sd;
+register struct PSAPabort *pa;
+{
+ struct AcSAPindication acis;
+ register struct AcSAPindication *aci = &acis;
+ register struct AcSAPabort *aca = &aci -> aci_abort;
+
+ if (isacs) {
+ if (AcABORTser (sd, pa, aci) == NOTOK)
+ acs_adios (aca, "AcABORTser");
+ advise (LLOG_NOTICE, NULLCP, "A-%sABORT.INDICATION: [%s] %d elements",
+ aca -> aca_source != ACA_USER ? "P-" : "",
+ AcErrString (aca -> aca_reason), aca -> aca_ninfo);
+
+ ACAFREE (aca);
+
+ exit (1);
+ }
+
+ if (!pa -> pa_peer)
+ ps_adios (pa, "P-P-ABORT.INDICATION");
+
+ advise (LLOG_NOTICE, NULLCP, "P-U-ABORT.INDICATION: %d elements",
+ pa -> pa_ninfo);
+ PAFREE (pa);
+
+ exit (1);
+}
+
+/* \f */
+
+static void ps_adios (pa, event)
+register struct PSAPabort *pa;
+char *event;
+{
+ ps_advise (pa, event);
+
+ _exit (1);
+}
+
+
+static void ps_advise (pa, event)
+register struct PSAPabort *pa;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (pa -> pa_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ PErrString (pa -> pa_reason),
+ pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
+ else
+ (void) sprintf (buffer, "[%s]", PErrString (pa -> pa_reason));
+
+ advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f AcSAP */
+
+static void acs_adios (aca, event)
+register struct AcSAPabort *aca;
+char *event;
+{
+ acs_advise (aca, event);
+
+ _exit (1);
+}
+
+
+static void acs_advise (aca, event)
+register struct AcSAPabort *aca;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (aca -> aca_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ AcErrString (aca -> aca_reason),
+ aca -> aca_cc, aca -> aca_cc, aca -> aca_data);
+ else
+ (void) sprintf (buffer, "[%s]", AcErrString (aca -> aca_reason));
+
+ advise (LLOG_NOTICE, NULLCP, "%s: %s (source %d)", event, buffer,
+ aca -> aca_source);
+}
+
+/* \f RtSAP */
+
+static int rts_main (argc, argv)
+int argc;
+char **argv;
+{
+ int async,
+ result,
+ ros,
+ sd;
+#ifdef DEBUG
+ int i;
+#endif
+ struct dispatch *ds;
+ struct isoservent *is;
+ struct RtSAPstart rtss;
+ register struct RtSAPstart *rts = &rtss;
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+ register struct AcSAPstart *acs = &rts -> rts_start;
+ register struct PSAPstart *ps = &acs -> acs_start;
+ register struct PSAPctxlist *pl = &ps -> ps_ctxlist;
+
+ if (isacs) {
+ if (RtInit (argc, argv, rts, rti) == NOTOK)
+ rts_adios (rta, "(Rt)initialization fails");
+ advise (LLOG_NOTICE, NULLCP, "RT-OPEN.INDICATION: <%d, %s, %s, 0x%x>",
+ rts -> rts_sd,
+ rts -> rts_mode == RTS_TWA ? "twa" : "mono",
+ rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
+ rts -> rts_data);
+
+ advise (LLOG_NOTICE, NULLCP, "ACSE: <%d, %s, %s, %s, %d>",
+ acs -> acs_sd, oid2ode (acs -> acs_context),
+ sprintaei (&acs -> acs_callingtitle),
+ sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
+
+ advise (LLOG_NOTICE, NULLCP,
+ "PSAP: <%d, %s, %s, %d, %s,",
+ ps -> ps_sd,
+ paddr2str (&ps -> ps_calling, NULLNA),
+ paddr2str (&ps -> ps_called, NULLNA),
+ pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
+ advise (LLOG_NOTICE, NULLCP,
+ " %s, %d, %d>",
+ sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+ ps -> ps_ssdusize);
+
+#ifdef DEBUG
+ {
+ if (ps -> ps_ninfo > 0)
+ advise (LLOG_DEBUG, NULLCP, "greetings: %d elements",
+ ps -> ps_ninfo);
+
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (LLOG_DEBUG, NULLCP, " ctx %d: %d %s 0x%x %d",
+ i, pl -> pc_ctx[i].pc_id,
+ sprintoid (pl -> pc_ctx[i].pc_asn),
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ if (ps -> ps_defctx)
+ advise (LLOG_DEBUG, NULLCP, " default: %s %d",
+ sprintoid (ps -> ps_defctx), ps -> ps_defctxresult);
+ }
+#endif
+
+ }
+ else {
+ if (RtBInit (argc, argv, rts, rti) == NOTOK)
+ rts_adios (rta, "(RtB)initialization fails");
+ advise (LLOG_NOTICE, NULLCP,
+ "RT-BEGIN.INDICATION: <%d, %s, %s, <%d, %s>, 0x%x>",
+ rts -> rts_sd, rts -> rts_mode == RTS_TWA ? "twa" :"monologue",
+ rts -> rts_turn == RTS_RESPONDER ? "responder" : "initiator",
+ ntohs (rts -> rts_port),
+ saddr2str (&rts -> rts_initiator.rta_addr),
+ rts -> rts_data);
+ }
+
+ if (rts -> rts_data) {
+ if ((result = prim2num (rts -> rts_data)) == NOTOK
+ && rts -> rts_data -> pe_errno != PE_ERR_NONE)
+ adios (NULLCP, "error decoding hello: %s",
+ pe_error (rts -> rts_data -> pe_errno));
+
+ advise (LLOG_DEBUG, NULLCP, "received greetings of %d", result);
+
+ pe_free (rts -> rts_data);
+ if ((rts -> rts_data = int2prim (result = getpid ())) == NULLPE)
+ adios (NULLCP, "unable to allocate hello");
+ }
+
+ sd = rts -> rts_sd;
+
+ if (isacs) {
+ struct TSAPaddr *ta = &ps -> ps_called.pa_addr.sa_addr;
+
+ if (is = getisoserventbyselector ("tsap", ta -> ta_selector,
+ ta -> ta_selectlen))
+ for (ds = rtse_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+ }
+ else
+ if (is = getisoserventbyport ("rtsap", rts -> rts_port))
+ for (ds = rts_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+
+ async = 0;
+ ros = !isacs && strncmp (is -> is_entity, "ros_", strlen ("ros_")) == 0;
+ for (argv++; *argv; argv++) {
+ if (strcmp (*argv, "-async") == 0) {
+ async++;
+ continue;
+ }
+ if (strcmp (*argv, "-sync") == 0) {
+ async = 0;
+ continue;
+ }
+ if (strcmp (*argv, "-rtse") == 0)
+ continue;
+ if (strcmp (*argv, "-rose") == 0) {
+ ros++;
+ continue;
+ }
+
+ advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+ }
+
+ if (isacs) {
+ switch (mymode) {
+ case echo:
+ if (rts -> rts_mode == RTS_TWA)
+ goto rtse_accept;
+ rtse_reject: ;
+ if (RtOpenResponse (sd, ACS_USER_NOREASON, NULLOID, NULLAEI,
+ NULLPA, NULLPC, ps -> ps_defctxresult, NULLPE, rti)
+ == NOTOK)
+ rts_adios (rta, "RT-OPEN.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+
+ case sink:
+ if (rts -> rts_mode != RTS_TWA
+ && rts -> rts_turn != RTS_INITIATOR)
+ goto rtse_reject;
+ rtse_accept:
+ if (RtOpenResponse (sd, ACS_ACCEPT, NULLOID, NULLAEI,
+ NULLPA, pl, ps -> ps_defctxresult,
+ rts -> rts_data, rti) == NOTOK)
+ rts_adios (rta, "RT-OPEN.RESPONSE (accept)");
+ advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
+ break;
+
+ default:
+ goto rtse_reject;
+ }
+ }
+ else {
+ switch (mymode) {
+ case echo:
+ if (rts -> rts_mode == RTS_TWA)
+ goto accept;
+ reject: ;
+ if (RtBeginResponse (sd, RTS_MODE, NULLPE, rti) == NOTOK)
+ rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+
+ case sink:
+ if (rts -> rts_mode != RTS_TWA
+ && rts -> rts_turn != RTS_INITIATOR)
+ goto reject;
+ accept: ;
+ if (RtBeginResponse (sd, RTS_ACCEPT, rts -> rts_data, rti)
+ == NOTOK)
+ rts_adios (rta, "RT-BEGIN.RESPONSE (accept)");
+ advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
+ break;
+
+ default:
+ if (RtBeginResponse (sd, RTS_VALIDATE, NULLPE, rti) == NOTOK)
+ rts_adios (rta, "RT-BEGIN.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+ }
+ }
+
+ RTSFREE (rts);
+
+ if (ros) {
+ struct RoSAPindication rois;
+ register struct RoSAPpreject *rop = &rois.roi_preject;
+
+ if (RoSetService (sd, RoRtService, &rois) == NOTOK)
+ ros_adios (rop, "set RO/RT fails");
+
+ do_ros (sd, async);
+ return;
+ }
+
+ if (async) {
+ if (RtSetIndications (sd, rts_indication, rti) == NOTOK)
+ rts_adios (rta, "set ASYNC fails");
+
+ for (;;)
+ pause ();
+ }
+
+ for (;;)
+ switch (result = RtWaitRequest (sd, NOTOK, rti)) {
+ case NOTOK:
+ case OK:
+ case DONE:
+ rts_indication (sd, rti);
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from RtWaitRequest=%d", result);
+ }
+}
+
+/* \f */
+
+static int rts_indication (sd, rti)
+int sd;
+register struct RtSAPindication *rti;
+{
+ switch (rti -> rti_type) {
+ case RTI_TURN:
+ rts_turn (sd, &rti -> rti_turn);
+ break;
+
+ case RTI_TRANSFER:
+ rts_transfer (sd, &rti -> rti_transfer);
+ break;
+
+ case RTI_ABORT:
+ rts_abort (sd, &rti -> rti_abort);
+ break;
+
+ case RTI_CLOSE:
+ rts_close (sd, &rti -> rti_close);
+ break;
+
+ case RTI_FINISH:
+ rts_finish (sd, &rti -> rti_finish);
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=%d", rti -> rti_type);
+ }
+}
+
+/* \f */
+
+static int rts_turn (sd, rtu)
+int sd;
+register struct RtSAPturn *rtu;
+{
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+
+ if (rtu -> rtu_please) {
+ if (RtGTurnRequest (sd, rti) == NOTOK)
+ rts_adios (rta, "RT-TURN-GIVE.REQUEST");
+ }
+ else
+ if (apdupe) {
+ if (RtTransferRequest (sd, apdupe, NOTOK, rti) == NOTOK)
+ rts_adios (rta, "RT-TRANSFER.REQUEST");
+ pe_free (apdupe);
+ apdupe = NULLPE;
+ }
+}
+
+/* \f */
+
+static int rts_transfer (sd, rtt)
+int sd;
+register struct RtSAPtransfer *rtt;
+{
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+ static int priority = 1;
+
+ if (mymode == echo) {
+ if (apdupe)
+ adios (NULLCP, "protocol screw-up");
+ if (RtPTurnRequest (sd, priority++, rti) == NOTOK)
+ rts_adios (rta, "RT-TURN-PLEASE.REQUEST");
+ apdupe = rtt -> rtt_data;
+ }
+ else
+ RTTFREE (rtt);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int rts_abort (sd, rta)
+int sd;
+register struct RtSAPabort *rta;
+{
+ if (rta -> rta_peer)
+ rts_adios (rta, "RT-U-ABORT.INDICATION");
+
+ if (RTS_FATAL (rta -> rta_reason))
+ rts_adios (rta, "RT-P-ABORT.INDICATION");
+ rts_advise (rta, "RT-P-ABORT.INDICATION");
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int rts_close (sd, rtc)
+int sd;
+struct RtSAPclose *rtc;
+{
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+
+ advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
+
+ if (RtEndResponse (sd, rti) == NOTOK)
+ rts_adios (rta, "RT-END.RESPONSE");
+
+ exit (0);
+}
+
+/* \f */
+
+static int rts_finish (sd, acf)
+int sd;
+register struct AcSAPfinish *acf;
+{
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+
+ advise (LLOG_NOTICE, NULLCP, "RT-CLOSE.INDICATION: %d, %d elements",
+ acf -> acf_reason, acf -> acf_ninfo);
+
+ if (RtCloseResponse (sd, ACR_NORMAL, mymode == echo
+ ? acf -> acf_info[0] : NULLPE, rti) == NOTOK)
+ rts_adios (rta, "RT-CLOSE.RESPONSE");
+
+ ACFFREE (acf);
+
+ exit (0);
+}
+
+/* \f */
+
+static void rts_adios (rta, event)
+register struct RtSAPabort *rta;
+char *event;
+{
+ rts_advise (rta, event);
+
+ _exit (1);
+}
+
+
+static void rts_advise (rta, event)
+register struct RtSAPabort *rta;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (rta -> rta_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s", RtErrString (rta -> rta_reason),
+ rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
+ else
+ (void) sprintf (buffer, "[%s]", RtErrString (rta -> rta_reason));
+
+ advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f RoSAP */
+
+static int ros_main (argc, argv)
+int argc;
+char **argv;
+{
+ int async,
+ result,
+ sd;
+ struct dispatch *ds;
+ struct isoservent *is;
+ struct RoSAPstart ross;
+ register struct RoSAPstart *ros = &ross;
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+
+ if (RoInit (argc, argv, ros, roi) == NOTOK)
+ ros_adios (rop, "(Ro)initialization fails");
+ advise (LLOG_NOTICE, NULLCP, "RO-BEGIN.INDICATION: <%d, <%d, %s>, 0x%x>",
+ ros -> ros_sd,
+ ntohs (ros -> ros_port),
+ saddr2str (&ros -> ros_initiator.roa_addr),
+ ros -> ros_data);
+ if (ros -> ros_data) {
+ if ((result = prim2num (ros -> ros_data)) == NOTOK
+ && ros -> ros_data -> pe_errno != PE_ERR_NONE)
+ adios (NULLCP, "error decoding hello: %s",
+ pe_error (ros -> ros_data -> pe_errno));
+
+ advise (LLOG_DEBUG, NULLCP, "received greetings of %d", result);
+
+ pe_free (ros -> ros_data);
+ if ((ros -> ros_data = int2prim (result = getpid ())) == NULLPE)
+ adios (NULLCP, "unable to allocate hello");
+ }
+
+ sd = ros -> ros_sd;
+
+ if (is = getisoserventbyport ("rosap", ros -> ros_port))
+ for (ds = ros_dispatches; ds -> ds_entity; ds++)
+ if (strcmp (ds -> ds_entity, is -> is_entity) == 0) {
+ mymode = ds -> ds_mode;
+ break;
+ }
+
+ async = 0;
+ for (argv++; *argv; argv++) {
+ if (strcmp (*argv, "-async") == 0) {
+ async++;
+ continue;
+ }
+ if (strcmp (*argv, "-sync") == 0) {
+ async = 0;
+ continue;
+ }
+
+ advise (LLOG_NOTICE, NULLCP, "unknown argument \"%s\"", *argv);
+ }
+
+ switch (mymode) {
+ case echo:
+ case sink:
+ if (RoBeginResponse (sd, ROS_ACCEPT, ros -> ros_data, roi)
+ == NOTOK)
+ ros_adios (rop, "RO-BEGIN.RESPONSE (accept)");
+ advise (LLOG_DEBUG, NULLCP, "sent greetings of %d", result);
+ break;
+
+ default:
+ if (RoBeginResponse (sd, ROS_VALIDATE, NULLPE, roi) == NOTOK)
+ ros_adios (rop, "RO-BEGIN.RESPONSE (reject)");
+ advise (LLOG_NOTICE, NULLCP, "rejected");
+ exit (1);
+ }
+
+ ROSFREE (ros);
+
+ do_ros (sd, async);
+}
+
+/* \f */
+
+static int do_ros (sd, async)
+int sd,
+ async;
+{
+ int result;
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+
+ if ((nullpe = pe_alloc (PE_CLASS_UNIV, PE_FORM_PRIM, PE_PRIM_NULL))
+ == NULLPE)
+ adios (NULLCP, "unable to allocate NULL PE");
+
+ if (async) {
+ if (RoSetIndications (sd, ros_indication, roi) == NOTOK)
+ ros_adios (rop, "set ASYNC fails");
+
+ for (;;)
+ pause ();
+ }
+
+ for (;;)
+ switch (result = RoWaitRequest (sd, NOTOK, roi)) {
+ case NOTOK:
+ case OK:
+ case DONE:
+ ros_indication (sd, roi);
+ break;
+
+ default:
+ adios (NULLCP, "unknown return from RoWaitRequest=%d", result);
+ }
+}
+
+/* \f */
+
+static int ros_indication (sd, roi)
+int sd;
+register struct RoSAPindication *roi;
+{
+ switch (roi -> roi_type) {
+ case ROI_INVOKE:
+ ros_invoke (sd, &roi -> roi_invoke);
+ break;
+
+ case ROI_RESULT:
+ ros_result (sd, &roi -> roi_result);
+ break;
+
+ case ROI_ERROR:
+ ros_error (sd, &roi -> roi_error);
+ break;
+
+ case ROI_UREJECT:
+ ros_ureject (sd, &roi -> roi_ureject);
+ break;
+
+ case ROI_PREJECT:
+ ros_preject (sd, &roi -> roi_preject);
+ break;
+
+ case ROI_END:
+ ros_end (sd, &roi -> roi_end);
+ break;
+
+ case ROI_FINISH:
+ ros_finish (sd, &roi -> roi_finish);
+ break;
+
+ default:
+ adios (NULLCP, "unknown indication type=%d", roi -> roi_type);
+ }
+}
+
+/* \f */
+
+static int ros_invoke (sd, rox)
+int sd;
+register struct RoSAPinvoke *rox;
+{
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+ static int ff = 0;
+
+ if (ff++ & 0x01) {
+ if (RoErrorRequest (sd, rox -> rox_id, ff,
+ mymode == echo ? rox -> rox_args : nullpe, ROS_NOPRIO,
+ roi) == NOTOK)
+ ros_adios (rop, "RO-ERROR.REQUEST");
+ }
+ else {
+ if (RoResultRequest (sd, rox -> rox_id, rox -> rox_op,
+ mymode == echo ? rox -> rox_args : nullpe, ROS_NOPRIO,
+ roi) == NOTOK)
+ ros_adios (rop, "RO-RESULT.REQUEST");
+ }
+
+ ROXFREE (rox);
+}
+
+/* \f */
+
+static int ros_result (sd, ror)
+int sd;
+register struct RoSAPresult *ror;
+{
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+
+ if (RoURejectRequest (sd, &ror -> ror_id, ROS_RRP_UNRECOG, ROS_NOPRIO, roi)
+ == NOTOK)
+ ros_adios (rop, "RO-REJECT-U.REQUEST");
+
+ RORFREE (ror);
+}
+
+/* \f */
+
+static int ros_error (sd, roe)
+int sd;
+register struct RoSAPerror *roe;
+{
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+
+ if (RoURejectRequest (sd, &roe -> roe_id, ROS_REP_UNRECOG, ROS_NOPRIO, roi)
+ == NOTOK)
+ ros_adios (rop, "RO-REJECT-U.REQUEST");
+
+ ROEFREE (roe);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int ros_ureject (sd, rou)
+int sd;
+register struct RoSAPureject *rou;
+{
+ if (rou -> rou_noid)
+ advise (LLOG_NOTICE, NULLCP, "RO-REJECT-U.INDICATION: %s",
+ RoErrString (rou -> rou_reason));
+ else
+ advise (LLOG_NOTICE, NULLCP, "RO-REJECT-U.INDICATION: %s (id=%d)",
+ RoErrString (rou -> rou_reason), rou -> rou_id);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int ros_preject (sd, rop)
+int sd;
+register struct RoSAPpreject *rop;
+{
+ if (ROS_FATAL (rop -> rop_reason))
+ ros_adios (rop, "RO-REJECT-P.INDICATION");
+ ros_advise (rop, "RO-REJECT-P.INDICATION");
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int ros_end (sd, roe)
+int sd;
+struct RoSAPend *roe;
+{
+ if (isrts) {
+ struct RtSAPindication rtis;
+ register struct RtSAPindication *rti = &rtis;
+ register struct RtSAPabort *rta = &rti -> rti_abort;
+
+ advise (LLOG_NOTICE, NULLCP, "RT-END.INDICATION");
+ if (RtEndResponse (sd, rti) == NOTOK)
+ rts_adios (rta, "RT-END.RESPONSE");
+ }
+ else {
+ struct RoSAPindication rois;
+ register struct RoSAPindication *roi = &rois;
+ register struct RoSAPpreject *rop = &roi -> roi_preject;
+
+ advise (LLOG_NOTICE, NULLCP, "RO-END.INDICATION");
+ if (RoEndResponse (sd, roi) == NOTOK)
+ ros_adios (rop, "RO-END.RESPONSE");
+ }
+
+ exit (0);
+}
+
+/* \f */
+
+static int ros_finish (sd, acf)
+int sd;
+register struct AcSAPfinish *acf;
+{
+ if (isrts) {
+ struct RtSAPindication rtis;
+ register struct RtSAPabort *rta = &rtis.rti_abort;
+
+ advise (LLOG_NOTICE, NULLCP, "RT-CLOSE.INDICATION: %d, %d elements",
+ acf -> acf_reason, acf -> acf_ninfo);
+
+ if (RtCloseResponse (sd, ACR_NORMAL, mymode == echo
+ ? acf -> acf_info[0] : NULLPE, &rtis) == NOTOK)
+ rts_adios (rta, "RT-CLOSE.RESPONSE");
+ }
+ else {
+ struct AcSAPindication acis;
+ register struct AcSAPabort *aca = &acis.aci_abort;
+
+ advise (LLOG_NOTICE, NULLCP, "A-RELEASE.INDICATION: %d, %d elements",
+ acf -> acf_reason, acf -> acf_ninfo);
+
+ if (AcRelResponse (sd, ACS_ACCEPT, ACR_NORMAL, mymode == echo
+ ? acf -> acf_info : NULLPEP, mymode == echo
+ ? acf -> acf_ninfo : 0, &acis) == NOTOK)
+ acs_adios (aca, "A-RELEASE.RESPONSE");
+ }
+
+ ACFFREE (acf);
+
+ exit (0);
+}
+
+/* \f */
+
+static void ros_adios (rop, event)
+register struct RoSAPpreject *rop;
+char *event;
+{
+ ros_advise (rop, event);
+
+ _exit (1);
+}
+
+
+static void ros_advise (rop, event)
+register struct RoSAPpreject *rop;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (rop -> rop_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s", RoErrString (rop -> rop_reason),
+ rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
+ else
+ (void) sprintf (buffer, "[%s]", RoErrString (rop -> rop_reason));
+
+ advise (LLOG_NOTICE, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f ERRORS */
+
+#ifndef lint
+void adios (va_alist)
+va_dcl
+{
+ va_list ap;
+
+ va_start (ap);
+
+ _ll_log (pgm_log, LLOG_FATAL, ap);
+
+ va_end (ap);
+
+ _exit (1);
+}
+#else
+/* VARARGS */
+
+void adios (what, fmt)
+char *what,
+ *fmt;
+{
+ adios (what, fmt);
+}
+#endif
+
+
+#ifndef lint
+void advise (va_alist)
+va_dcl
+{
+ int code;
+ va_list ap;
+
+ va_start (ap);
+
+ code = va_arg (ap, int);
+
+ _ll_log (pgm_log, code, ap);
+
+ va_end (ap);
+}
+#else
+/* VARARGS */
+
+void advise (code, what, fmt)
+char *what,
+ *fmt;
+int code;
+{
+ advise (code, what, fmt);
+}
+#endif
--- /dev/null
+.TH ISOENTITIES 5 "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isoentities.5,v 7.2 91/02/22 09:46:43 mrose Interim $
+.\"
+.\"
+.\" $Log: isoentities.5,v $
+.\" Revision 7.2 91/02/22 09:46:43 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.1 90/10/15 22:54:22 mrose
+.\" typo
+.\"
+.\" Revision 7.0 89/11/23 22:27:31 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+.B isoentities
+\- ISODE entities database
+.SH DESCRIPTION
+The \fIisoentities\fR file contains information regarding the known
+application-entity titles (AETs).
+This file is used by the stub\-directory service in ISODE.
+.PP
+\fBNB\0\fR: Use of this database is deprecated.
+Consult the ISODE \fIUser's Manual\fR for further information.
+.PP
+Entries are separated by blank lines (or the end\-of\-file).
+Items are separated by any number of blanks and/or tab characters,
+though double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+Each entry consists of four items:
+the first two,
+the designator and qualifier,
+for the object descriptor of the application-entity information
+(the distinguished designator \*(lqdefault\*(rq is used for a template entry);
+the third item is the object identifier of application-entity
+information in dot-notation
+(if no application-entity information is desired the string
+\*(lqNULL\*(rq should be used instead);
+and the fourth item is the entire presentation address expressed using
+the ISODE string format.
+Note that since double-quotes are often used in the new string format,
+it is \fBvery\fR important to quote them correctly in the
+\fIisoentities\fR file.
+Usually preceeding the first character of the address with single backslash
+is adequate.
+.PP
+It is suggested for readability purposes that a blank line should
+seperate entries.
+.PP
+Note that this database is used by the stub-directory service in ISODE.
+A real directory uses an entirely different mechanism for resolving lookups.
+The stub-directory mechanism in ISODE transforms the internal AET
+notion (the object identifiers) into one which appears to have come
+from a real directory (i.e., application-entity information).
+.SH "RFC1085 SUPPORT"
+Since applications using RFC1085 (the lightweight presentation protocol)
+usually demultiplex on the basis of TCP or UDP port,
+a further definition for the qualifier is placed in
+\fI/etc/services\fR,
+one of:
+.sp
+.in +.5i
+.nf
+qualifier portno/lpp
+qualifier portno/tcp
+qualifier portno/udp
+.fi
+.in -.5i
+.sp
+The first alternative says that the service lives on both TCP and UD;
+the second alternative says that the service lives on TCP only;
+and,
+the third alternative says that the service lives on UDP only.
+.SH FILES
+.nf
+.ta \w'\*(EDisoentities 'u
+\*(EDisoentities ISODE entities database
+.re
+.fi
+.SH "SEE ALSO"
+isobjects(5), isoservices(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Entities Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
+.br
+with design conceptualization by Stephen E. Kille, University College London.
--- /dev/null
+.TH ISOMACROS 5 "12 Feb 1989"
+.\" $Header: /f/osi/support/RCS/isomacros.5,v 7.1 91/02/22 09:46:44 mrose Interim $
+.\"
+.\"
+.\" $Log: isomacros.5,v $
+.\" Revision 7.1 91/02/22 09:46:44 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:27:33 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+.B isomacros
+\- ISODE macros database
+.SH DESCRIPTION
+The \fIisomacros\fR
+file contains information regarding local macros for network addresses.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+The first item is the macro, a simple string.
+The second item is the prefix for the corresponding network address.
+.SH "USER-SPECIFIC MACROS"
+By default
+a user-specific macros database is consulted before the system\-wide
+macros file.
+The user-specific file is called \fB\&.isode_macros\fR in the user's
+home directory.
+.SH FILES
+.nf
+.ta \w'$HOME/.isode_macros 'u
+\*(EDisomacros ISODE macros database
+$HOME/.isode_macros user-specific macros database
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 1:
+Application Services\fR, \*(lqThe ISODE Macros Database\*(rq,
+.br
+\fIA string encoding of Presentation Address\fR, S.E. Kille
+.br
+\fIAn Interim approach to use of Network Addresses\fR, S.E. Kille
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+.TH ISORE 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/isore.8c,v 7.1 91/02/22 09:46:45 mrose Interim $
+.\"
+.\"
+.\" $Log: isore.8c,v $
+.\" Revision 7.1 91/02/22 09:46:45 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:27:34 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+isore \- help out ISODE TSAP programs
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDisore
+\fImagic\0arguments\fR
+.in -.5i
+(under a program loaded with \fB\-ltsap\fR)
+.SH DESCRIPTION
+The \fIisore\fR program is used to correct a deficiency in the 4.2
+Berkeley UNIX implementation of TCP/IP.
+In short,
+the SIGIO signal for asynchronous notification of socket activity is not
+implemented.
+If a transport\-descriptor is marked as being asynchronous
+(the TSAP-provider can initiate INDICATION events at any time),
+then this capability is necessary.
+The \fIisore\fR program is spawned automatically when one or more
+transport\-descriptors are marked for asynchronous INDICATIONs.
+It monitors the TCP/IP traffic, as efficiently as possible,
+and sends the SIGEMT signal to the program when the network would generate
+an N\-DATA.INDICATION event.
+The program catches this signal and performs the appropriate action.
+.PP
+This program is mostly likely obsolete on 4.3BSD and SVR3 systems.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices 'u
+None
+.re
+.fi
+.SH "SEE ALSO"
+libtsap(3n)
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+/* isore.c - help out ISODE TSAP programs */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/support/RCS/isore.c,v 7.1 91/02/22 09:46:46 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/support/RCS/isore.c,v 7.1 91/02/22 09:46:46 mrose Interim $
+ *
+ *
+ * $Log: isore.c,v $
+ * Revision 7.1 91/02/22 09:46:46 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:27:34 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <stdio.h>
+#include <signal.h>
+#include "manifest.h"
+
+/* \f MAIN */
+
+SFD EMTser ();
+
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int argc;
+char **argv,
+ **envp;
+{
+ int fd,
+ mask,
+ nfds,
+ ppid;
+ fd_set ifds,
+ rfds;
+
+ if (argc != 4)
+ exit (1);
+ if ((nfds = atoi (argv[1])) < 0
+ || sscanf (argv[2], "0x%x", &mask) != 1
+ || (ppid = atoi (argv[3])) < 0)
+ exit (2);
+
+ FD_ZERO (&rfds);
+ for (fd = 0; fd < nfds; fd++)
+ if (mask & (1 << fd))
+ FD_SET (fd, &rfds);
+
+ (void) signal (SIGEMT, EMTser);
+
+ for (;;) {
+ ifds = rfds;
+ switch (xselect (nfds, &ifds, NULLFD, NULLFD, NOTOK)) {
+ case NOTOK:
+ fprintf (stderr, "NOTOK\n");
+ break;
+
+ case OK:
+ fprintf (stderr, "OK\n");
+ break;
+
+ default:
+ (void) kill (ppid, SIGEMT);
+ sigpause (0);
+ break;
+ }
+ }
+}
+
+/* \f SIGNALS */
+
+/* ARGSUSED */
+
+static SFD EMTser (sig, code, sc)
+int sig;
+long code;
+struct sigcontext *sc;
+{
+#ifndef BSDSIGS
+ (void) signal (SIGEMT, EMTser);
+#endif
+}
--- /dev/null
+.TH ISOSERVICES 5 "08 Apr 1986"
+.\" $Header: /f/osi/support/RCS/isoservices.5,v 7.2 91/02/22 09:46:46 mrose Interim $
+.\"
+.\"
+.\" $Log: isoservices.5,v $
+.\" Revision 7.2 91/02/22 09:46:46 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.1 90/10/15 22:54:23 mrose
+.\" typo
+.\"
+.\" Revision 7.0 89/11/23 22:27:35 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+.B isoservices
+\- ISODE services database
+.SH DESCRIPTION
+The \fIisoservices\fR
+file contains information regarding the known services on the host.
+.PP
+\fBNB\0\fR: Use of this database is deprecated.
+Consult the ISODE \fIUser's Manual\fR for further information.
+.PP
+Items are separated by any number of blanks and/or tab characters.
+However, double\-quotes may be used to prevent separation between arguments
+in the vector.
+The character `#' at the beginning of a line indicates a comment line.
+.PP
+Each line consists of the name of the provider, a slash, and the name of the
+entity residing above the provider;
+the selector used to identify the entity to the provider;
+and,
+the program and argument vector to \fIexecvp\fR when the service is requested.
+If the selector starts with a hash\-mark (`#')
+it is interpreted numerically as a decimal short-word quantity;
+otherwise if it appears in double\-quotes,
+it is interpreted as an ascii string,
+with the usual escape mechanisms for introducing non\-printable characters;
+otherwise,
+it is interpreted as an exploded octet string.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices 'u
+\*(EDisoservices ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5), isobjects(5),
+.br
+\fIThe ISO Development Environment: User's Manual, Volume 2:
+Underlying Services\fR, \*(lqThe ISODE Service Database\*(rq.
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+###############################################################################
+#
+# isotailor - ISODE tailoring file
+#
+# This file is purposely not installed; it is an example only!
+#
+#
+# $Header: /f/osi/support/RCS/isotailor,v 7.1 91/02/22 09:46:47 mrose Interim $
+#
+#
+# $Log: isotailor,v $
+# Revision 7.1 91/02/22 09:46:47 mrose
+# Interim 6.8
+#
+# Revision 7.0 89/11/23 22:27:36 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+# <variable> : <value>
+#
+# Arbitrary whitespace separates the two items
+#
+# For the xsaplevels, <value> consists of any of the following
+# (seperated by whitespace):
+#
+# none - does nothing
+#
+# fatal - fatal errors
+#
+# exceptions - exceptional events
+#
+# notice - informational notices
+#
+# remaining levels available under -DDEBUG
+#
+# pdus - PDU printing
+#
+# trace - program tracing
+#
+# debug - full debugging
+#
+# all - all of the above
+#
+###############################################################################
+
+compatlevel: exceptions
+compatfile: -
+addrlevel: exceptions
+addrfile: -
+tsaplevel: exceptions
+tsapfile: -
+ssaplevel: exceptions
+ssapfile: -
+psaplevel: exceptions
+psapfile: -
+psap2level: exceptions
+psap2file: -
+acsaplevel: exceptions
+acsapfile: -
+rtsaplevel: exceptions
+rtsapfile: -
+rosaplevel: exceptions
+rosapfile: -
--- /dev/null
+.TH ISOTAILOR 5 "5 July 1988"
+.\" $Header: /f/osi/support/RCS/isotailor.5,v 7.8 91/02/22 09:46:48 mrose Interim $
+.\"
+.\"
+.\" $Log: isotailor.5,v $
+.\" Revision 7.8 91/02/22 09:46:48 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.7 90/11/21 11:37:51 mrose
+.\" update
+.\"
+.\" Revision 7.6 90/10/29 18:37:21 mrose
+.\" updates
+.\"
+.\" Revision 7.5 90/07/09 14:50:51 mrose
+.\" sync
+.\"
+.\" Revision 7.4 90/01/11 18:38:00 mrose
+.\" real-sync
+.\"
+.\" Revision 7.3 89/12/12 16:14:33 mrose
+.\" localHost
+.\"
+.\" Revision 7.2 89/11/30 23:51:52 mrose
+.\" typo
+.\"
+.\" Revision 7.1 89/11/27 10:30:48 mrose
+.\" sync
+.\"
+.\" Revision 7.0 89/11/23 22:27:37 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+.B isotailor
+\- ISODE tailoring file
+.SH DESCRIPTION
+The \fIisotailor\fR file contains information used to run-time
+configure the ISODE distribution.
+Entries are separated by end\-of\-line (or the end\-of\-file).
+The character `#' at the beginning of a line indicates a comment line.
+The syntax is:
+.sp
+.in +.5i
+.nf
+variable: value
+.fi
+.in -.5i
+.sp
+as in
+.sp
+.in +.5i
+.nf
+sbindir: /usr/etc/
+.fi
+.in -.5i
+.PP
+The entries come in several types. There are general ISODE
+configuration parameters, operating system specific tailoring and
+interface specific tailoring parameters.
+.SH "LOCAL ENVIRONMENT TAILORING"
+There are some variables that are used to make up for deficiencies in
+operating systems, or to override the operating system. These are
+described as follows.
+.IP localname
+This takes a string as a parameter and is used as
+the name of the local host if the \fIgethostname\fR call
+(or equivalent, e.g., \fIuname\fR)
+is not used. This will also override any other run-time determination
+of the local hostname.
+.IP binpath
+This takes a string as a parameter and indicates the directory where
+the ISODE user programs are kept (be sure to use a trailing slash).
+.IP sbinpath
+This takes a string as a parameter and indicates the directory where
+the ISODE system programs are kept (be sure to use a trailing slash).
+.IP etcpath
+This takes a string as a parameter and indicates the directory where
+the ISODE configuration files are kept (be sure to use a trailing slash).
+.SH "LOGGING TAILORING"
+There are a number of options that can be set for each layer of ISODE.
+The first variable indicates the default logging directory,
+the other variables give information about each log file.
+.IP logpath
+This variable takes a string as a parameter and indicates the
+directory where the ISODE log files are kept (be sure to use a
+trailing slash).
+.PP
+The remaining variables are all configured in the same way and are in
+the general format:
+.sp
+.in +.5i
+.nf
+xyzlevel: [none] [exceptions] [notice] [pdus] [trace] [debug] [all]
+xyzfile: filename
+.fi
+.in -.5i
+.sp
+The filename can be either the name of a file of a `\-' in which case
+the standard error is used. If the filename contains the string `%d'
+then this is replaced by the current process id.
+.PP
+The normal level for this style of tailoring is to set exceptions. The
+other two values can be added in when debugging, if so desired.
+The current variables in this format are as follows.
+.sp
+.in +.5i
+.nf
+.ta \w'compatlevel 'u
+compatlevel native services subsystem
+compatfile
+addrlevel addressing subsystem
+addrfile
+tsaplevel transport level
+tsapfile
+ssaplevel session level
+ssapfile
+psaplevel presentation elements
+psapfile
+psap2level presentation level
+psap2file
+acsaplevel association control level
+acsapfile
+rtsaplevel reliable transfer level
+rtsapfile
+rosaplevel remote operations level
+rosapfile
+.sp
+.in -.5i
+.fi
+.SH "TRANSPORT STACK TAILORING"
+There are several variables which can be used to en/disable configured
+TS-stacks and to define OSI communities and their relationship
+to this system.
+.SS "TS-STACKS"
+.IP ts_stacks
+which takes one or more of the following values:
+.sp
+.in +.5i
+.nf
+[tcp] [x25] [bridge] [tp4] [all]
+.fi
+.in -.5i
+.sp
+indicates which TS-stacks should be enabled.
+This is useful when multiple machines (with different interfaces)
+share the same executables.
+For example,
+the \fB\*(EDisotailor\fR file is a normally symbolic link to
+\fB/private\*(EDisotailor\fR.
+.SS "OSI COMMUNITIES"
+.IP ts_interim
+which takes one or more OSI community names as a value.
+Each community name must be defined as a macro in the
+\fIisomacros\fR\0(5) file.
+.IP ts_communities
+which takes one or more of the following values:
+.sp
+.in +.5i
+.nf
+[int-x25] [janet] [internet] [realns] [localTCP] [all]
+.fi
+.in -.5i
+.sp
+This variable is used to distinguish membership in various OSI communities.
+For example,
+a site with an X.25 connection might be attached to the International X.25
+network, but not the JANET.
+Thus \fIts_stacks\fR would include \*(lqx25\*(rq,
+and \fIts_communities\fR would include \*(lqint-x25\*(rq but not
+\*(lqjanet\*(rq.
+Note that the ordering of communities is important:
+network addresses will be tried in the order that their respective
+communities are listed with this variable.
+.IP default_nsap_community
+which takes an integer value,
+declaring the default community to be used for NSAP addresses.
+.IP default_x25_community
+declaring the default community to be used for X.25 (DTE) addresses.
+.IP default_tcp_community
+declaring the default community to be used for TCP (RFC1006) addresses.
+.SS "TS-BRIDGE"
+These are the parameters that are used in the Transport-Service Bridge
+implementation.
+.IP tsb_communities
+A list of pairs of values.
+The first of each value should be a community as defined in the
+\fIts_communities\fP variable
+(obviously the values \*(lqnone\*(rq and \*(lqall\*(rq are not permissible).
+The second value of the pair should be a presentation address using
+the ISODE \*(lqstring\*(rq format.
+When a call is to be placed and the network corresponds to one
+of the communities given here, then a call through the bridge given in
+the second variable will be made automatically.
+.IP tsb_default_address
+This variable contains a string encoded presentation address which the
+bridge will listen on by default.
+This should normally consist of a set of network addresses with no selectors
+present.
+.PP
+Consider the case of a host with access to both the Internet and the
+International X.25 network.
+This host might have this entry in its \fIisotailor\fR file:
+.sp
+.in +.5i
+.nf
+tsb_default_address: Internet=sheriff+17004\\|Int-X25(80)=23426020017299+PID+03018000
+.fi
+.in -.5i
+.sp
+This tells the bridge to listen on two network endpoints.
+Hosts in the Internet community wishing to reach the International
+X.25 community would have this entry in their \fIisotailor\fR file:
+.sp
+.in +.5i
+.nf
+tsb_communities: int-x25 Internet=sheriff+17004
+.fi
+.in -.5i
+.sp
+Similarly,
+hosts in the International X.25 community wishing to reach the
+Internet community, would have the entry:
+.sp
+.in +.5i
+.nf
+tsb_communities: internet Int-X25(80)=23426020017299+PID+03018000
+.fi
+.in -.5i
+.SH "INTERFACE SPECIFIC TAILORING"
+Most interfaces that ISODE runs over have some form of tailoring.
+These are usually very dependent on the interface. Each interface
+which supports tailoring will now be described.
+.SS "General X.25 Tailoring"
+There are two specific variables that can be used with any X.25
+interface.
+.IP x25_local_dte
+This is the X.121 address that ISODE processes will listen on
+by default.
+It may be a full X.121 address or a sub-address.
+.IP x25_local_pid
+This is the X.25 protocol ID that ISODE processes will listen on by default.
+Traditionally, this is the first four octets of the CUDF in hex-notation,
+e.g., 03010100.
+.PP
+There are also three variables for performing address
+manipulation as required by some network vendors.
+.IP x25_intl_zero
+If this has the value `on' then any international DTEs (i.e.
+having non\-local DNICs) will have a leading zero introduced
+before being passed to the network.
+.IP x25_strip_dnic
+If this has the value `on' then any local DTEs (i.e. having the
+local DNIC) will have this DNIC removed before being passed to
+the network.
+.IP x25_dnic_prefix
+This should be set to the local DNIC (the first four digits of the
+DTE) of the host machine.
+It should only be set if one or both of the previous two
+variables has the value `on'.
+.PP
+There are also two variables for logging X.25 statistics.
+.IP x25level
+Defines the level of logging to be used for X.25 statistics logging.
+(At present, only \*(lqnotice\*(rq level messages are generated.)
+.IP x25file
+Defines the filename to be used for X.25 statistics logging.
+.SS "SUNLINK X.25"
+These setting are only useful when SUN_X25 is defined along with X25.
+The effect of these parameters is more fully documented in the Sun manuals.
+.IP reverse_charge
+Set to 1 or 0 to enable/disable reverse charging.
+.IP recvpktsize
+.IP sendpktsize
+This should be set to one of 0 (default), 16, 32, 64, 128, 256, 512 or
+1024 to set the send/receive packet size.
+.IP recvwndsize
+.IP sendwndsize
+This sets the send/receive window sizes. Legal values are 0 (default),
+7 and 127.
+.IP recvthruput
+.IP sendthruput
+This sets the sending/receiving throughput values. Legal values are 0
+(default) 75, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 48000.
+.IP cug_req
+Closed user group request. Set to either 0 or 1.
+.IP cug_index
+Sets the closed user group index number.
+.IP fast_select_type
+Sets the fast select parameters. Either 0, 1 or 2.
+.IP rpoa_req
+.IP rpoa
+Recognised private operating agency parameters.
+.SS "CAMTEC CCL"
+These are used
+when the Camtec X.25 is accessed via the
+CCL (sockets) mechanism.
+.IP x25_outgoing_port
+This selects which port on the Camtec card will be used
+for outgoing calls, and takes the value A, B or #.
+A and B are the two X.21 WAN interfaces and # is the
+Ethernet.
+Listening is automatically done on all three ports.
+.SS "BRIDGE X.25"
+These are parameters that are used in the tp0bridge implementation.
+.IP x25_bridge_host
+The host machine that is running the tp0bridge.
+.IP x25_bridge_port
+This is the TCP port that is to be used
+for bridging.
+The default is 146, which should be in defined in /etc/services.
+.IP x25_bridge_addr
+The X.121 address of the remote host.
+.IP x25_bridge_listen
+The X.121 address to listen on for incoming calls, on the remote host.
+.IP x25_bridge_pid
+The protocol ID used for listening along with the previous address.
+This is encoded as a string of eight hex digits.
+.IP x25_bridge_discrim
+A string used to discriminate the network. When attempting to place an
+X.25 call with BRIDGE_X25 and real X25 configured in, this string is
+used to decide which interface to use. If the string is empty, the
+bridge will be used. If it is set to `\-' the bridge will not be used.
+If the string is anything else, it is compared against the called
+X.121 address. If there is a match, then the bridge is used, otherwise
+the real interface is used.
+.SH "SESSION SERVICES TAILORING"
+Ther are three variables that can be tailored:
+.IP ses_abort_timer
+The number of seconds to drain on session aborts.
+.IP ses_disconnect_timer
+The number of seconds to drain on session disconnects.
+.IP ses_refuse_timer
+The number of seconds to drain on session refuses.
+.SH "DIRECTORY SERVICES TAILORING"
+There are two variables that can be tailored:
+.IP ns_enable
+This takes either the string \*(lqon\*(rq or \*(lqoff\*(rq as a parameter.
+If \*(lqon\*(rq,
+then the \*(lquser-friendly namservice" will be used to perform
+name/address resolution.
+If the nameservice lookup fails,
+the stub-directory will be used as a fallback.
+.IP ns_address
+This is the transport address of the nameservice.
+It is specified using the ISODE \*(lqstring\*(rq format,
+e.g.,
+.in +.5i
+Internet=wp.psi.net+17006
+.in -.5i
+which indicates that the nameservice lives in the TCP/IP communications domain
+on TCP port \*(lq17006\*(rq at host \*(lqwp.psi.net\*(rq.
+The nameservice is accessed via the OSI CO-mode transport service,
+so other kinds of addresses (e.g., X.25 addresses can be used as well).
+.SH "PROGRAM-SPECIFIC TAILORING"
+By default
+a program-specific tailoring file is consulted before the system\-wide
+tailoring file.
+The program-specific file is called \fB\&.myname_tailor\fR in the user's
+home directory,
+where \*(lqmyname\*(rq is the name that the program was invoked with.
+.SH FILES
+.nf
+.ta \w'$HOME/.myname_tailor 'u
+\*(EDisotailor ISODE tailoring file
+$HOME/.myname_tailor program-specific tailoring file
+.re
+.fi
+.SH "SEE ALSO"
+\fIThe ISO Development Environment: User's Manual, Volume 2:
+Underlying Services\fR, \*(lqThe ISODE Tailoring File\*(rq.
+.SH AUTHORS
+Marshall T. Rose
+.br
+Simon Walton,
+University College London
--- /dev/null
+.TH LPPD 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/lppd.8c,v 7.2 91/02/22 09:46:50 mrose Interim $
+.\"
+.\" Contributed by The Wollongong Group, Inc.
+.\"
+.\"
+.\" $Log: lppd.8c,v $
+.\" Revision 7.2 91/02/22 09:46:50 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.1 90/12/19 09:16:06 mrose
+.\" touch-up
+.\"
+.\" Revision 7.0 89/11/23 22:27:38 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+lppd \- lpp listen and dispatch daemon
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDlppd
+\%[\-d]
+\%[\-s\ service\-designator]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fIlppd\fR server listens for lightweight presentation protocol
+connections which utilize TCP\-backing.
+The server implements the protocol described in RFC1085.
+.PP
+Basically, the server listens on various TCP ports for connections,
+and immediately execs the appropriate program to enter the protocol
+and provide the service.
+The `\-s' option overrides the default service\-qualifier used when
+deciding which services to listen for.
+.PP
+Note that \fIlppd\fR does not listen for connections which utilize
+UDP\-backing.
+To support this transport base,
+the program which implements the service must listen directly itself
+(and potentially manage multiple simultaneous associations).
+This is done trivially by using the \*(lqisodeserver()\*(rq routine.
+.SH "DEBUG OPERATION"
+If \fIlppd\fR is started interactively,
+or if the `\-d' switch is given,
+then debug mode is entered.
+In this case,
+all logging activity is displayed on the user's terminal,
+the logging information is more verbose,
+and \fIlppd\fR will terminate after it handles the first incoming connection
+(this allows \fIlppd\fR to be run under a debugger).
+.SH FILES
+.nf
+.ta \w'\*(LDlppd.log 'u
+\*(EDisoentities ISODE entities database
+\*(EDisoservices ISODE services database
+\*(LDlppd.log log file
+.re
+.fi
+.SH "SEE ALSO"
+isoentities(5), isoservices(5)
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+/* lppd.c - lpp listen and dispatch daemon */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/support/RCS/lppd.c,v 7.6 91/02/22 09:46:51 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/support/RCS/lppd.c,v 7.6 91/02/22 09:46:51 mrose Interim $
+ *
+ * Contributed by The Wollongong Group, Inc.
+ *
+ *
+ * $Log: lppd.c,v $
+ * Revision 7.6 91/02/22 09:46:51 mrose
+ * Interim 6.8
+ *
+ * Revision 7.5 90/12/19 09:16:08 mrose
+ * touch-up
+ *
+ * Revision 7.4 90/12/11 10:52:26 mrose
+ * lock-and-load
+ *
+ * Revision 7.3 90/10/29 18:37:23 mrose
+ * updates
+ *
+ * Revision 7.2 90/07/09 14:50:54 mrose
+ * sync
+ *
+ * Revision 7.1 90/02/19 13:09:50 mrose
+ * update
+ *
+ * Revision 7.0 89/11/23 22:27:39 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <varargs.h>
+#include "manifest.h"
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#ifdef BSD42
+#include <sys/file.h>
+#endif
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+#ifndef X_OK
+#define X_OK 1
+#endif
+#include "psap.h"
+#include "tsap.h"
+#include "isoservent.h"
+#include "logger.h"
+#include "tailor.h"
+
+/* \f */
+
+static int debug = 0;
+static int nbits = FD_SETSIZE;
+
+static LLog _pgm_log = {
+ "lppd.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
+ LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *pgm_log = &_pgm_log;
+
+static char *myname = "lppd";
+static char myhost[BUFSIZ];
+
+
+#define NTADDRS FD_SETSIZE
+
+static struct TSAPaddr *tz;
+static struct TSAPaddr tas[NTADDRS];
+
+
+struct dispatch {
+ char *dp_entity;
+
+ u_short dp_port;
+};
+
+static struct dispatch *dz;
+static struct dispatch dps[NTADDRS];
+
+
+void adios (), advise ();
+void ts_advise ();
+
+
+extern int errno;
+
+/* \f */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int argc;
+char **argv,
+ **envp;
+{
+ int listening,
+ vecp;
+ char *vec[4];
+ register struct NSAPaddr *na;
+ register struct TSAPaddr *ta;
+ register struct dispatch *dp;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ arginit (argv);
+ envinit ();
+
+ listening = 0;
+
+ for (ta = tas, dp = dps; ta < tz; ta++, dp++) {
+ na = ta -> ta_addrs;
+ if (na -> na_stack != NA_TCP)
+ adios (NULLCP, "unexpected network type 0x%x", na -> na_stack);
+ if (na -> na_tset != NA_TSET_TCP)
+ adios (NULLCP, "unexpected transport base 0x%x", na -> na_tset);
+
+ advise (LLOG_NOTICE, NULLCP, "listening on %s for \"%s\"",
+ taddr2str (ta), dp -> dp_entity);
+
+ if (TNetListen (ta, td) == NOTOK) {
+ ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed");
+ _exit (1);
+ }
+
+ listening++;
+ }
+
+ if (!listening)
+ adios (NULLCP, "no network services selected");
+
+ for (ta = tas;;) {
+ if (TNetAcceptAux (&vecp, vec, NULLIP, ta, 0, NULLFD, NULLFD, NULLFD,
+ NOTOK, td) == NOTOK) {
+ ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed");
+ continue;
+ }
+
+ if (vecp <= 0)
+ continue;
+
+ if (debug)
+ break;
+
+ switch (TNetFork (vecp, vec, td)) {
+ case OK:
+ ll_hdinit (pgm_log, myname);
+ break;
+
+ case NOTOK:
+ ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed");
+ default:
+ continue;
+ }
+ break;
+ }
+
+ lppd (vecp, vec, ta);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int lppd (vecp, vec, ta)
+int vecp;
+char **vec;
+struct TSAPaddr *ta;
+{
+ register u_short port = ta -> ta_addrs[0].na_port;
+ register struct dispatch *dp;
+ register struct isoservent *is;
+
+ for (dp = dps; dp < dz; dp++)
+ if (dp -> dp_port == port)
+ break;
+ if (dp >= dz)
+ adios (NULLCP, "unable to find service associated with local port %d",
+ ntohs (port));
+
+ if ((is = getisoserventbyname (dp -> dp_entity, "lpp")) == NULL)
+ adios (NULLCP, "unable to find program associated with service %s",
+ dp -> dp_entity);
+
+ *is -> is_tail++ = vec[1];
+ *is -> is_tail++ = vec[2];
+ *is -> is_tail = NULL;
+
+ advise (LLOG_NOTICE, NULLCP, "exec \"%s\" for \"%s\"", *is -> is_vec,
+ dp -> dp_entity);
+
+ (void) execv (*is -> is_vec, is -> is_vec);
+
+ adios (*is -> is_vec, "unable to exec");
+}
+
+/* \f */
+
+static void ts_advise (td, code, event)
+register struct TSAPdisconnect *td;
+int code;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (td -> td_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ TErrString (td -> td_reason),
+ td -> td_cc, td -> td_cc, td -> td_data);
+ else
+ (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
+
+ advise (code, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f */
+
+static arginit (vec)
+char **vec;
+{
+ register int n;
+ register char *ap;
+ struct stat st;
+ register struct isoservent *is;
+ register struct PSAPaddr *pa;
+ register struct NSAPaddr *na;
+ AEI aei;
+
+ if (myname = rindex (*vec, '/'))
+ myname++;
+ if (myname == NULL || *myname == NULL)
+ myname = *vec;
+
+ isodetailor (myname, 0);
+ ll_hdinit (pgm_log, myname);
+
+ if (getuid () == 0
+ && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK
+ && st.st_uid != 0)
+ adios (NULLCP, "%s not owned by root", ap);
+
+ (void) strcpy (myhost, TLocalHostName ());
+
+ for (vec++; ap = *vec; vec++) {
+ if (*ap == '-')
+ switch (*++ap) {
+ case 'd':
+ debug++;
+ continue;
+
+ case 's':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -s service-designator");
+ (void) strcpy (myhost, ap);
+ continue;
+
+ default:
+ adios (NULLCP, "-%s: unknown switch", ap);
+ }
+
+ adios (NULLCP, "usage: %s [switches]", myname);
+ }
+
+ bzero ((char *) tas, sizeof tas);
+ tz = tas;
+
+ bzero ((char *) dps, sizeof dps);
+ dz = dps;
+
+ (void) setisoservent (0);
+ while (is = getisoservent ())
+ if (strcmp (is -> is_provider, "lpp") == 0
+ && access (*is -> is_vec, X_OK) != NOTOK) {
+ if ((aei = str2aei (myhost, is -> is_entity)) == NULLAEI)
+ continue;
+ if ((pa = aei2addr (aei)) == NULLPA)
+ adios (NULLCP, "address translation failed on %s-%s",
+ myhost, is -> is_entity);
+
+ for (na = pa -> pa_addr.sa_addr.ta_addrs,
+ n = pa -> pa_addr.sa_addr.ta_naddr;
+ n > 0;
+ na++, n--) {
+ if (na -> na_stack != NA_TCP)
+ continue;
+ if (na -> na_tset == 0)
+ na -> na_tset = NA_TSET_TCP;
+ else
+ if (na -> na_tset != NA_TSET_TCP)
+ continue;
+ if (na -> na_port == 0)
+ continue;
+
+ if (tz >= tas + NTADDRS) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "too many services, starting with %s",
+ is -> is_entity);
+ goto no_more;
+ }
+
+ bcopy ((char *) na, (char *) tz -> ta_addrs, sizeof *na);
+ tz -> ta_naddr = 1;
+ tz++;
+
+ if ((dz -> dp_entity =
+ malloc ((unsigned) (strlen (is -> is_entity) + 1)))
+ == NULL)
+ adios (NULLCP, "out of memory");
+ (void) strcpy (dz -> dp_entity, is -> is_entity);
+ dz -> dp_port = na -> na_port;
+ dz++;
+ }
+ }
+no_more: ;
+ (void) endisoservent ();
+}
+
+/* \f */
+
+static envinit () {
+ int i,
+ sd;
+
+ nbits = getdtablesize ();
+
+ if (debug == 0 && !(debug = isatty (2))) {
+ for (i = 0; i < 5; i++) {
+ switch (fork ()) {
+ case NOTOK:
+ sleep (5);
+ continue;
+
+ case OK:
+ break;
+
+ default:
+ _exit (0);
+ }
+ break;
+ }
+
+ (void) chdir ("/");
+
+ if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
+ adios ("/dev/null", "unable to read");
+ if (sd != 0)
+ (void) dup2 (sd, 0), (void) close (sd);
+ (void) dup2 (0, 1);
+ (void) dup2 (0, 2);
+
+#ifdef SETSID
+ if (setsid () == NOTOK)
+ advise (LLOG_EXCEPTIONS, "failed", "setsid");
+#endif
+#ifdef TIOCNOTTY
+ if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
+ (void) ioctl (sd, TIOCNOTTY, NULLCP);
+ (void) close (sd);
+ }
+#else
+#ifdef SYS5
+ (void) setpgrp ();
+ (void) signal (SIGINT, SIG_IGN);
+ (void) signal (SIGQUIT, SIG_IGN);
+#endif
+#endif
+ }
+ else
+ ll_dbinit (pgm_log, myname);
+
+#ifndef sun /* damn YP... */
+ for (sd = 3; sd < nbits; sd++)
+ if (pgm_log -> ll_fd != sd)
+ (void) close (sd);
+#endif
+
+ (void) signal (SIGPIPE, SIG_IGN);
+
+ ll_hdinit (pgm_log, myname);
+ advise (LLOG_NOTICE, NULLCP, "starting");
+}
+
+/* \f ERRORS */
+
+#ifndef lint
+void adios (va_alist)
+va_dcl
+{
+ va_list ap;
+
+ va_start (ap);
+
+ _ll_log (pgm_log, LLOG_FATAL, ap);
+
+ va_end (ap);
+
+ _exit (1);
+}
+#else
+/* VARARGS */
+
+void adios (what, fmt)
+char *what,
+ *fmt;
+{
+ adios (what, fmt);
+}
+#endif
+
+
+#ifndef lint
+void advise (va_alist)
+va_dcl
+{
+ int code;
+ va_list ap;
+
+ va_start (ap);
+
+ code = va_arg (ap, int);
+
+ _ll_log (pgm_log, code, ap);
+
+ va_end (ap);
+}
+#else
+/* VARARGS */
+
+void advise (code, what, fmt)
+char *what,
+ *fmt;
+int code;
+{
+ advise (code, what, fmt);
+}
+#endif
--- /dev/null
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/macros.db,v 7.1 91/02/22 09:46:52 mrose Interim $
+#
+#
+# $Log: macros.db,v $
+# Revision 7.1 91/02/22 09:46:52 mrose
+# Interim 6.8
+#
+# Revision 7.0 89/11/23 22:27:41 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+# US GOSIP v2 Addresses
+
+us NS+47000580
+nsfnet us=ffff00
+psinet us=fffc00
+
+
--- /dev/null
+###############################################################################
+#
+# isomacros - ISODE macro file
+#
+# Mappings between user-friendly macros and network addresses
+#
+#
+# $Header: /f/osi/support/RCS/macros.prefix,v 7.3 91/02/22 09:46:53 mrose Interim $
+#
+#
+# $Log: macros.prefix,v $
+# Revision 7.3 91/02/22 09:46:53 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/09/07 11:15:26 mrose
+# update
+#
+# Revision 7.1 89/12/12 16:14:35 mrose
+# localHost
+#
+# Revision 7.0 89/11/23 22:27:41 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Syntax:
+#
+# <macro> <string>
+#
+# Each token is separated by LWSP, though double-quotes may be
+# used to prevent separation
+#
+###############################################################################
+
+
+# standard macros, defined in "A string encoding of Presentation Address"
+
+Int-X25(80) TELEX+00728722+X.25(80)+01+
+Janet TELEX+00728722+X.25(80)+02+
+Internet-RFC-1006 TELEX+00728722+RFC-1006+03+
+
+
+# ISODE standard macros
+
+X25(80) TELEX+00728722+X.25(80)+
+TCP TELEX+00728722+RFC-1006+
+
+
+# Interim Community Names
+
+realNS NS+
+Int-X25 X25(80)=01+
+# Janet X25(80)=02+
+Internet TCP=03+
+localTCP TCP=05+
+localHost localTCP=127.0.0.1+
+IXI X25(80)=06+
+
+
--- /dev/null
+: run this script through /bin/sh
+M=/bin/make
+if [ -f /usr/bin/make ]; then
+ M=/usr/bin/make
+fi
+
+exec $M TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"}
--- /dev/null
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/objects.db,v 7.3 91/02/22 09:46:55 mrose Interim $
+#
+#
+# $Log: objects.db,v $
+# Revision 7.3 91/02/22 09:46:55 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/11/20 15:33:17 mrose
+# update
+#
+# Revision 7.1 90/01/11 18:38:03 mrose
+# real-sync
+#
+# Revision 7.0 89/11/23 22:27:43 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+###############################################################################
+# ISO ASN.1
+###############################################################################
+
+# iso standard 8824
+"iso asn.1 abstract syntax" 1.0.8824
+
+# iso standard 8825
+"iso asn.1 abstract transfer" 1.0.8825
+
+# joint-iso-ccitt asn1(1) basic-encoding(1)
+"basic encoding of a single asn.1 type" 2.1.1
+
+
+###############################################################################
+# ISO ASSOCIATION CONTROL
+###############################################################################
+
+# joint-iso-ccitt associationControl(2) abstractSyntax(1) apdus(0) version1(1)
+"acse pci version 1" 2.2.1.0.1
+
+
+###############################################################################
+# ISO/CCITT RELIABLE TRANSFER
+###############################################################################
+
+# joint-iso-ccitt reliable-transfer (3) apdus (0)
+"rtse pci version 1" 2.3.0
+
+# joint-iso-ccitt reliable-transfer (3) aseID (1)
+"rtse ase identifier" 2.3.1
+
+# joint-iso-ccitt reliable-transfer (3) abstract-syntax (2)
+"rtse abstract syntax" 2.3.2
+
+
+###############################################################################
+# ISO/CCITT REMOTE OPERATIONS
+###############################################################################
+
+# joint-iso-ccitt remote-operations (4) notation (0)
+"rose notation" 2.4.0
+
+# joint-iso-ccitt remote-operations (4) apdus (1)
+"rose pci version 1" 2.4.1
+
+# joint-iso-ccitt remote-operations (4) notation-extension (2)
+"rose notation-extension" 2.4.2
+
+# joint-iso-ccitt remote-operations (4) aseID (3)
+"rose ase identifier" 2.4.3
+
+# joint-iso-ccitt remote-operations (4) aseID-ACSE (4)
+"rose ase identifier ACSE" 2.4.4
+
+
+###############################################################################
+# ISO/CCITT DIRECTORY SERVICES
+###############################################################################
+
+# joint-iso-ccitt ds(5) applicationContext(3) directoryAccessAC(1)
+"directory directoryAccessAC" 2.5.3.1
+
+# joint-iso-ccitt ds(5) applicationContext(3) directorySystemAC(2)
+"directory directorySystemAC" 2.5.3.2
+
+# joint-iso-ccitt ds(5) abstractService(9) directoryAccessAS(1)
+"directory directoryAccessAS" 2.5.9.1
+
+# joint-iso-ccitt ds(5) abstractService(9) directorySystemAS(2)
+"directory directorySystemAS" 2.5.9.2
+
+
+###############################################################################
+# ISO FTAM
+###############################################################################
+
+# iso standard 8571 abstract-syntax (2) ftam-pci (1)
+"ftam pci" 1.0.8571.2.1
+
+# iso standard 8571 application-context (1) iso-ftam (1)
+"iso ftam" 1.0.8571.1.1
+
+# nbs-ad-hoc ftam-nil-ap-title (7)
+"nil AP title" 1.3.9999.1.7
+"null AP title" 1.3.9999.5.1
+
+### BEGIN DIS FTAM ###
+
+# iso standard 8571 transfer-syntax (3) ftam-pci (1)
+"ftam pci transfer syntax" 1.0.8571.3.1
+
+### END DIS FTAM ###
+
+
+###############################################################################
+# ISO VT
+###############################################################################
+
+# TEMPORARY
+"iso vt pci" 1.17.1.10.1
+"iso vt" 1.17.1.10.2
+
+
+"telnet" 1.3.9999.1.8.0
+"forms" 1.3.9999.1.8.1
+"default" 1.3.9999.1.8.2
+
+
+###############################################################################
+# ISO CMIP
+###############################################################################
+
+# iso standard 9596 abstractSyntax(0) cmip-pci(0)
+"cmip pci" 1.0.9596.0.0
+
+# iso standard 9596 cmip(2) version(1) acse(0) functional-units(0)
+"cmip initialize pci" 1.0.9596.2.1.0.0
+
+# iso standard 9596 cmip(2) version(1) acse(0) m-abort-source(1)
+"cmip abort pci" 1.0.9596.2.1.0.1
+
+# TEMPORARY application-context until 9596-2 gets its act together
+"iso cmip" 1.17.1.11.2
+
+
+###############################################################################
+#
+# ISODE Object Identifiers
+#
+# The PCI is an object identifier
+# without asking ISO's permission, we usurp the tree of object
+# identifiers that start with sub-elements "1.17"
+#
+###############################################################################
+
+# reserved for ISODE debug aids: 1.17.0
+# 1.17.0.n.1 pci for debug
+# 1.17.0.n.2 application context for debug
+
+# 1.17.0.1 isode echo
+"isode echo pci" 1.17.0.1.1
+
+# 1.17.0.2 isode sink
+"isode sink pci" 1.17.0.2.1
+
+# reserved for ISODE demo programs: 1.17.1
+# 1.17.1.n.1 pci for demo
+# 1.17.1.n.2 application context for demo
+
+# 1.17.1.1 isode miscellany
+"isode miscellany pci" 1.17.1.1.1
+"isode miscellany" 1.17.1.1.2
+
+# 1.17.1.2 isode image (obsolete)
+
+# 1.17.1.3 isode callback demo
+# reserved (not actually used yet)
+"isode callback demo pci" 1.17.1.3.1
+"isode callback demo" 1.17.1.3.2
+
+# 1.17.1.4 isode listen demo
+# reserved (not actually used yet)
+"isode listen demo pci" 1.17.1.4.1
+"isode listen demo" 1.17.1.4.2
+
+# 1.17.1.5 isode passwd lookup demo
+"isode passwd lookup demo pci" 1.17.1.5.1
+"isode passwd lookup demo" 1.17.1.5.2
+
+# 1.17.1.6 isode dbm demo
+"isode dbm demo pci" 1.17.1.6.1
+"isode dbm demo" 1.17.1.6.2
+
+# 1.17.1.7 obsolete
+
+# 1.17.1.8 isode shell
+"isode shell" 1.17.1.8.1
+"isode shell pci" 1.17.1.8.2
+
+# 1.17.1.9 isode idist
+"isode idist" 1.17.1.9.1
+"isode idist pci" 1.17.1.9.2
+
+
+# 1.17.1.10 VT (temporary)
+# defined above
+
+# 1.17.1.11 CMIP (temporary)
+# defined above
+
+# 1.17.1.12 Z39.50 (temporary)
+"IRP Z39.50" 1.17.1.12.2
+
+# 1.17.1.13 RFA
+"rfa" 1.17.1.13.1
+"rfa pci" 1.17.1.13.2
+
+
+# reserved for local ISODE programs: 1.17.2
+# 1.17.2.n.1 pci for local program
+# 1.17.2.n.2 application context for local program
+
+# additions for local ISODE programs are made to the site's objects.local file
+
+
+# reserved for ISODE FTAM document types: 1.17.3
+# see the isodocuments(5) file
+
+
+# reserved for application entity titles: 1.17.4
+# 1.17.4.0 templates for services
+# 1.17.4.1 templates for local services
+# 1.17.4.2 examples of specific services
+# 1.17.4.3 specific services under different administrations
+
+
+# reserved for use with Directory object definitions: 1.17.5
+# 1.17.5.0 reserved
+# 1.17.5.1 object definitions under different administrations
+# (numbers parallel to 1.17.4.3 tree)
--- /dev/null
+###############################################################################
+#
+# $Header: /f/osi/support/RCS/services.db,v 7.5 91/02/22 09:46:56 mrose Interim $
+#
+#
+# $Log: services.db,v $
+# Revision 7.5 91/02/22 09:46:56 mrose
+# Interim 6.8
+#
+# Revision 7.4 90/11/20 15:33:21 mrose
+# update
+#
+# Revision 7.3 90/10/15 22:54:24 mrose
+# typo
+#
+# Revision 7.2 90/07/09 14:50:58 mrose
+# sync
+#
+# Revision 7.1 90/01/11 18:38:07 mrose
+# real-sync
+#
+# Revision 7.0 89/11/23 22:27:44 mrose
+# Release 6.0
+#
+###############################################################################
+
+
+###############################################################################
+#
+# Entities living above the lightweight presentation service
+#
+# Selector is unimportant
+#
+###############################################################################
+
+"lpp/isode miscellany" "" lpp.imisc
+lpp/mib "" lpp.cmot
+
+
+###############################################################################
+#
+# Entities living above the transport layer, expressed as TSAP IDs
+#
+# 0 reserved
+# 1-127 reserved for GOSIP
+# 128-255 GOSIP-style TSAP IDs for ISODE
+# 256-511 TSAP selectors for ISO applications
+# 512-1023 TSAP selectors for ISODE
+# 1024-2047 TSAP selectors reserved for local programs
+# 2048-32767 unassigned
+# 32768-65535 process-specific
+#
+###############################################################################
+
+# internal server to support asynchronous event INDICATIONs
+tsap/isore #0 isore
+
+# GOSIP-style addressing
+tsap/session #1 tsapd-bootstrap
+
+# debug aids
+tsap/echo #128 isod.tsap
+tsap/sink #129 isod.tsap
+
+# ISO applications
+
+# this is where ISODE 5.0 FTAM (IS over IS) lives
+"tsap/filestore" #259 iso.ftam
+
+# this is where ISODE 4.0 FTAM (DIS over IS) lives
+"tsap/filestore" #258 iso.ftam-4.0
+
+# this is where ISODE 3.0 FTAM (DIS over DIS) lived
+"tsap/filestore" #256 iso.ftam-3.0
+
+# QUIPU is a static server
+#"tsap/directory" #257 iso.quipu
+
+"tsap/terminal" #260 iso.vt
+
+"tsap/mib" #261 ros.cmip
+
+"tsap/Z39.50" #262 iso.z39-50
+
+# ISODE applications
+"tsap/isode echo" #512 isod.acsap
+"tsap/isode rtse echo" #513 isod.rtsap -rtse
+"tsap/isode ros_echo" #514 isod.rtsap -rtse -rose
+"tsap/isode sink" #515 isod.acsap
+"tsap/isode rtse sink" #516 isod.rtsap -rtse
+"tsap/isode ros_sink" #517 isod.rtsap -rtse -rose
+"tsap/isode miscellany" #518 ros.imisc
+# imagestore is obsolete
+#"tsap/imagestore" #519 ros.image
+"tsap/isode callback demo" #520 iso.callback
+"tsap/passwdstore" #521 ros.lookup
+# dbmstore is obsolete
+#"tsap/dbmstore" #522 ros.dbm
+# temporary until the FTAM/FTP gateway is co-resident with the FTAM responder
+"tsap/ftpstore" #523 iso.ftam-ftp
+"tsap/shell" #524 ros.osh
+"tsap/isode idist" #525 ros.idist
+"tsap/rfa" #526 ros.rfa
+
+
+###############################################################################
+#
+# Entities living above the session layer, expressed as SSAP IDs
+#
+# 0 reserved
+# 1-127 reserved for GOSIP
+# 128-255 GOSIP-style SSAP IDs for ISODE
+# 256-1023 unassigned
+# 1024-2047 SSAP selectors reserved for local programs
+# 2048-32767 unassigned
+# 32768-65535 process-specific
+#
+###############################################################################
+
+# GOSIP-style addressing
+ssap/presentation #1 tsapd-bootstrap
+ssap/rts #2 tsapd-bootstrap
+ssap/ros #3 tsapd-bootstrap
+
+# debug aids
+ssap/echo #128 isod.ssap
+ssap/sink #129 isod.ssap
+
+
+###############################################################################
+#
+# Entities living above the presentation layer, expressed as PSAP IDs
+#
+# 0 reserved
+# 1-127 reserved for GOSIP
+# 128-255 GOSIP-style PSAP IDs for ISODE
+# 256-1023 unassigned
+# 1024-2047 PSAP selectors reserved for local programs
+# 2048-32767 unassigned
+# 32768-65535 process-specific
+#
+###############################################################################
+
+# GOSIP-style addressing
+psap/ftam #1 iso.ftam
+
+# debug aids
+psap/echo #128 isod.psap
+psap/sink #129 isod.psap
+
+
+###############################################################################
+#
+# Old-style RTS addressing
+#
+# 0 reserved
+# 1-127 reserved for GOSIP
+# 128-255 GOSIP-style for ISODE
+#
+###############################################################################
+
+# mhs
+rtsap/p1 1
+rtsap/p3 3
+
+# debug aids
+rtsap/echo #128 isod.rtsap
+rtsap/sink #129 isod.rtsap
+rtsap/ros_echo #130 isod.rtsap
+rtsap/ros_sink #131 isod.rtsap
+"rtsap/file transfer" #132 iso.rtf
+
+
+###############################################################################
+#
+# Old-style ROS addressing
+#
+# 0 reserved
+# 1-127 reserved for GOSIP
+# 128-255 GOSIP-style for ISODE
+#
+###############################################################################
+
+# debug aids
+rosap/echo #128 isod.rosap
+rosap/sink #129 isod.rosap
--- /dev/null
+.TH TSAPD 8C "31 May 1988"
+.\" $Header: /f/osi/support/RCS/tsapd.8c,v 7.3 91/02/22 09:46:57 mrose Interim $
+.\"
+.\"
+.\" $Log: tsapd.8c,v $
+.\" Revision 7.3 91/02/22 09:46:57 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.2 90/12/19 09:16:11 mrose
+.\" touch-up
+.\"
+.\" Revision 7.1 90/10/15 18:18:59 mrose
+.\" typos
+.\"
+.\" Revision 7.0 89/11/23 22:27:45 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+tsapd \- OSI transport listener
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDtsapd
+\%[\-d]
+\%[\-t] \%[\-x] \%[\-b] \%[\-z]
+\%[\-r]
+\%[\-p\ portno]
+\%[\-a\ x121address] \%[\-i\ pid]
+\%[\-A\ X121address] \%[\-I\ pid]
+.in -.5i
+(under /etc/rc.local)
+.SH DESCRIPTION
+The \fItsapd\fR server listens for OSI transport connections on the local
+host.
+.PP
+For a TCP\-based network service,
+the server implements the protocol described in RFC1006.
+Basically, the server listens on TCP port 102 for connections,
+decodes the connection request packet,
+and execs the appropriate program to enter the protocol and provide the
+service.
+The `\-p' option overrides the default TCP port.
+.PP
+For an X.25\-based network service,
+the server implements the transport class 0 protocol,
+decodes the connection request packet,
+and execs the appropriate program to enter the protocol and provide the
+service.
+The `\-a' switch is used to specify the X.121 address of the local host
+\(em this overrides the entry in the \fBisotailor\fP file.
+In addition,
+the `\-i' switch is used to specify the protocol ID to listen on.
+Note that on most X.25 implementations,
+if the local X.121 address is not present in the \fBisotailor\fR file,
+then the `-a' switch must be used in order for the transport server to
+receive incoming calls.
+.PP
+If the tp0bridge is providing the X.25\-based network service, the
+`\-A' switch is used to specify the X.121 address of the local host.
+In addition the `\-I' switch is used to specify the protocol ID to
+listen on.
+.PP
+For a TP4\-based transport service,
+the server simply listens to any incoming connections,
+and execs the appropriate program to provide the service.
+.PP
+By default,
+all network services are enabled
+(if defined in the configuration).
+The `\-t' option specifies TCP\-only operation,
+the `\-x' option specifies X.25\-only operation,
+the `\-b' option specifies tp0bridge\-only operation,
+and the `\-z' option specifies TP4\-only operation.
+.PP
+Since \fItsapd\fR reads the \fBisoservices\fR\0(5) file to determine
+which program to run when an incoming connection is received,
+if \fItsapd\fR is running as root then it checks to see that the
+\fBisoservices\fR file is also owned by root.
+The `\-r' option disables this check.
+.PP
+As a further precaution,
+\fItsapd\fR runs the program with permissions set to the owner and
+group of the program.
+Hence, unpriviledged programs can be invoked directly under \fItsapd\fR.
+.SH "DEBUG OPERATION"
+If \fItsapd\fR is started interactively,
+or if the `\-d' switch is given,
+then debug mode is entered.
+In this case,
+all logging activity is displayed on the user's terminal,
+the logging information is more verbose,
+and \fItsapd\fR will terminate after it handles the first incoming connection
+(this allows \fItsapd\fR to be run under a debugger).
+.SH EXAMPLES
+For most installations,
+.sp
+.in +.5i
+\*(SDtsapd &
+.in -.5i
+.sp
+run under /etc/rc.local is sufficient.
+This runs TCP\-, X.25\-based and/or TP4\-based services,
+depending on the configuration.
+.SH FILES
+.nf
+.ta \w'\*(LDtsapd.log 'u
+\*(EDisoservices ISODE services database
+\*(LDtsapd.log log file
+.re
+.fi
+.SH "SEE ALSO"
+iaed(8c), isoservices(5)
+.SH AUTHOR
+Marshall T. Rose
--- /dev/null
+/* tsapd.c - OSI transport listener */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/support/RCS/tsapd.c,v 7.12 91/02/22 09:46:59 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/support/RCS/tsapd.c,v 7.12 91/02/22 09:46:59 mrose Interim $
+ *
+ *
+ * $Log: tsapd.c,v $
+ * Revision 7.12 91/02/22 09:46:59 mrose
+ * Interim 6.8
+ *
+ * Revision 7.11 90/12/19 09:16:14 mrose
+ * touch-up
+ *
+ * Revision 7.10 90/12/17 22:13:27 mrose
+ * -call
+ *
+ * Revision 7.9 90/12/11 10:52:29 mrose
+ * lock-and-load
+ *
+ * Revision 7.8 90/11/05 14:10:32 mrose
+ * oops
+ *
+ * Revision 7.7 90/10/30 14:25:32 mrose
+ * update
+ *
+ * Revision 7.6 90/10/29 18:37:25 mrose
+ * updates
+ *
+ * Revision 7.5 90/10/16 11:21:04 mrose
+ * update
+ *
+ * Revision 7.4 90/10/15 22:54:26 mrose
+ * typo
+ *
+ * Revision 7.3 90/10/15 18:18:47 mrose
+ * iaed
+ *
+ * Revision 7.2 90/07/09 14:51:00 mrose
+ * sync
+ *
+ * Revision 7.1 90/02/19 13:09:53 mrose
+ * update
+ *
+ * Revision 7.0 89/11/23 22:27:46 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <varargs.h>
+#include "manifest.h"
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#ifdef BSD42
+#include <sys/file.h>
+#endif
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+#ifndef X_OK
+#define X_OK 1
+#endif
+
+#ifdef IAE
+#include <quipu/util.h>
+#include <quipu/bind.h>
+#include <quipu/list.h>
+#include <quipu/ds_search.h>
+
+#define NOGOSIP
+#endif
+
+#ifndef NOGOSIP
+#include "rosap.h"
+#include "rtsap.h"
+#include "psap2.h"
+#include "ssap.h"
+#endif
+#include "tpkt.h"
+
+#ifdef TCP
+#include "internet.h"
+#endif
+#ifdef X25
+#include "x25.h"
+#endif
+#ifdef TP4
+#include "tp4.h"
+#endif
+#ifndef IAE
+#include "isoservent.h"
+#endif
+#include "tailor.h"
+
+/* \f */
+
+static int debug = 0;
+static int nbits = FD_SETSIZE;
+
+static LLog _pgm_log = {
+#ifndef IAE
+ "tsapd.log",
+#else
+ "iaed.log",
+#endif
+ NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE,
+ LLOG_FATAL, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *pgm_log = &_pgm_log;
+
+static char *pgmname = "tsapd";
+static char myhost[BUFSIZ];
+
+static int tcpservice = 1;
+static int x25service = 1;
+static int bridgeservice = 1;
+static int tp4service = 1;
+
+static int *services[] = {
+ &tp4service, &tcpservice, &x25service, &bridgeservice
+};
+
+
+#define NTADDRS FD_SETSIZE
+
+static int listening = 0;
+
+static struct TSAPaddr *tz;
+static struct TSAPaddr tas[NTADDRS];
+
+
+#ifdef IAE
+#define IAETIME (24 * 60 * 60L)
+
+static int isbound = 0;
+static int main_dsa = NOTOK;
+static int referral_dsa = NOTOK;
+
+static long nextime;
+
+static DN userdn = NULL;
+static char passwd[DBA_MAX_PASSWD_LEN];
+
+static AttributeType t_ev;
+static AttributeType t_pa;
+
+static struct ds_search_arg search_arg;
+
+struct IAEntry {
+ struct TSAPaddr is_addr;
+
+ char *is_vector;
+ char **is_vec;
+ char **is_tail;
+};
+
+#define NENTRIES 100
+static struct IAEntry *iz;
+static struct IAEntry iae[NENTRIES];
+
+
+int str2dnY ();
+
+
+extern int dsa_ad;
+extern int dsa_dead;
+extern char *local_dit;
+extern struct PSAPaddr dsa_bound;
+
+extern int as_print (), dn_print (), de_print (), fi_print ();
+#endif
+
+
+void adios (), advise ();
+void ts_advise ();
+
+#ifdef NOGOSIP
+#define ssapd NULLIFP
+#else
+int ssapd (), psapd ();
+#endif
+
+
+extern int errno;
+
+#ifdef IAE
+long time ();
+#endif
+
+/* \f */
+
+/* ARGSUSED */
+
+main (argc, argv, envp)
+int argc;
+char **argv,
+ **envp;
+{
+ int failed,
+ vecp;
+ char *vec[4];
+ register struct TSAPaddr *ta;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+ arginit (argv);
+ envinit ();
+
+ failed = 0;
+
+ for (ta = tas; ta < tz; ta++) {
+ register struct NSAPaddr *na;
+
+ if (ta -> ta_naddr) {
+ if (((na = ta -> ta_addrs) -> na_stack < 0
+ || na -> na_stack
+ >= sizeof services / sizeof services[0]))
+ adios (NULLCP, "unknown network type 0x%x", na -> na_stack);
+ }
+ else
+ na = NULLNA;
+
+ if (!*services[na ? na -> na_stack : NA_NSAP])
+ continue;
+
+ advise (LLOG_NOTICE, NULLCP, "listening on %s", taddr2str (ta));
+
+ if (TNetListen (ta, td) == NOTOK) {
+ ts_advise (td, LLOG_EXCEPTIONS, "TNetListen failed");
+ failed++;
+ }
+ else
+ listening++;
+ }
+
+ if (!listening)
+ adios (NULLCP, failed ? "no successful listens"
+ : "no network services selected");
+
+ for (;;) {
+#ifdef IAE
+ int secs;
+ long now;
+
+ (void) time (&now);
+ now++;
+
+ if ((secs = (int) (nextime - now)) <= 0) {
+ search_directory (0);
+
+ secs = IAETIME;
+ }
+#else
+#define secs NOTOK
+#endif
+
+ if (TNetAccept (&vecp, vec, 0, NULLFD, NULLFD, NULLFD, secs, td)
+ == NOTOK) {
+ ts_advise (td, LLOG_EXCEPTIONS, "TNetAccept failed");
+ continue;
+ }
+
+ if (vecp <= 0)
+ continue;
+
+ if (debug)
+ break;
+
+ switch (TNetFork (vecp, vec, td)) {
+ case OK:
+#ifdef IAE
+ (void) signal (SIGHUP, SIG_DFL);
+#endif
+ ll_hdinit (pgm_log, pgmname);
+ break;
+
+ case NOTOK:
+ ts_advise (td, LLOG_EXCEPTIONS, "TNetFork failed");
+ default:
+ continue;
+ }
+ break;
+ }
+
+ tsapd (vecp, vec);
+}
+
+/* \f */
+
+static char buffer1[4096];
+static char buffer2[32768];
+
+
+static int tsapd (vecp, vec)
+int vecp;
+char **vec;
+{
+ char buffer[BUFSIZ];
+#ifndef IAE
+ register struct isoservent *is;
+#else
+ register struct IAEntry *is;
+#endif
+ struct tsapblk *tb;
+ struct TSAPstart tss;
+ register struct TSAPstart *ts = &tss;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+ IFP hook;
+
+/* begin UGLY */
+ (void) strcpy (buffer1, vec[1]);
+ (void) strcpy (buffer2, vec[2]);
+/* end UGLY */
+
+ if (TInit (vecp, vec, ts, td) == NOTOK) {
+ ts_advise (td, LLOG_EXCEPTIONS, "T-CONNECT.INDICATION");
+ return;
+ }
+
+/* used to print this in ssapd()... */
+ advise (LLOG_NOTICE, NULLCP,
+ "T-CONNECT.INDICATION: <%d, %s, %s, %d, %d>",
+ ts -> ts_sd,
+ taddr2str (&ts -> ts_calling), taddr2str (&ts -> ts_called),
+ ts -> ts_expedited, ts -> ts_tsdusize);
+
+ hook = ssapd;
+ if (ts -> ts_called.ta_selectlen) {
+#ifndef IAE
+ if ((is = getisoserventbyselector ("tsap", ts -> ts_called.ta_selector,
+ ts -> ts_called.ta_selectlen))
+ == NULL) {
+#else
+ for (is = iae; is < iz; is++)
+ if (is -> is_addr.ta_selectlen == ts -> ts_called.ta_selectlen
+ && bcmp (is -> is_addr.ta_selector,
+ ts -> ts_called.ta_selector,
+ is -> is_addr.ta_selectlen) == 0)
+ break;
+ if (is >= iz) {
+#endif
+ (void) sprintf (buffer, "OSI service tsap/%s not found",
+ sel2str (ts -> ts_called.ta_selector,
+ ts -> ts_called.ta_selectlen, 1));
+ goto out;
+ }
+ }
+ else
+#ifndef IAE
+ if (hook == NULLIFP
+ || (is = getisoserventbyname ("session", "tsap")) == NULL)
+#endif
+ {
+ (void) strcpy (buffer, "default session service not found");
+ goto out;
+ }
+
+#ifndef IAE
+ *is -> is_tail++ = buffer1;
+ *is -> is_tail++ = buffer2;
+ *is -> is_tail = NULL;
+#else
+ is -> is_tail[0] = buffer1;
+ is -> is_tail[1] = buffer2;
+ is -> is_tail[2] = NULL;
+#endif
+
+ if (tb = findtblk (ts -> ts_sd))
+ tb -> tb_fd = NOTOK;
+ switch (hook ? (*hook) (is, td) : OK) {
+ case NOTOK:
+ ts_advise (td, LLOG_EXCEPTIONS, "service not started at tsap");
+ case DONE:
+ exit (1);
+ /* NOTREACHED */
+
+ case OK:
+ default:
+ (void) setperms (is);
+ (void) execv (*is -> is_vec, is -> is_vec);
+ (void) sprintf (buffer, "unable to exec %s: %s",
+ *is -> is_vec, sys_errname (errno));
+ SLOG (pgm_log, LLOG_FATAL, NULLCP, ("%s", buffer));
+ break;
+ }
+
+out: ;
+ advise (LLOG_EXCEPTIONS, NULLCP, "%s", buffer);
+ if (strlen (buffer) >= TD_SIZE)
+ buffer[0] = NULL;
+ (void) TDiscRequest (ts -> ts_sd, buffer, strlen (buffer) + 1, td);
+
+ exit (1);
+}
+
+/* \f */
+
+static int setperms (is)
+#ifndef IAE
+register struct isoservent *is;
+#else
+register struct IAEntry *is;
+#endif
+{
+ struct stat st;
+
+ if (stat (*is -> is_vec, &st) == NOTOK) {
+ (void) setgid (1);
+ (void) setuid (1);
+ }
+ else {
+ (void) setgid (st.st_gid);
+ (void) setuid (st.st_uid);
+ }
+}
+
+/* \f */
+
+static void ts_advise (td, code, event)
+register struct TSAPdisconnect *td;
+int code;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (td -> td_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ TErrString (td -> td_reason),
+ td -> td_cc, td -> td_cc, td -> td_data);
+ else
+ (void) sprintf (buffer, "[%s]", TErrString (td -> td_reason));
+
+ advise (code, NULLCP, "%s: %s", event, buffer);
+}
+
+/* \f */
+
+#ifndef NOGOSIP
+static int ssapd (is, td)
+register struct isoservent *is;
+register struct TSAPdisconnect *td;
+{
+ int sd;
+ struct TSAPstart tss;
+ register struct TSAPstart *ts = &tss;
+ struct SSAPindication sis;
+ register struct SSAPabort *sa = &sis.si_abort;
+
+ if (strcmp (is -> is_entity, "session")
+ || strcmp (is -> is_provider, "tsap"))
+ return OK;
+
+ if (TInit (is -> is_tail - is -> is_vec, is -> is_vec, ts, td) == NOTOK)
+ return NOTOK;
+
+ sd = ts -> ts_sd;
+
+ if (TConnResponse (sd, &ts -> ts_called, ts -> ts_expedited, NULLCP, 0,
+ NULLQOS, td) == NOTOK)
+ return NOTOK;
+
+ if (SExec (ts, &sis, psapd, setperms) == NOTOK) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "service not started at ssap: %s",
+ SErrString (sa -> sa_reason));
+ if (sa -> sa_cc > 0)
+ advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
+ sa -> sa_cc, sa -> sa_cc, sa -> sa_data);
+
+ SAFREE (sa);
+ }
+
+ return DONE;
+}
+
+/* \f */
+
+#define RMASK \
+ "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
+\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+
+
+static int psapd (is, si)
+register struct isoservent *is;
+register struct SSAPindication *si;
+{
+ struct SSAPstart sss;
+ register struct SSAPstart *ss = &sss;
+ struct PSAPindication pis;
+ register struct PSAPabort *pa = &pis.pi_abort;
+ struct RtSAPindication rtis;
+ register struct RtSAPabort *rta = &rtis.rti_abort;
+ struct RoSAPindication rois;
+ register struct RoSAPpreject *rop = &rois.roi_preject;
+
+ if (strcmp (is -> is_provider, "ssap"))
+ return OK;
+
+ if (strcmp (is -> is_entity, "presentation")
+ && strcmp (is -> is_entity, "rts")
+ && strcmp (is -> is_entity, "ros"))
+ return OK;
+
+/* begin UGLY */
+ (void) strcpy (buffer1, *(is -> is_tail - 2));
+ (void) strcpy (buffer2, *(is -> is_tail - 1));
+/* end UGLY */
+ if (SInit (is -> is_tail - is -> is_vec, is -> is_vec, ss, si) == NOTOK)
+ return NOTOK;
+ advise (LLOG_NOTICE, NULLCP,
+ "S-CONNECT.INDICATION: <%d, %s, %s, %s, %s, %ld, %d>",
+ ss -> ss_sd, sprintref (&ss -> ss_connect),
+ saddr2str (&ss -> ss_calling), saddr2str (&ss -> ss_called),
+ sprintb (ss -> ss_requirements, RMASK), ss -> ss_isn,
+ ss -> ss_ssdusize);
+
+ if (strcmp (is -> is_entity, "presentation") == 0) {
+ if (PExec (ss, &pis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "service not started at psap: %s",
+ PErrString (pa -> pa_reason));
+ if (pa -> pa_cc > 0)
+ advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
+ pa -> pa_cc, pa -> pa_cc, pa -> pa_data);
+ }
+
+ return DONE;
+ }
+
+ if (strcmp (is -> is_entity, "rts") == 0) {
+ if (RtExec (ss, &rtis, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "service not started at rtsap: %s",
+ RtErrString (rta -> rta_reason));
+ if (rta -> rta_cc > 0)
+ advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
+ rta -> rta_cc, rta -> rta_cc, rta -> rta_data);
+ }
+ }
+ else {
+ if (RoExec (ss, &rois, buffer1, buffer2, NULLIFP, setperms) == NOTOK) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "service not started at rosap: %s",
+ RoErrString (rop -> rop_reason));
+ if (rop -> rop_cc > 0)
+ advise (LLOG_EXCEPTIONS, NULLCP, " %*.*s",
+ rop -> rop_cc, rop -> rop_cc, rop -> rop_data);
+ }
+ }
+
+ return DONE;
+}
+#endif
+
+/* \f */
+
+#ifndef IAE
+static arginit (vec)
+char **vec;
+{
+ int rflag;
+ register char *ap;
+#ifdef TCP
+ int port;
+ struct NSAPaddr *tcp_na;
+ register struct servent *sp;
+#endif
+#ifdef X25
+ struct NSAPaddr *x25_na;
+#endif
+#ifdef BRIDGE_X25
+ struct NSAPaddr *bridge_na;
+#endif
+#ifdef TP4
+ register struct isoservent *is;
+#endif
+ struct stat st;
+
+ if (pgmname = rindex (*vec, '/'))
+ pgmname++;
+ if (pgmname == NULL || *pgmname == NULL)
+ pgmname = *vec;
+
+ isodetailor (pgmname, 0);
+ ll_hdinit (pgm_log, pgmname);
+
+ rflag = 0;
+
+ (void) strcpy (myhost, TLocalHostName ());
+
+ bzero ((char *) tas, sizeof tas);
+ tz = tas;
+
+#ifdef TCP
+ if (!(ts_stacks & TS_TCP))
+ tcpservice = 0;
+ if ((sp = getservbyname ("tsap", "tcp")) == NULL
+ && (sp = getservbyname ("iso-tsap", "tcp")) == NULL)
+ advise (LLOG_EXCEPTIONS, NULLCP, "tcp/tsap: unknown service");
+
+ tcp_na = tz -> ta_addrs;
+ tcp_na -> na_stack = NA_TCP;
+ tcp_na -> na_community = ts_comm_tcp_default;
+ tcp_na -> na_domain[0] = NULL;
+ tcp_na -> na_port = sp ? sp -> s_port : htons ((u_short) 102);
+ tz -> ta_naddr = 1;
+
+ tz++;
+#endif
+
+#ifdef X25
+ if (!(ts_stacks & TS_X25))
+ x25service = 0;
+
+ x25_na = tz -> ta_addrs;
+ x25_na -> na_stack = NA_X25;
+ x25_na -> na_community = ts_comm_x25_default;
+ if (x25_local_dte && *x25_local_dte) {
+ (void) strcpy (x25_na -> na_dte, x25_local_dte);
+ x25_na -> na_dtelen = strlen (x25_na -> na_dte);
+ }
+ if (x25_local_pid && *x25_local_pid)
+ x25_na -> na_pidlen =
+ str2sel (x25_local_pid, -1, x25_na -> na_pid, NPSIZE);
+ tz -> ta_naddr = 1;
+
+ tz++;
+#endif
+
+#ifdef BRIDGE_X25
+ if (!(ts_stacks & TS_BRG))
+ bridgeservice = 0;
+
+ bridge_na = tz -> ta_addrs;
+ bridge_na -> na_stack = NA_BRG;
+ bridge_na -> na_community = ts_comm_x25_default;
+ if (x25_bridge_listen && *x25_bridge_listen) {
+ (void) strcpy (bridge_na -> na_dte, x25_bridge_listen);
+ bridge_na -> na_dtelen = strlen (bridge_na -> na_dte);
+ }
+ if (x25_bridge_pid && *x25_bridge_pid)
+ bridge_na -> na_pidlen =
+ str2sel (x25_bridge_pid, -1, bridge_na -> na_pid, NPSIZE);
+ tz -> ta_naddr = 1;
+
+ tz++;
+#endif
+
+#ifdef TP4
+ if (!(ts_stacks & TS_TP4))
+ tp4service = 0;
+
+ (void) setisoservent (0);
+ while (is = getisoservent ())
+ if (strcmp (is -> is_provider, "tsap") == 0
+ && (strcmp (*is -> is_vec, "tsapd-bootstrap") == 0
+ || access (*is -> is_vec, X_OK) != NOTOK)) {
+ if (strcmp (is -> is_entity, "isore") == 0)
+ continue;
+
+ if (tz >= tas + NTADDRS) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "too many services, starting with %s",
+ is -> is_entity);
+ break;
+ }
+
+ bcopy (is -> is_selector, tz -> ta_selector,
+ tz -> ta_selectlen = is -> is_selectlen);
+ tz -> ta_naddr = 0;
+
+ tz++;
+ }
+ (void) endisoservent ();
+#endif
+
+ for (vec++; ap = *vec; vec++) {
+ if (*ap == '-')
+ switch (*++ap) {
+ case 'd':
+ debug++;
+ continue;
+
+ case 't':
+ ts_stacks = TS_TCP;
+ tcpservice = 1;
+ x25service = bridgeservice = tp4service = 0;
+ continue;
+
+ case 'x':
+ ts_stacks = TS_X25;
+ x25service = 1;
+ tcpservice = bridgeservice = tp4service = 0;
+ continue;
+
+ case 'z':
+ ts_stacks = TS_TP4;
+ tp4service = 1;
+ tcpservice = x25service = bridgeservice = 0;
+ continue;
+
+ case 'b':
+ ts_stacks = TS_BRG;
+ bridgeservice = 1;
+ tcpservice = x25service = tp4service = 0;
+ continue;
+
+ case 'r':
+ rflag = 1;
+ continue;
+
+#ifdef TCP
+ case 'p':
+ if ((ap = *++vec) == NULL
+ || *ap == '-'
+ || (port = atoi (ap)) <= 0)
+ adios (NULLCP, "usage: %s -p portno", pgmname);
+ tcp_na -> na_port = htons ((u_short) port);
+ continue;
+#endif
+
+#ifdef X25
+ /* This permits listening on a specific subaddress. */
+ case 'a':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -a x121address", pgmname);
+ (void) strcpy (x25_na -> na_dte, ap);
+ x25_na -> na_dtelen = strlen (ap);
+ continue;
+
+ /* This permits listening on a specific protocol id.
+ In fact, SunLink X.25 lets you listen on a protocol
+ id mask, but let's keep it simple. */
+ case 'i':
+ if ((ap = *++vec) == NULL || *ap == '-' )
+ adios (NULLCP, "usage: %s -i pid", pgmname);
+ x25_na -> na_pidlen =
+ str2sel (ap, -1, x25_na -> na_pid, NPSIZE);
+ continue;
+#endif
+
+#ifdef BRIDGE_X25
+ case 'A':
+ if ((ap = *++vec) == NULL ||
+ *ap == '-')
+ adios (NULLCP, "usage: %s -A x121address", pgmname);
+ (void) strcpy (bridge_na -> na_dte, ap);
+ bridge_na -> na_dtelen = strlen (ap);
+ continue;
+
+ case 'I':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -I pid", pgmname);
+ bridge_na -> na_pidlen =
+ str2sel (ap, -1, bridge_na -> na_pid, NPSIZE);
+ continue;
+#endif
+
+ default:
+ adios (NULLCP, "-%s: unknown switch", ap);
+ }
+
+ adios (NULLCP, "usage: %s [switches]", pgmname);
+ }
+
+ if (!rflag
+ && getuid () == 0
+ && stat (ap = isodefile ("isoservices", 0), &st) != NOTOK
+ && st.st_uid != 0)
+ adios (NULLCP, "%s not owned by root", ap);
+}
+
+/* \f */
+
+#else
+static arginit (vec)
+char **vec;
+{
+ int argp,
+ options;
+ register char *ap;
+ char base[BUFSIZ],
+ **argptr,
+ *args[4];
+
+ if (pgmname = rindex (*vec, '/'))
+ pgmname++;
+ if (pgmname == NULL || *pgmname == NULL)
+ pgmname = *vec;
+
+ isodetailor (pgmname, 0);
+ ll_hdinit (pgm_log, pgmname);
+
+ quipu_syntaxes ();
+
+ argp = 0;
+ args[argp++] = pgmname;
+ for (argptr = vec, argptr++; ap = *argptr; argptr++) {
+ if (*ap == '-')
+ switch (*++ap) {
+ case 'D':
+ case 'u':
+ case 'p':
+ if ((ap = *++argptr) == NULL || *ap == '-')
+ break;
+ continue;
+
+ case 'c':
+ if ((ap = *++argptr) == NULL || *ap == '-')
+ break;
+ args[argp++] = "-c";
+ args[argp++] = ap;
+ break;
+
+ default:
+ continue;
+ }
+
+ break;
+ }
+ args[argp] = NULLCP;
+
+ dsap_init (&argp, (argptr = args, &argptr));
+
+ (void) strcpy (myhost, TLocalHostName ());
+ (void) strcpy (base, local_dit);
+
+ if (!(ts_stacks & TS_TCP))
+ tcpservice = 0;
+ if (!(ts_stacks & TS_X25))
+ x25service = 0;
+ if (!(ts_stacks & TS_BRG))
+ bridgeservice = 0;
+ if (!(ts_stacks & TS_TP4))
+ tp4service = 0;
+
+ options = SVC_OPT_PREFERCHAIN;
+ userdn = NULLDN, passwd[0] = NULL;
+ for (vec++; ap = *vec; vec++) {
+ if (*ap == '-')
+ switch (*++ap) {
+ case 'd':
+ debug++;
+ ll_dbinit (pgm_log, pgmname);
+ continue;
+
+ case 't':
+ ts_stacks = TS_TCP;
+ tcpservice = 1;
+ x25service = bridgeservice = tp4service = 0;
+ continue;
+
+ case 'x':
+ ts_stacks = TS_X25;
+ x25service = 1;
+ tcpservice = bridgeservice = tp4service = 0;
+ continue;
+
+ case 'z':
+ ts_stacks = TS_TP4;
+ tp4service = 1;
+ tcpservice = x25service = bridgeservice = 0;
+ continue;
+
+ case 'b':
+ ts_stacks = TS_BRG;
+ bridgeservice = 1;
+ tcpservice = x25service = tp4service = 0;
+ continue;
+
+ case 'r': /* ignored... */
+ continue;
+
+ case 'D':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -D DIT", pgmname);
+ if (*ap == '@')
+ (void) strcpy (base, ap);
+ else
+ (void) sprintf (base, "%s@%s", local_dit, ap);
+ continue;
+
+ case 'm':
+ options |= SVC_OPT_DONTUSECOPY;
+ continue;
+
+ case 'c':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -c DSA-name-or-address",
+ pgmname);
+ continue;
+
+ case 'u':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -u username", pgmname);
+ if ((userdn = str2dn (*ap != '@' ? ap : ap + 1)) == NULLDN)
+ adios (NULLCP, "invalid DN for username: %s", ap);
+ bzero ((char *) ap, strlen (ap));
+ continue;
+
+ case 'p':
+ if ((ap = *++vec) == NULL || *ap == '-')
+ adios (NULLCP, "usage: %s -p password", pgmname);
+ (void) strcpy (passwd, ap);
+ bzero ((char *) ap, strlen (ap));
+ continue;
+
+ default:
+ adios (NULLCP, "-%s: unknown switch", ap);
+ }
+
+ adios (NULLCP, "usage: %s [switches]", pgmname);
+ }
+
+ {
+ Attr_Sequence as;
+ AttributeType t_oc;
+ DN local_dn;
+ register Filter fi;
+ register struct ds_search_arg *sa = &search_arg;
+
+ if ((t_ev = str2AttrT ("execVector")) == NULL)
+ adios (NULLCP, "unknown attribute type \"%s\"", "execVector");
+ if ((t_oc = str2AttrT ("objectClass")) == NULL)
+ adios (NULLCP, "unknown attribute type \"%s\"", "objectClass");
+ if ((t_pa = str2AttrT ("presentationAddress")) == NULL)
+ adios (NULLCP, "unknown attribute type \"%s\"",
+ "presentationAddress");
+
+ if (str2dnY (*base != '@' ? base : base + 1, &local_dn) == NOTOK)
+ adios (NULLCP, "DIT subtree invalid: \"%s\"", base);
+
+ fi = filter_alloc ();
+ bzero ((char *) fi, sizeof *fi);
+
+ fi -> flt_type = FILTER_ITEM;
+ fi -> FUITEM.fi_type = FILTERITEM_EQUALITY;
+ fi -> FUITEM.UNAVA.ava_type = AttrT_cpy (t_oc);
+ if ((fi -> FUITEM.UNAVA.ava_value =
+ str2AttrV ("iSODEApplicationEntity",
+ fi -> FUITEM.UNAVA.ava_type -> oa_syntax))
+ == NULL)
+ adios (NULLCP, "unknown attribute value \"%s\" for \"%s\"",
+ "iSODEApplicationEntity", "objectClass");
+
+ as = as_merge (as_comp_new (AttrT_cpy (t_ev), NULLAV, NULLACL_INFO),
+ as_comp_new (AttrT_cpy (t_pa), NULLAV, NULLACL_INFO));
+
+ bzero ((char *) sa, sizeof *sa);
+
+ sa -> sra_common.ca_servicecontrol.svc_options = options;
+ sa -> sra_common.ca_servicecontrol.svc_timelimit = SVC_NOTIMELIMIT;
+ sa -> sra_common.ca_servicecontrol.svc_sizelimit = SVC_NOSIZELIMIT;
+ sa -> sra_baseobject = local_dn;
+ sa -> sra_subset = SRA_WHOLESUBTREE;
+ sa -> sra_filter = fi;
+ sa -> sra_searchaliases = TRUE;
+ sa -> sra_eis.eis_allattributes = FALSE;
+ sa -> sra_eis.eis_select = as;
+ sa -> sra_eis.eis_infotypes = EIS_ATTRIBUTESANDVALUES;
+
+ search_directory (1);
+ }
+}
+
+/* \f */
+
+static search_directory (firstime)
+int firstime;
+{
+ int i;
+ register struct ds_search_arg *sa = &search_arg;
+ struct ds_search_result search_result;
+ register struct ds_search_result *sr = &search_result;
+ struct DSError error;
+ register struct DSError *se = &error;
+ register EntryInfo *ptr;
+ register struct IAEntry *ia;
+ register struct TSAPaddr *ta,
+ *tb,
+ *ty;
+ struct TSAPaddr tys[NTADDRS];
+
+ advise (LLOG_NOTICE, NULLCP,
+ "searching directory for iSODEApplicationEntity objects");
+
+ while (rebind_to_directory () == NOTOK) {
+ if (!firstime)
+ return;
+
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "sleeping for 5 minutes...");
+ sleep ((unsigned) 5 * 60);
+ }
+
+ for (;;) {
+ if (debug) {
+ pslog (pgm_log, LLOG_DEBUG, "performing subtree search of",
+ dn_print, (caddr_t) sa -> sra_baseobject);
+ pslog (pgm_log, LLOG_DEBUG, " for", fi_print,
+ (caddr_t) sa -> sra_filter);
+ }
+
+ if (ds_search (sa, se, sr) == DS_OK)
+ break;
+ if (do_error (se) == NOTOK) {
+ if (!firstime)
+ return;
+
+ adios (NULLCP, "search failed");
+ }
+
+ sa -> sra_baseobject =
+ se -> ERR_REFERRAL.DSE_ref_candidates -> cr_name;
+ }
+
+ if (sr -> srr_correlated != TRUE)
+ correlate_search_results (sr);
+
+ if (!firstime)
+ for (ia = iae; ia < iz; ia++) {
+ free (ia -> is_vector);
+ free (ia -> is_vec[0]);
+ free ((char *) ia -> is_vec);
+ }
+
+ bzero ((char *) iae, sizeof iae);
+ iz = iae;
+
+ bzero ((char *) tys, sizeof tys);
+ ty = tys;
+
+ i = 0;
+ for (ptr = sr -> CSR_entries; ptr; ptr = ptr -> ent_next) {
+ Attr_Sequence eptr;
+ AV_Sequence avs;
+
+ if (iz >= iae + NENTRIES) {
+ pslog (pgm_log, LLOG_EXCEPTIONS,
+ "too many services, starting with", dn_print,
+ (caddr_t) ptr -> ent_dn);
+ break;
+ }
+
+ if (debug) {
+ pslog (pgm_log, LLOG_DEBUG, "processing", dn_print,
+ (caddr_t) ptr -> ent_dn);
+ pslog (pgm_log, LLOG_DEBUG, " attributes", as_print,
+ (caddr_t) ptr -> ent_attr);
+ }
+
+ for (eptr = ptr -> ent_attr; eptr; eptr = eptr -> attr_link) {
+ if (AttrT_cmp (eptr -> attr_type, t_pa) == 0) {
+ if (avs = eptr -> attr_value) {
+ register struct PSAPaddr *pa =
+ (struct PSAPaddr *) avs -> avseq_av.av_struct;
+
+ if ((ta = &pa -> pa_addr.sa_addr) -> ta_selectlen == 0
+ || pa -> pa_selectlen > 0
+ || pa -> pa_addr.sa_selectlen > 0)
+ continue;
+
+ iz -> is_addr = *ta; /* struct copy */
+ }
+
+ continue;
+ }
+
+ if (AttrT_cmp (eptr -> attr_type, t_ev) == 0) {
+ if (avs = eptr -> attr_value) {
+ int vecp;
+ register char **vp;
+ char *cp,
+ *evec[NVEC + NSLACK + 1];
+
+ cp = (char *) avs -> avseq_av.av_struct;
+ if ((iz -> is_vector =
+ malloc ((unsigned) (strlen (cp) + 1)))
+ == NULL)
+ adios (NULLCP, "out of memory allocating iaeVector");
+ (void) strcpy (iz -> is_vector, cp);
+
+ if ((vecp = str2vec (iz -> is_vector, evec)) < 1)
+ goto losing_iae;
+ if ((iz -> is_vec =
+ (char **) calloc ((unsigned) (vecp + 3),
+ sizeof *iz -> is_vec))
+ == NULL)
+ adios (NULLCP, "out of memory allocating execVector");
+ iz -> is_tail = iz -> is_vec, vp = evec;
+ while (*iz -> is_tail++ = *vp++)
+ continue;
+ iz -> is_tail--;
+
+ if (access (cp = isodefile (iz -> is_vec[0], 1), X_OK)
+ == NOTOK) {
+ advise (LLOG_EXCEPTIONS, cp, "unable to find program");
+ iz -> is_vec[0] = NULL;
+ goto losing_iae;
+ }
+ if ((iz -> is_vec[0] =
+ malloc ((unsigned) (strlen (cp) + 1)))
+ == NULL)
+ adios (NULLCP, "out of memory allocating pgmVector");
+ (void) strcpy (iz -> is_vec[0], cp);
+ }
+ continue;
+ }
+ }
+ if ((ta = &iz -> is_addr) -> ta_selectlen == 0
+ || iz -> is_vector == NULL) {
+ pslog (pgm_log, LLOG_EXCEPTIONS, "invalid entry", dn_print,
+ (caddr_t) ptr -> ent_dn);
+
+losing_iae: ;
+ if (iz -> is_vector)
+ free (iz -> is_vector);
+ if (iz -> is_vec) {
+ if (iz -> is_vec[0])
+ free (iz -> is_vec[0]);
+ free ((char *) iz -> is_vec);
+ }
+ bzero ((char *) iz, sizeof *iz);
+ continue;
+ }
+
+ if (ta -> ta_naddr == 0)
+ *ty++ = *ta; /* struct copy */
+ else {
+ register int n = ta -> ta_naddr;
+ register struct NSAPaddr *na = ta -> ta_addrs;
+
+ for (; n > 0; na++, n--) {
+ for (tb = tys; tb < ty; tb++)
+ if (tb -> ta_naddr != 0
+ && bcmp ((char *) na, (char *) tb -> ta_addrs,
+ sizeof *na) == 0)
+ break;
+ if (tb >= ty) {
+ if (na -> na_type == NA_NSAP)
+ bcopy (ta -> ta_selector, ty -> ta_selector,
+ ty -> ta_selectlen = ta -> ta_selectlen);
+ else
+ ty -> ta_selectlen = 0;
+ ty -> ta_naddr = 1;
+ ty -> ta_addrs[0] = *na; /* struct copy */
+
+ ty++;
+ }
+ }
+ }
+
+ for (ia = iae; ia < iz; ia++) {
+ tb = &ia -> is_addr;
+
+ if (ta -> ta_selectlen == tb -> ta_selectlen
+ && bcmp (ta -> ta_selector, tb -> ta_selector,
+ ta -> ta_selectlen) == 0) {
+ char buffer[BUFSIZ];
+
+ (void) strcpy (buffer, taddr2str (tb));
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "two services with the same transport selector: %s and %s",
+ buffer, taddr2str (ta));
+ pslog (pgm_log, LLOG_EXCEPTIONS, "starting with", dn_print,
+ (caddr_t) ptr -> ent_dn);
+ adios (NULLCP, "you lose big");
+ }
+ }
+
+ iz++, i++;
+ }
+
+ if (sr -> CSR_cr) {
+ advise (LLOG_EXCEPTIONS, NULLCP,
+ "partial results only (not all DSAs could be reached)");
+ }
+ else
+ if (sr -> CSR_limitproblem != LSR_NOLIMITPROBLEM) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "%s limit exceeded",
+ sr -> CSR_limitproblem == LSR_TIMELIMITEXCEEDED
+ ? "time"
+ : sr -> CSR_limitproblem == LSR_SIZELIMITEXCEEDED
+ ? "size" : "administrative");
+ }
+
+ if (i == 0)
+ adios (NULLCP, "search failed to find anything");
+ else
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "%d match%s found",
+ i, i != 1 ? "es" : "");
+
+ dn_free (sr -> CSR_object);
+ entryinfo_free (sr -> CSR_entries, 0);
+ crefs_free (sr -> CSR_cr);
+
+ (void) unbind_from_directory ();
+
+ if (!firstime) {
+ int failed = 0;
+ struct TSAPdisconnect tds;
+
+ for (ta = tas; ta < tz; ta++) {
+ for (tb = tys; tb < ty; tb++)
+ if (bcmp ((char *) ta, (char *) tb, sizeof *ta) == 0)
+ break;
+ if (tb >= ty) {
+ advise (LLOG_NOTICE, NULLCP, "closing %s", taddr2str (ta));
+
+ if (TNetClose (ta, &tds) == NOTOK)
+ ts_advise (&tds, LLOG_EXCEPTIONS, "TNetClose failed");
+
+ listening--;
+ }
+ }
+
+ for (ta = tys; ta < ty; ta++) {
+ for (tb = tas; tb < tz; tb++)
+ if (bcmp ((char *) ta, (char *) tb, sizeof *ta) == 0)
+ break;
+ if (tb >= tz) {
+ register struct NSAPaddr *na;
+
+ if (ta -> ta_naddr) {
+ if (((na = ta -> ta_addrs) -> na_stack < 0
+ || na -> na_stack
+ >= sizeof services / sizeof services[0]))
+ adios (NULLCP, "unknown network type 0x%x",
+ na -> na_stack);
+ }
+ else
+ na = NULLNA;
+
+ if (!*services[na ? na -> na_stack : NA_NSAP])
+ continue;
+
+ advise (LLOG_NOTICE, NULLCP, "listening on %s",
+ taddr2str (ta));
+
+ if (TNetListen (ta, &tds) == NOTOK) {
+ ts_advise (&tds, LLOG_EXCEPTIONS, "TNetListen failed");
+ failed++;
+ }
+ else
+ listening++;
+ }
+ }
+
+ if (!listening)
+ adios (NULLCP, failed ? "no successful listens"
+ : "no network services selected");
+
+ }
+ bzero ((char *) tas, sizeof tas);
+ tz = tas;
+
+ for (ta = tys; ta < ty; *tz++ = *ta++) /* struct copy */
+ continue;
+
+ if (debug) {
+ advise (LLOG_DEBUG, NULLCP, "application entitites...");
+ for (ia = iae; ia < iz; ia++)
+ advise (LLOG_DEBUG, NULLCP, " addr=%s vector=%s",
+ taddr2str (&ia -> is_addr), ia -> is_vector);
+
+ advise (LLOG_DEBUG, NULLCP, "transport addresses...");
+ for (ta = tas; ta < tz; ta++)
+ advise (LLOG_DEBUG, NULLCP, " addr=%s", taddr2str (ta));
+ }
+
+ (void) time (&nextime);
+ nextime += IAETIME;
+}
+
+/* \f */
+
+static bind_to_directory ()
+{
+ struct ds_bind_arg bind_arg,
+ bind_result;
+ register struct ds_bind_arg *ba = &bind_arg,
+ *br = &bind_result;
+ struct ds_bind_error bind_error;
+ register struct ds_bind_error *be = &bind_error;
+ static int very_first_time = 1;
+
+ (void) unbind_from_directory ();
+
+ make_bind_args (ba, br, be);
+
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "connecting to DSA...");
+
+ if (secure_ds_bind (ba, be, br) != DS_OK) {
+ if (very_first_time)
+ very_first_time = 0;
+ else
+ advise (LLOG_EXCEPTIONS, NULLCP, "unable to connect: %s",
+ be -> dbe_type == DBE_TYPE_SECURITY ? "security error"
+ : "DSA unavailable");
+
+ isbound = 0;
+
+ return;
+ }
+ very_first_time = 0;
+ dn_free (br -> dba_dn);
+
+ main_dsa = dsap_ad;
+
+ advise (LLOG_NOTICE, NULLCP, "connected to %s", pa2str (&dsa_bound));
+
+ isbound = 1;
+}
+
+/* \f */
+
+static int rebind_to_directory ()
+{
+ if (referral_dsa != NOTOK) {
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+ (void) dap_unbind (referral_dsa);
+ referral_dsa = NOTOK;
+ dsap_ad = main_dsa;
+ }
+
+ if (!isbound)
+ (void) bind_to_directory ();
+
+ return (isbound ? OK : NOTOK);
+}
+
+/* \f */
+
+static int make_bind_args (ba, br, be)
+register struct ds_bind_arg *ba,
+ *br;
+register struct ds_bind_error *be;
+{
+ bzero ((char *) ba, sizeof *ba);
+ bzero ((char *) br, sizeof *br);
+ bzero ((char *) be, sizeof *be);
+
+ ba -> dba_version = DBA_VERSION_V1988;
+ if (ba -> dba_dn = userdn)
+ ba -> dba_auth_type = DBA_AUTH_SIMPLE;
+ if (ba -> dba_passwd_len = strlen (passwd))
+ (void) strcpy (ba -> dba_passwd, passwd);
+}
+
+/* \f */
+
+static int unbind_from_directory ()
+{
+ int wasbound;
+
+ if (wasbound = isbound) {
+ if (referral_dsa != NOTOK) {
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+ (void) dap_unbind (referral_dsa);
+ referral_dsa = NOTOK;
+ dsap_ad = main_dsa;
+ }
+
+ (void) ds_unbind ();
+ isbound = 0;
+ }
+
+ dsa_dead = 0;
+
+ return wasbound;
+}
+
+/* \f */
+
+static int do_error (de)
+register struct DSError *de;
+{
+ if (de -> dse_type == DSE_REFERRAL
+ && de -> ERR_REFERRAL.DSE_ref_candidates) {
+ register struct access_point *ap;
+ struct ds_bind_arg bind_arg,
+ bind_result;
+ register struct ds_bind_arg *ba = &bind_arg,
+ *br = &bind_result;
+ struct ds_bind_error bind_error;
+ register struct ds_bind_error *be = &bind_error;
+
+ ap = de -> ERR_REFERRAL.DSE_ref_candidates -> cr_accesspoints;
+
+ if (referral_dsa != NOTOK) {
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+ (void) dap_unbind (referral_dsa);
+ referral_dsa = NOTOK;
+ dsap_ad = main_dsa;
+ }
+
+ make_bind_args (ba, br, be);
+
+ pslog (pgm_log, LLOG_NOTICE, "referring to", dn_print,
+ (caddr_t) ap -> ap_name);
+
+ if (dap_bind (&referral_dsa, ba, be, br, ap -> ap_address) != DS_OK) {
+ advise (LLOG_EXCEPTIONS, NULLCP, "unable to connect: %s",
+ be -> dbe_type == DBE_TYPE_SECURITY ? "security error"
+ : "DSA unavailable");
+
+ dsap_ad = main_dsa;
+
+ ds_error_free (de);
+ return NOTOK;
+ }
+ dsap_ad = referral_dsa;
+
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "referral in progress");
+
+ ds_error_free (de);
+ return OK;
+ }
+
+ pslog (pgm_log, LLOG_EXCEPTIONS, "DAP error:", de_print, (caddr_t) de);
+
+ if (dsa_dead) {
+ dsa_dead = 0;
+
+ if (referral_dsa != NOTOK) {
+ if (debug)
+ advise (LLOG_DEBUG, NULLCP, "dap_unbind from referral dsa");
+
+ (void) dap_unbind (referral_dsa);
+ referral_dsa = NOTOK;
+ dsap_ad = main_dsa;
+ }
+ else
+ (void) unbind_from_directory ();
+ }
+
+ return NOTOK;
+}
+
+/* \f */
+
+int str2dnY (str, dn)
+char *str;
+DN *dn;
+{
+ if (*str == NULL) {
+ *dn = NULLDN;
+ return OK;
+ }
+
+ return ((*dn = str2dn (str)) != NULLDN ? OK : NOTOK);
+}
+
+/* \f */
+
+#ifdef BSD42
+/* ARGSUSED */
+#endif
+
+static SFD hupser (sig)
+int sig;
+{
+#ifndef BSD42
+ (void) signal (sig, hupser);
+#endif
+
+ search_directory (0);
+}
+#endif
+
+/* \f */
+
+static envinit () {
+ int i,
+ sd;
+
+ nbits = getdtablesize ();
+
+ if (debug == 0 && !(debug = isatty (2))) {
+ for (i = 0; i < 5; i++) {
+ switch (fork ()) {
+ case NOTOK:
+ sleep (5);
+ continue;
+
+ case OK:
+ break;
+
+ default:
+ _exit (0);
+ }
+ break;
+ }
+
+ (void) chdir ("/");
+
+ if ((sd = open ("/dev/null", O_RDWR)) == NOTOK)
+ adios ("/dev/null", "unable to read");
+ if (sd != 0)
+ (void) dup2 (sd, 0), (void) close (sd);
+ (void) dup2 (0, 1);
+ (void) dup2 (0, 2);
+
+#ifdef SETSID
+ if (setsid () == NOTOK)
+ advise (LLOG_EXCEPTIONS, "failed", "setsid");
+#endif
+#ifdef TIOCNOTTY
+ if ((sd = open ("/dev/tty", O_RDWR)) != NOTOK) {
+ (void) ioctl (sd, TIOCNOTTY, NULLCP);
+ (void) close (sd);
+ }
+#else
+#ifdef SYS5
+ (void) setpgrp ();
+ (void) signal (SIGINT, SIG_IGN);
+ (void) signal (SIGQUIT, SIG_IGN);
+#endif
+#endif
+ }
+ else
+ ll_dbinit (pgm_log, pgmname);
+
+#ifndef sun /* damn YP... */
+ for (sd = 3; sd < nbits; sd++)
+ if (pgm_log -> ll_fd != sd)
+ (void) close (sd);
+#endif
+
+ (void) signal (SIGPIPE, SIG_IGN);
+
+ ll_hdinit (pgm_log, pgmname);
+ advise (LLOG_NOTICE, NULLCP, "starting");
+
+#ifdef IAE
+ (void) signal (SIGHUP, hupser);
+#endif
+}
+
+/* \f ERRORS */
+
+#ifndef lint
+void adios (va_alist)
+va_dcl
+{
+ va_list ap;
+
+ va_start (ap);
+
+ _ll_log (pgm_log, LLOG_FATAL, ap);
+
+ va_end (ap);
+
+ _exit (1);
+}
+#else
+/* VARARGS */
+
+void adios (what, fmt)
+char *what,
+ *fmt;
+{
+ adios (what, fmt);
+}
+#endif
+
+
+#ifndef lint
+void advise (va_alist)
+va_dcl
+{
+ int code;
+ va_list ap;
+
+ va_start (ap);
+
+ code = va_arg (ap, int);
+
+ _ll_log (pgm_log, code, ap);
+
+ va_end (ap);
+}
+#else
+/* VARARGS */
+
+void advise (code, what, fmt)
+char *what,
+ *fmt;
+int code;
+{
+ advise (code, what, fmt);
+}
+#endif
--- /dev/null
+###############################################################################
+# Instructions to Make, for compilation of ISODE TSAP processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/tsap/RCS/Makefile,v 7.3 91/02/22 09:47:03 mrose Interim $
+#
+#
+# $Log: Makefile,v $
+# Revision 7.3 91/02/22 09:47:03 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/12/23 18:43:23 mrose
+# update
+#
+# Revision 7.1 90/07/09 14:51:03 mrose
+# sync
+#
+# Revision 7.0 89/11/23 22:30:25 mrose
+# Release 6.0
+#
+###############################################################################
+
+###############################################################################
+#
+# NOTICE
+#
+# Acquisition, use, and distribution of this module and related
+# materials are subject to the restrictions of a license agreement.
+# Consult the Preface in the User's Manual for the full terms of
+# this agreement.
+#
+###############################################################################
+
+
+LIBES = libtsap.a $(TOPDIR)libcompat.a
+LLIBS = $(TOPDIR)llib-lcompat
+HFILES = $(HDIR)tsap.h $(HDIR)isoaddrs.h \
+ $(HDIR)manifest.h $(HDIR)general.h $(HDIR)config.h
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all: libtsap
+inst-all: # inst-libtsap manuals
+install: inst-all clean
+lint: l-libtsap
+
+
+################################################################
+# libtsap
+################################################################
+
+CFILES = tsaprovider.c tsaperror.c tsapstate.c \
+ fd2tpkt.c str2tpkt.c text2tpkt.c \
+ tsaprespond.c tsapinitiate.c tsaplose.c \
+ tsaplisten.c tsapmgmt.c tsapmisc.c \
+ tp0ts.c ts2tcp.c ts2x25.c ts2bridge.c \
+ ts2bsd.c ts2sunlink.c $(CTSAP)
+OFILES = tsaprovider.o tsaperror.o tsapstate.o \
+ fd2tpkt.o str2tpkt.o text2tpkt.o \
+ tsaprespond.o tsapinitiate.o tsaplose.o \
+ tsaplisten.o tsapmgmt.o tsapmisc.o \
+ tp0ts.o ts2tcp.o ts2x25.o ts2bridge.o \
+ ts2bsd.o ts2sunlink.o $(OTSAP) \
+ $(OSTRINGS)
+
+
+inst-libtsap: $(LIBDIR)libtsap.a $(LINTDIR)llib-ltsap
+
+$(LIBDIR)libtsap.a: libtsap.a
+ -rm -f $@
+ cp libtsap.a $@
+ @$(UTILDIR)make-lib.sh $(SYSTEM) $@ -ranlib
+ -@ls -gls $@
+ -@echo ""
+
+$(LINTDIR)llib-ltsap: llib-ltsap
+ -cp $@ zllib-ltsap
+ -rm -f $@
+ sed -e 's%#include "\(.*\)"%#include "$(INCDIR)\1"%' \
+ < llib-ltsap | \
+ sed -e 's%#include "/usr/include/\(.*\)"%#include <\1>%' > $@
+ @$(UTILDIR)inst-lint.sh $(SYSTEM) $(OPTIONS) $@
+ -@ls -gls $@ $@.ln
+ -@echo ""
+
+libtsap: libtsap.a
+
+libtsap.a: tsapvrsn.o
+ -rm -f $@
+ @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(OFILES) \
+ tsapvrsn.o
+ -@rm -f $(TOPDIR)libtsap.a $(TOPDIR)llib-ltsap
+ -@$(LN) libtsap.a $(TOPDIR)libtsap.a
+ -@$(LN) llib-ltsap $(TOPDIR)llib-ltsap
+ -@ls -l $@
+ -@echo "TSAP library built normally"
+
+tsapvrsn.c: $(OFILES)
+ @$(UTILDIR)version.sh tsap > $@
+
+l-libtsap:; $(LINT) $(LFLAGS) $(CFILES) tsapvrsn.c $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+tsaprovider.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)x25.h $(HDIR)isoservent.h \
+ $(HDIR)tailor.h $(HDIR)logger.h $(HDIR)mpkt.h
+tsaperror.o: $(HFILES)
+tsapstate.o: $(HDIR)tpkt.h $(HFILES)
+fd2tpkt.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+str2tpkt.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+text2tpkt.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)logger.h
+tsaprespond.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+tsapinitiate.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)isoservent.h $(HDIR)tailor.h \
+ $(HDIR)logger.h $(HDIR)mpkt.h
+tsaplose.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \
+ $(HDIR)mpkt.h
+tsaplisten.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)mpkt.h $(HDIR)internet.h \
+ $(HDIR)x25.h $(HDIR)tp4.h
+tsapmgmt.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)mpkt.h
+tsapmisc.o: $(HDIR)tpkt.h $(HFILES)
+tp0ts.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h \
+ $(HDIR)mpkt.h
+ts2tcp.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)internet.h $(HDIR)tailor.h \
+ $(HDIR)logger.h
+ts2x25.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)x25.h $(HDIR)tailor.h \
+ $(HDIR)logger.h
+ts2x25.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ts2bridge.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tailor.h $(HDIR)logger.h
+ts2bsd.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tp4.h $(HDIR)mpkt.h
+ts2sunlink.o: $(HDIR)tpkt.h $(HFILES) $(HDIR)tp4.h $(HDIR)mpkt.h
+
+
+################################################################
+# manual pages
+################################################################
+
+MANUALS = libtsap.3n
+
+manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+ -@echo ""
+
+
+################################################################
+# clean
+################################################################
+
+clean:; rm -f *.o *.a z* _* core tsapvrsn.c
+
+grind:; iprint Makefile
+ tgrind -lc $(CFILES) tsapvrsn.c llib-ltsap
+ @echo $(MANUALS) | \
+ tr " " "\012" | \
+ sed -e "s%.*%itroff -man &%" | \
+ sh -ve
--- /dev/null
+.TH LIBTSAP 3N "31 May 1988"
+.\" $Header: /f/osi/tsap/RCS/libtsap.3n,v 7.1 91/02/22 09:47:06 mrose Interim $
+.\"
+.\"
+.\" $Log: libtsap.3n,v $
+.\" Revision 7.1 91/02/22 09:47:06 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:30:28 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+libtsap \- Transport Services library
+.SH SYNOPSIS
+.B "#include <isode/tsap.h>"
+.sp
+\fIcc\fR\0...\0\fB\-ltsap\fR
+.SH DESCRIPTION
+The \fIlibtsap\fR library contains a set of routines which implement
+transport services on top of the TCP.
+In essence,
+they implement a Transport Service Access Point (TSAP) interface to the
+native TCP/IP implementation on Berkeley UNIX.
+.PP
+Although the ISO model is symmetric,
+the TCP/IP model (and this implementation) is based on a client/server
+paradigm and hence asymmetric.
+The information herein is skeletal:
+consult the \fIUser's Manual\fR for actual examples of how ISO servers and
+clients are coded and interact with the \fIlibtsap\fR library.
+.SH ADDRESSES
+TSAP addresses are represented by the \fBTSAPaddr\fR structure.
+This contains one more more network addresses,
+and a transport-selector as found in the \fIisoservices\fR\0(5)
+database.
+.SH "SERVER INITIALIZATION"
+A program providing an ISO service is invoked under \fItsapd\fR\0(8c),
+with the argument vector listed in the ISODE services database.
+The server's very first action is to re\-capture the TSAP
+state as recorded by \fItsapd\fR.
+This is accomplished by calling \fBTInit\fR.
+Information returned by this call is equivalent to the parameters passed by a
+T\-CONNECTION.INDICATION event.
+If the call is successful,
+the program can then examine the argument vector that was passed via
+\fIexecvp\fR
+(it's important to call \fBTInit\fR prior to reading \fBargc\fR and
+\fBargv\fR).
+If the call to \fBTInit\fR is not successful,
+information returned by the call indicates the reason for failure.
+.PP
+After examining the information provided by \fBTInit\fR
+(and possibly the argument vector),
+the server should either accept or reject the connection.
+If accepting, the \fBTConnResponse\fR routine is called
+(which corresponds to the T\-CONNECT.RESPONSE action).
+If the call is successful,
+the interaction is henceforth symmetric.
+If un\-successful,
+information returned by the call indicates the reason for failure.
+If rejecting, the \fBTDiscRequest\fR routine is called
+(which corresponds to the T\-DISCONNECT.REQUEST action),
+and the program may exit.
+.SH "CLIENT INITIALIZATION"
+A program requesting an ISO service calls \fBTConnRequest\fR
+(which corresponds to the T\-CONNECT.REQUEST action).
+If successful,
+the interaction is henceforth symmetric.
+If un\-successful,
+information returned by the call indicates the reason for failure.
+.SH TRANSPORT\-DESCRIPTORS
+Once a connection has been established via a successful return from
+\fBTConnResponse\fR (for servers) or \fBTConnRequest\fR (for clients),
+a connection is referenced by a small integer
+(returned in a structure passed to these calls) called a
+\fItransport\-descriptor\fR.
+The transport\-descriptor appears as an argument to the peer routines described
+below.
+.PP
+By default,
+events associated with a transport\-descriptor are synchronous in nature:
+activity in the network won't generate an INDICATION event without program
+first asking to be told of any activity.
+To mark a transport\-descriptor as asynchronous,
+a call to \fBTSetIndications\fR is made with the addresses of an integer
+function to handle these events:
+.sp
+.in +.5i
+.nf
+.ta \w'\fIroutine\fR 'u
+\fIroutine\fR \fIevents\fR
+\fBfunc1\fR T\-DATA.INDICATION, T\-EXPEDITED DATA.INDICATION
+\fBfunc2\fR T\-DISCONNECT.INDICATION
+.re
+.fi
+.in -.5i
+.sp
+Upon a successful return from \fBTSetIndications\fR,
+these functions will be called as appropriate in this fashion:
+.sp
+.in +.5i
+.B "(*func1) (sd, tx);"
+.sp
+.B "(*func2) (sd, td);"
+.in -.5i
+.sp
+where \fBsd\fR is the transport\-descriptor,
+\fBtx\fR is a pointer to a \fBTSAPdata\fR structure,
+and \fBtd\fR is a pointer to a \fBTSAPdisconnect\fR structure.
+Any value returned by these functions is ignored.
+.PP
+Note well: the \fB\-ltsap\fR library uses the SIGEMT signal to provide this
+interface.
+Programs loaded with \fB\-ltsap\fR that use asynchronous transport\-descriptors
+should NOT use SIGEMT for other purposes.
+.PP
+For synchronous multiplexing of several connections,
+the routine \fBTSelectMask\fR updates a file\-descriptor mask and counter for
+use with \fIselect\fR\0(2).
+.SH PEER
+As a rule,
+a fatal failure (consult the \fIUser's Manual\fR)
+on return from any of these routines is equivalent to a
+T\-DISCONNECT.INDICATION.
+.sp
+.in +.5i
+.nf
+.ta \w'\fBTWriteRequest\fR 'u
+\fIroutine\fR \fIaction\fR
+\fBTDataRequest\fR T\-DATA.REQUEST
+\fBTExpdRequest\fR T\-EXPEDITED\-DATA.REQUEST
+\fBTWriteRequest\fR T\-WRITE.REQUEST (write user data vectors)
+\fBTReadRequest\fR T\-READ.REQUEST (synchronous read)
+\fBTDiscRequest\fR T\-DISCONNECT.REQUEST
+.re
+.fi
+.in -.5i
+.sp
+Note that the \fBTReadRequest\fR routine returns data from the peer by
+allocating memory.
+It should be freed before the structure is re\-used.
+.PP
+Finally,
+the routine \fBTErrString\fR takes a failure code from a \fBTSAPdisconnect\fR
+structure and returns a null\-terminated diagnostic string.
+Also,
+the routine \fBTLocalHostName\fR returns a null\-terminated string
+denoting the name of the localhost.
+.SH FILES
+.nf
+.ta \w'\*(EDisoservices 'u
+\*(EDisoservices ISODE services database
+.re
+.fi
+.SH "SEE ALSO"
+isoc(1c), isoservices(5), isod(8c), isore(8c), tsapd(8c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+\fIRFC1006: ISO Transport Services on top of the TCP, Version: 3\fR,
+.br
+ISO 8072:
+\fIInformation Processing Systems \-\- Open Systems Interconnection \-\-
+Transport Service Definition\fR,
+.br
+CCITT Recommendation X.214:
+\fITransport Service Definition for Open Systems Interconnection (OSI) for
+CCITT Applications\fR
+.SH DIAGNOSTICS
+All routines return the manifest constant \fBNOTOK\fR (\-1) on error.
+In addition,
+those routines which take a pointer to a \fBTSAPdisconnect\fR structure
+fill\-in the structure as appropriate.
+.SH AUTHORS
+Marshall T. Rose
+.br
+Dwight E. Cass,
+Northrop Research and Technology Center
+.SH BUGS
+Do not confuse transport\-descriptors with file\-descriptors.
+Unlike file\-descriptors which are implemented by the kernel,
+transport\-descriptors do not work across \fIfork\fRs and \fIexec\fRs.
--- /dev/null
+/* llib-ltsap - lint library for -ltsap */
+
+/*
+ * $Header: /f/osi/tsap/RCS/llib-ltsap,v 7.2 91/02/22 09:47:07 mrose Interim $
+ *
+ *
+ * $Log: llib-ltsap,v $
+ * Revision 7.2 91/02/22 09:47:07 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 89/12/18 17:50:13 mrose
+ * update
+ *
+ * Revision 7.0 89/11/23 22:30:29 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include "tsap.h"
+
+/* \f */
+
+/* T-CONNECT.INDICATION */
+
+int TInit (vecp, vec, ts, td)
+int vecp;
+char **vec;
+struct TSAPstart *ts;
+struct TSAPdisconnect *td;
+{
+ return TInit (vecp, vec, ts, td);
+}
+
+
+/* T-CONNECT.RESPONSE */
+
+int TConnResponse (sd, responding, expedited, data, cc, qos, td)
+int sd;
+struct TSAPaddr *responding;
+int expedited,
+ cc;
+char *data;
+struct QOStype *qos;
+struct TSAPdisconnect *td;
+{
+ return TConnResponse (sd, responding, expedited, data, cc, qos, td);
+}
+
+
+/* T-(ASYN-)CONNECT.REQUEST */
+
+int TAsynConnRequest (calling, called, expedited, data, cc, qos,
+ tc, td, async)
+struct TSAPaddr *calling,
+ *called;
+int expedited,
+ cc,
+ async;
+char *data;
+struct QOStype *qos;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+ return TAsynConnRequest (calling, called, expedited, data, cc, qos,
+ tc, td, async);
+}
+
+
+/* T-ASYN-RETRY.REQUEST (pseudo) */
+
+int TAsynRetryRequest (sd, tc, td)
+int sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+ return TAsynRetryRequest (sd, tc, td);
+}
+
+
+/* T-ASYN-NEXT.REQUEST (pseudo) */
+
+int TAsynNextRequest (sd, tc, td)
+int sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+ return TAsynNextRequest (sd, tc, td);
+}
+
+
+/* T-DATA.REQUEST */
+
+int TDataRequest (sd, data, cc, td)
+int sd;
+char *data;
+int cc;
+struct TSAPdisconnect *td;
+{
+ return TDataRequest (sd, data, cc, td);
+}
+
+
+/* T-WRITE.REQUEST (pseudo, write user data vectors) */
+
+int TWriteRequest (sd, uv, td)
+int sd;
+struct udvec *uv;
+struct TSAPdisconnect *td;
+{
+ return TWriteRequest (sd, uv, td);
+}
+
+
+/* T-EXPEDITED-DATA.REQUEST */
+
+int TExpdRequest (sd, data, cc, td)
+int sd;
+char *data;
+int cc;
+struct TSAPdisconnect *td;
+{
+ return TExpdRequest (sd, data, cc, td);
+}
+
+
+/* T-READ.REQUEST (pseudo; synchronous read) */
+
+int TReadRequest (sd, tx, secs, td)
+int sd;
+struct TSAPdata *tx;
+int secs;
+struct TSAPdisconnect *td;
+{
+ return TReadRequest (sd, tx, secs, td);
+}
+
+
+/* T-DISCONNECT.REQUEST */
+
+int TDiscRequest (sd, data, cc, td)
+int sd;
+char *data;
+int cc;
+struct TSAPdisconnect *td;
+{
+ return TDiscRequest (sd, data, cc, td);
+}
+
+
+/* define vectors for INDICATION events */
+
+int TSetIndications (sd, data, disc, td)
+int sd;
+IFP data,
+ disc;
+struct TSAPdisconnect *td;
+{
+ return TSetIndications (sd, data, disc, td);
+}
+
+
+/* map transport descriptors for select() */
+
+int TSelectMask (sd, mask, nfds, td)
+int sd;
+fd_set *mask;
+int *nfds;
+struct TSAPdisconnect *td;
+{
+ return TSelectMask (sd, mask, nfds, td);
+}
+
+
+/* estimate of octets that might be returned */
+
+int TSelectOctets (sd, nbytes, td)
+int sd;
+long *nbytes;
+struct TSAPdisconnect *td;
+{
+ return TSelectOctets (sd, nbytes, td);
+}
+
+
+/* get TSAPs */
+
+int TGetAddresses (sd, initiating, responding, td)
+int sd;
+struct TSAPaddr *initiating,
+ *responding;
+struct TSAPdisconnect *td;
+{
+ return TGetAddresses (sd, initiating, responding, td);
+}
+
+
+/* define transport manager */
+
+#ifdef MGMT
+int TSetManager (sd, fnx, td)
+int sd;
+IFP fnx;
+struct TSAPdisconnect *td;
+{
+ return TSetManager (sd, fnx, td);
+}
+#endif
+
+
+/* save the state of a connection */
+
+int TSaveState (sd, vec, td)
+int sd;
+char **vec;
+struct TSAPdisconnect *td;
+{
+ return TSaveState (sd, vec, td);
+}
+
+
+/* restore the state of a connection */
+
+int TRestoreState (buffer, ts, td)
+char *buffer;
+struct TSAPstart *ts;
+struct TSAPdisconnect *td;
+{
+ return TRestoreState (buffer, ts, td);
+}
+
+
+/* return TSAP error code in string form */
+
+char *TErrString (c)
+int c;
+{
+ return TErrString (c);
+}
+
+
+/* start listening on an TSAP */
+
+int TNetListen (ta, td)
+struct TSAPaddr *ta;
+struct TSAPdisconnect *td;
+{
+ return TNetListen (ta, td);
+}
+
+
+/* start listening on a set of unique TSAPs */
+
+int TNetUnique (ta, td)
+struct TSAPaddr *ta;
+struct TSAPdisconnect *td;
+{
+ return TNetUnique (ta, td);
+}
+
+
+/* accept a call on an TSAP */
+
+int TNetAcceptAux (vecp, vec, newfd, ta, nfds, rfds, wfds, efds, secs, td)
+int *vecp;
+char **vec;
+int *newfd;
+struct TSAPaddr *ta;
+int nfds;
+fd_set *rfds,
+ *wfds,
+ *efds;
+int secs;
+struct TSAPdisconnect *td;
+{
+ return TNetAcceptAux (vecp, vec, newfd, ta, nfds, rfds, wfds, efds, secs,
+ td);
+}
+
+
+/* stop listening on an TSAP */
+
+int TNetClose (ta, td)
+struct TSAPaddr *ta;
+struct TSAPdisconnect *td;
+{
+ return TNetClose (ta, td);
+}
+
+
+/* fork after accepting a connection */
+
+int TNetFork (vecp, vec, td)
+int vecp;
+char **vec;
+struct TSAPdisconnect *td;
+{
+ return TNetFork (vecp, vec, td);
+}
+
+
+/* enable/disable queued (non-blocking) writes */
+
+int TSetQueuesOK (sd, onoff, td)
+int sd;
+int onoff;
+struct TSAPdisconnect *td;
+{
+ return TSetQueuesOK (sd, onoff, td);
+}
--- /dev/null
+: run this script through /bin/sh
+M=/bin/make
+if [ -f /usr/bin/make ]; then
+ M=/usr/bin/make
+fi
+
+exec $M MODULE=tsap TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"}
--- /dev/null
+/* str2tpkt.c - read/write a TPDU thru a string */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/str2tpkt.c,v 7.2 91/02/22 09:47:11 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/str2tpkt.c,v 7.2 91/02/22 09:47:11 mrose Interim $
+ *
+ *
+ * $Log: str2tpkt.c,v $
+ * Revision 7.2 91/02/22 09:47:11 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 89/12/07 01:07:28 mrose
+ * queued writes
+ *
+ * Revision 7.0 89/11/23 22:30:30 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+
+int readfnx (), getfnx (), writefnx (), putfnx ();
+
+/* \f */
+
+char *tpkt2str (t)
+struct tsapkt *t;
+{
+ int cc;
+ char packet[BUFSIZ];
+ static char buffer[2 * sizeof packet + 1];
+
+ (void) writefnx ((struct tsapblk *) NOTOK, packet, 0);
+ if (tpkt2fd ((struct tsapblk *) 0, t, putfnx) == NOTOK)
+ return NULLCP;
+
+ cc = writefnx ((struct tsapblk *) NOTOK, NULLCP, 0);
+ if (t -> t_qbuf) {
+ bcopy (t -> t_qbuf -> qb_data, packet + cc, t -> t_qbuf -> qb_len);
+ cc += t -> t_qbuf -> qb_len;
+ }
+ buffer[explode (buffer, (u_char *) packet, cc)] = NULL;
+
+ DLOG (tsap_log, LLOG_PDUS,
+ ("write %d bytes, \"%s\"", strlen (buffer), buffer));
+
+ return buffer;
+}
+
+/* \f */
+
+struct tsapkt *str2tpkt (buffer)
+char *buffer;
+{
+ char packet[BUFSIZ];
+ register struct tsapkt *t;
+
+ DLOG (tsap_log, LLOG_PDUS,
+ ("read %d bytes, \"%s\"", strlen (buffer), buffer));
+
+ (void) getfnx (NOTOK, NULLPKT, packet,
+ implode ((u_char *) packet, buffer, strlen (buffer)));
+ t = fd2tpkt (0, getfnx, readfnx);
+
+ return t;
+}
+
+/* \f */
+
+static int getfnx (fd, t, buffer, n)
+int fd;
+register struct tsapkt *t;
+char *buffer;
+int n;
+{
+ static int cc;
+
+ if (fd == NOTOK) {
+ (void) readfnx (NOTOK, buffer, cc = n);
+ return OK;
+ }
+
+ t -> t_length = cc + sizeof t -> t_pkthdr;
+ t -> t_vrsn = TPKT_VRSN;
+
+ if (readfnx (fd, (char *) &t -> t_li, sizeof t -> t_li)
+ != sizeof t -> t_li)
+ return DR_LENGTH;
+
+ if (readfnx (fd, (char *) &t -> t_code, sizeof t -> t_code)
+ != sizeof t -> t_code)
+ return DR_LENGTH;
+
+ return OK;
+}
+
+
+static int readfnx (fd, buffer, n)
+int fd,
+ n;
+char *buffer;
+{
+ register int i;
+ static int cc;
+ static char *bp;
+
+ if (fd == NOTOK) {
+ bp = buffer, cc = n;
+
+ return OK;
+ }
+
+ if ((i = min (cc, n)) > 0) {
+ bcopy (bp, buffer, n);
+ bp += i, cc -= i;
+ }
+
+ return i;
+}
+
+/* \f */
+
+static int putfnx (tb, t, cp, n)
+struct tsapblk *tb;
+register struct tsapkt *t;
+char *cp;
+int n;
+{
+ register int cc;
+ register struct udvec *uv;
+
+ cc = sizeof t -> t_li;
+ if (writefnx (tb, (char *) &t -> t_li, cc) != cc)
+ return NOTOK;
+
+ if (writefnx (tb, (char *) &t -> t_code, sizeof t -> t_code)
+ != sizeof t -> t_code)
+ return NOTOK;
+ cc += sizeof t -> t_code;
+
+ if (writefnx (tb, cp, n) != n)
+ return NOTOK;
+ cc += n;
+
+ if (t -> t_vdata
+ && writefnx (tb, t -> t_vdata, t -> t_vlen) != t -> t_vlen)
+ return NOTOK;
+ cc += t -> t_vlen;
+
+ for (uv = t -> t_udvec; uv -> uv_base; uv++) {
+ if (writefnx (tb, uv -> uv_base, uv -> uv_len) != uv -> uv_len)
+ return NOTOK;
+ cc += uv -> uv_len;
+ }
+
+ return cc;
+}
+
+/* \f */
+
+static int writefnx (tb, buffer, n)
+struct tsapblk *tb;
+int n;
+char *buffer;
+{
+ static int cc;
+ static char *bp;
+
+ if (tb) {
+ if (buffer == NULLCP)
+ return cc;
+ bp = buffer, cc = 0;
+
+ return OK;
+ }
+
+ bcopy (buffer, bp, n);
+ bp += n, cc += n;
+
+ return n;
+}
--- /dev/null
+/* text2tpkt.c - test utilities for use with TPDU packets */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/text2tpkt.c,v 7.3 91/02/22 09:47:12 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/text2tpkt.c,v 7.3 91/02/22 09:47:12 mrose Interim $
+ *
+ *
+ * $Log: text2tpkt.c,v $
+ * Revision 7.3 91/02/22 09:47:12 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/11/21 11:31:26 mrose
+ * sun
+ *
+ * Revision 7.1 90/10/17 11:58:57 mrose
+ * sync
+ *
+ * Revision 7.0 89/11/23 22:30:31 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "tpkt.h"
+#include "logger.h"
+
+/* \f */
+
+char *fgets (), *calloc ();
+
+/* \f */
+
+#define TPKT_TYPE(e) (void) ll_printf (lp, "%sCODE/ %s\n", rw, e)
+
+
+void tpkt2text (lp, t, isread)
+register LLog *lp;
+register struct tsapkt *t;
+int isread;
+{
+ char *rw = isread ? "<--- " : "---> ";
+ register struct udvec *uv;
+
+ LLOG (lp, LLOG_ALL,
+ ("dump of TPKT 0x%x, errno=0x%x version=0x%x length=%d",
+ t, t -> t_errno, t -> t_vrsn, t -> t_length));
+ (void) ll_printf (lp, "%s(\n", rw);
+
+ (void) ll_printf (lp, "%sLI/ %d\n", rw, t -> t_li);
+ if (t -> t_vdata)
+ type_data (lp, "VARIABLE", rw, t -> t_vlen, t -> t_vdata);
+
+ switch (TPDU_CODE (t)) {
+ case TPDU_CR:
+ case TPDU_CC:
+ TPKT_TYPE (TPDU_CODE (t) == TPDU_CR ? "CONNECT REQUEST"
+ : "CONNECT CONFIRM");
+ (void) ll_printf (lp, "%sDSTREF/ 0x%x\n", rw, ntohs (t -> t_cr.cr_dstref));
+ (void) ll_printf (lp, "%sSRCREF/ 0x%x\n", rw, ntohs (t -> t_cr.cr_srcref));
+ (void) ll_printf (lp, "%sCLASS/ 0x%x\n", rw, t -> t_cr.cr_class);
+ if (t -> t_calledlen > 0)
+ type_id (lp, "CALLED", rw, t -> t_called, t -> t_calledlen);
+ if (t -> t_callinglen > 0)
+ type_id (lp, "CALLING", rw, t -> t_calling, t -> t_callinglen);
+ if (t -> t_tpdusize)
+ (void) ll_printf (lp, "%sTPDUSIZE/ %d\n", rw, 1 << t -> t_tpdusize);
+ (void) ll_printf (lp, "%sOPTIONS/ 0x%x\n", rw, t -> t_options);
+ if (t -> t_alternate)
+ (void) ll_printf (lp, "%sALTERNATES/ 0x%x\n", rw, t -> t_alternate);
+ break;
+
+ case TPDU_DR:
+ TPKT_TYPE ("DISCONNECT REQUEST");
+ (void) ll_printf (lp, "%sDSTREF/ 0x%x\n", rw, ntohs (t -> t_dr.dr_dstref));
+ (void) ll_printf (lp, "%sSRCREF/ 0x%x\n", rw, ntohs (t -> t_dr.dr_srcref));
+ (void) ll_printf (lp, "%sREASON/ 0x%x: %s\n", rw, t -> t_dr.dr_reason,
+ TErrString ((int) t -> t_dr.dr_reason));
+ break;
+
+ case TPDU_DT:
+ case TPDU_ED:
+ TPKT_TYPE (TPDU_CODE (t) == TPDU_DT ? "DATA TRANSFER"
+ : "EXPEDITED DATA TRANSFER");
+ (void) ll_printf (lp, "%sSEQUENCE/ %s0x%x\n", rw,
+ t -> t_dt.dt_nr & DT_EOT ? "<EOT>+" : "",
+ t -> t_dt.dt_nr & ~DT_EOT);
+ break;
+
+ case TPDU_ER:
+ TPKT_TYPE ("ERROR");
+ (void) ll_printf (lp, "%sDSTREF/ 0x%x\n", rw, ntohs (t -> t_er.er_dstref));
+ (void) ll_printf (lp, "%sREJECT/ 0x%x\n", rw, t -> t_er.er_reject);
+ break;
+
+ default:
+ (void) ll_printf (lp, "%sCODE/ 0x%x\n", rw, TPDU_CODE (t));
+ break;
+ }
+
+ if (t -> t_qbuf && t -> t_qbuf -> qb_data)
+ type_data (lp, "QBUF", rw, t -> t_qbuf -> qb_len,
+ t -> t_qbuf -> qb_data);
+ for (uv = t -> t_udvec; uv -> uv_base; uv++)
+ type_data (lp, "UVEC", rw, uv -> uv_len, uv -> uv_base);
+ (void) ll_printf (lp, "%s)\n", rw);
+
+ (void) ll_sync (lp);
+}
+
+/* \f */
+
+static type_id (lp, type, rw, selector, len)
+LLog *lp;
+char *type,
+ *rw;
+char *selector;
+int len;
+{
+ char buffer[BUFSIZ];
+
+ buffer[explode (buffer, (u_char *) selector, len)] = NULL;
+
+ (void) ll_printf (lp, "%s%s/ %d/\"%s\"\n", rw, type, len, buffer);
+}
+
+
+static type_data (lp, type, rw, len, data)
+LLog *lp;
+char *type,
+ *rw,
+ *data;
+int len;
+{
+ char buffer[BUFSIZ];
+ char *cp;
+ int i;
+
+ (void) ll_printf (lp, "%s%s DATA/ %d ", rw, type, len);
+ for (cp = data; len > 0; ) {
+ i = (sizeof buffer - 1) / 2;
+ if (len < i)
+ i = len;
+ buffer[explode (buffer, (u_char *) cp, i)] = NULL;
+ (void) ll_printf (lp, "%s", buffer);
+ cp += i;
+ len -= i;
+ }
+ (void) ll_printf (lp, "\n");
+}
+
+/* \f */
+
+void text2tpkt (t)
+register struct tsapkt *t;
+{
+ char buffer[80], /* Working input buffer */
+ *bptr; /* Pointer to our buffer */
+ int data;
+
+ printf("Packet Length [%d]: ", data = t -> t_length);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%d", &data);
+ t -> t_length = data;
+ printf("Packet Version [%02x]: ", data = t -> t_vrsn);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_vrsn = data;
+ printf("Packet Errno [%02x]: ", data = t -> t_errno);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%d", &data);
+ t -> t_errno = data;
+ printf("TPDU Code [%02x]: ", data = t -> t_code);
+ (void) fflush(stdout); bptr = fgets(buffer, sizeof buffer, stdin);
+ while (isspace((u_char) *bptr) && (*bptr != '\0')) ++bptr;
+ if (toupper(*bptr) == 'C') {
+ if (toupper(*(bptr + 1)) == 'R') {
+ data = 0xE0;
+ } else if (toupper(*(bptr + 1)) == 'C') {
+ data = 0xD0;
+ } else (void) sscanf(buffer, "%x", &data);
+ } else if (toupper(*bptr) == 'D') {
+ if (toupper(*(bptr + 1)) == 'R') {
+ data = 0x80;
+ } else if (toupper(*(bptr + 1)) == 'T') {
+ data = 0xF0;
+ } else (void) sscanf(buffer, "%x", &data);
+ } else (void) sscanf(buffer, "%x", &data);
+ t -> t_code = data;
+ switch (TPDU_CODE(t)) {
+ case TPDU_CR:
+ case TPDU_CC:
+ t -> t_li = TPDU_MINLEN(t, CR);
+ printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_li = data;
+ printf("Destination Reference [%04x]: ",
+ data = ntohs (t -> t_cr.cr_dstref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_dstref = htons((u_short)data);
+ printf("Source Reference [%04x]: ", data = ntohs(t -> t_cr.cr_srcref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_srcref = htons ((u_short)data);
+ printf("Class/Options [%02x]: ", data = t-> t_cr.cr_class);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_class = data;
+ printf("TPDU size [%02x]: ",
+ data = t -> t_cr.cr_tpdusize);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_tpdusize = data;
+ printf("Real Options [%02x]: ",data = ntohs(t -> t_cr.cr_options));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_options = htons((u_short)data);
+ printf("Alternate classes [%02x]: ",
+ data = t -> t_cr.cr_alternate);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_alternate = data;
+ break;
+ case TPDU_DR:
+ t -> t_li = TPDU_MINLEN(t, DR);
+ printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_li = data;
+ printf("Destination Reference [%04x]: ",
+ data = ntohs(t -> t_dr.dr_dstref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_dr.dr_dstref = htons((u_short)data);
+ printf("Source Reference [%04x]: ", data = ntohs(t -> t_dr.dr_srcref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_dr.dr_srcref = htons((u_short)data);
+ printf("Disconnect Reason [%02x]: ", data = t-> t_dr.dr_reason);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_dr.dr_reason = data;
+ break;
+ case TPDU_DT:
+ case TPDU_ED:
+ t -> t_li = TPDU_MINLEN(t, DT);
+ printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_li = data;
+ printf("EOT/Sequence [%04x]: ", data = t -> t_dt.dt_nr);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_dt.dt_nr = data;
+ break;
+ case TPDU_ER:
+ t -> t_li = TPDU_MINLEN(t, ER);
+ printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_li = data;
+ printf("Destination Reference [%04x]: ",
+ data = ntohs(t -> t_er.er_dstref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_er.er_dstref = htons((u_short)data);
+ printf("Reject Cause [%02x]: ", data = t-> t_er.er_reject);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_er.er_reject = data;
+ break;
+ default:
+ t -> t_li = TPDU_MINLEN(t, CR);
+ printf("TPDU Fixed Length (LI) [%02x]: ", data = t -> t_li);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_li = data;
+ printf("Octets 3-4 [%04x]: ",
+ data = ntohs(t -> t_cr.cr_dstref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_dstref = htons((u_short)data);
+ printf("Octets 5-6 [%04x]: ",
+ data = ntohs(t -> t_cr.cr_srcref));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_srcref = htons((u_short)data);
+ printf("Octet 7 [%02x]: ", data = t-> t_cr.cr_class);
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%x", &data);
+ t -> t_cr.cr_class = data;
+ break;
+ }
+#ifdef notdef /* Dwight can fix this... */
+ printf("Calling TSAP ID [%d]: ",
+ ntohs (t -> t_calling));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%d", &data);
+ t -> t_calling = htons((u_short)data);
+ printf("Called TSAP ID [%d]: ",
+ ntohs (t -> t_called));
+ (void) fflush(stdout); (void) fgets(buffer, sizeof buffer, stdin);
+ (void) sscanf(buffer, "%d", &data);
+ t -> t_called = htons((u_short)data);
+#endif
+}
--- /dev/null
+/* ts2bridge.c - TPM: X.25 interface via bridge */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2bridge.c,v 7.5 91/02/22 09:47:16 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/ts2bridge.c,v 7.5 91/02/22 09:47:16 mrose Interim $
+ *
+ * Contributed by Julian Onions, Nottingham University in the UK
+ *
+ *
+ * $Log: ts2bridge.c,v $
+ * Revision 7.5 91/02/22 09:47:16 mrose
+ * Interim 6.8
+ *
+ * Revision 7.4 91/01/14 13:34:21 mrose
+ * loader
+ *
+ * Revision 7.3 90/07/09 14:51:11 mrose
+ * sync
+ *
+ * Revision 7.2 90/03/23 17:31:14 mrose
+ * 8
+ *
+ * Revision 7.1 89/12/07 01:07:34 mrose
+ * queued writes
+ *
+ * Revision 7.0 89/11/23 22:30:35 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "tpkt.h"
+#ifdef BRIDGE_X25
+#include <sys/uio.h>
+#include <sys/ioctl.h>
+#include "tailor.h"
+
+/*
+ * This could be anything up to the size TCP encapsualtion howver, to
+ * interwork with the X.25 it should be the same as X.25's MAXNSDU.
+ * This define is clearly a hack - but including x25.h messes things up more!
+ */
+#define MAXNSDU (1024)
+
+extern int errno;
+
+/* \f N-CONNECT.REQUEST */
+/* ARGSUSED */
+int bridgeopen (tb, local, remote, td, async)
+register struct tsapblk *tb;
+struct NSAPaddr *local,
+ *remote;
+struct TSAPdisconnect *td;
+{
+ register int fd;
+
+ if ((fd = start_bridge_client (local)) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "socket", "unable to start");
+
+ tb -> tb_fd = fd;
+ (void) BTService (tb);
+
+ if (join_bridge_server (fd, remote) == NOTOK) {
+ (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+ (void) close_bridge_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+ return DONE;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int bridgeretry (tb, td)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+ int fd = tb -> tb_fd;
+ fd_set mask;
+
+ FD_ZERO (&mask);
+ FD_SET (fd, &mask);
+
+ if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
+ return OK;
+
+ return DONE;
+}
+
+/* \f init for read from network/write to network */
+
+#define bridgeinit tcpinit
+#define bridgeread read
+int close_bridge_socket ();
+#define select_bridge_socket selsocket
+
+int tcpinit ();
+int tcpwrite ();
+int selsocket ();
+int read ();
+
+/* \f */
+
+/* ARGSUSED */
+
+char *bridgesave (fd, dte1, l1, dte2, l2, td)
+int fd;
+char *dte1;
+int l1;
+char *dte2;
+int l2;
+struct TSAPdisconnect *td;
+{
+ static char buffer[BUFSIZ];
+
+ (void) sprintf (buffer, "%c%d %*s %*s",
+ NT_BRG, fd, l1, dte1, l2, dte2);
+ return buffer;
+}
+
+
+int bridgerestore (tb, buffer, td)
+register struct tsapblk *tb;
+char *buffer;
+struct TSAPdisconnect *td;
+{
+ int fd;
+ char dte1[NSAP_DTELEN + 1],
+ dte2[NSAP_DTELEN + 1];
+ register struct NSAPaddr *na;
+ register struct tsapADDR *ta;
+
+ if (sscanf (buffer, "%d %s %s", &fd, dte1, dte2) != 3 || fd < 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "bad initialization vector \"%s\"", buffer);
+
+ ta = &tb -> tb_initiating;
+ ta -> ta_present = 1;
+ na = &ta -> ta_addr;
+ na -> na_stack = NA_BRG;
+ na -> na_community = ts_comm_x25_default;
+ bcopy(dte1, na -> na_dte, strlen(dte1));
+ na -> na_dtelen = strlen (na -> na_dte);
+
+ tb -> tb_fd = fd;
+ (void) BTService (tb);
+
+ ta = &tb -> tb_responding;
+ ta -> ta_present = 1;
+ na = &ta -> ta_addr;
+ na -> na_stack = NA_BRG;
+ na -> na_community = ts_comm_x25_default;
+ bcopy(dte1, na -> na_dte, strlen(dte2));
+ na -> na_dtelen = strlen (na -> na_dte);
+
+ return OK;
+}
+
+/* \f */
+
+int BTService (tb)
+register struct tsapblk *tb;
+{
+ tb -> tb_flags |= TB_BRG;
+
+ tb -> tb_tsdusize = MAXNSDU - (tb -> tb_tpduslop = DT_MAGIC);
+
+ tb -> tb_retryfnx = bridgeretry;
+
+ tb -> tb_initfnx = bridgeinit;
+ tb -> tb_readfnx = bridgeread;
+ tb -> tb_writefnx = tp0write;
+ tb -> tb_closefnx = close_bridge_socket;
+ tb -> tb_selectfnx = select_bridge_socket;
+
+ tp0init (tb);
+}
+#else
+int _ts2bridge_stub () {};
+#endif
--- /dev/null
+/* ts2tcp.c - TPM: TCP interface */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.8 91/02/22 09:47:23 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/ts2tcp.c,v 7.8 91/02/22 09:47:23 mrose Interim $
+ *
+ *
+ * $Log: ts2tcp.c,v $
+ * Revision 7.8 91/02/22 09:47:23 mrose
+ * Interim 6.8
+ *
+ * Revision 7.7 90/12/11 10:51:46 mrose
+ * lock-and-load
+ *
+ * Revision 7.6 90/10/16 16:24:17 mrose
+ * foo
+ *
+ * Revision 7.5 90/07/09 14:51:21 mrose
+ * sync
+ *
+ * Revision 7.4 90/03/23 17:31:28 mrose
+ * 8
+ *
+ * Revision 7.3 90/02/19 13:07:26 mrose
+ * update
+ *
+ * Revision 7.2 89/12/08 09:41:39 mrose
+ * touch-up
+ *
+ * Revision 7.1 89/12/07 01:07:36 mrose
+ * queued writes
+ *
+ * Revision 7.0 89/11/23 22:30:40 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+#ifdef TCP
+#include "internet.h"
+#include <errno.h>
+#ifdef BSD42
+#include <sys/ioctl.h>
+#endif
+#ifdef SYS5
+#include <fcntl.h>
+#endif
+
+
+#define MAX1006 2048 /* could be as high as TPKT_MAXLEN */
+
+/* \f DATA */
+
+#if defined(FIONBIO) || defined(O_NDELAY)
+#define NODELAY
+#endif
+
+#ifdef NODELAY
+static fd_set inprogress;
+static struct sockaddr_in *peers = NULL;
+#endif
+
+
+extern int errno;
+
+/* \f N-CONNECT.REQUEST */
+
+int tcpopen (tb, local, remote, td, async)
+register struct tsapblk *tb;
+struct NSAPaddr *local,
+ *remote;
+struct TSAPdisconnect *td;
+int async;
+{
+ int fd;
+#ifdef FIONBIO
+ int onoff;
+#endif
+ struct sockaddr_in lo_socket,
+ in_socket;
+ register struct sockaddr_in *lsock = &lo_socket,
+ *isock = &in_socket;
+ register struct hostent *hp;
+ register struct servent *sp;
+
+#ifndef NODELAY
+ if (async)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "asynchronous not supported");
+#endif
+
+ bzero ((char *) isock, sizeof *isock);
+
+ if (remote -> na_port == 0) {
+ if ((sp = getservbyname ("tsap", "tcp")) == NULL)
+ sp = getservbyname ("iso-tsap", "tcp");
+ isock -> sin_port = sp ? sp -> s_port : htons ((u_short) 102);
+ }
+ else
+ isock -> sin_port = remote -> na_port;
+
+ if ((hp = gethostbystring (remote -> na_domain)) == NULL)
+ return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
+ remote -> na_domain);
+#ifdef notanymore
+ (void) strncpy (remote -> na_domain, hp -> h_name,
+ sizeof remote -> na_domain);
+#endif
+
+ isock -> sin_family = hp -> h_addrtype;
+ inaddr_copy (hp, isock);
+
+#ifndef notanymore
+ (void) strcpy (remote -> na_domain, inet_ntoa (isock -> sin_addr));
+#endif
+
+ if (local && local -> na_domain[0]) {
+ bzero ((char *) lsock, sizeof *lsock);
+
+ if ((hp = gethostbystring (local -> na_domain)) == NULL)
+ return tsaplose (td, DR_ADDRESS, NULLCP, "%s: unknown host",
+ local -> na_domain);
+
+ if ((lsock -> sin_family = hp -> h_addrtype) != isock -> sin_family)
+ return tsaplose (td, DR_ADDRESS, NULLCP,
+ "address family mismatch");
+
+ inaddr_copy (hp, lsock);
+ }
+ else
+ lsock = NULL;
+
+ if ((fd = start_tcp_client (lsock, 0)) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "socket", "unable to start");
+
+#ifdef FIONBIO
+ if (async)
+ (void) ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff));
+#else
+#ifdef O_NDELAY
+ if (async)
+ (void) fcntl (fd, F_SETFL, O_NDELAY);
+#endif
+#endif
+ tb -> tb_fd = fd;
+ (void) TTService (tb);
+
+ if (join_tcp_server (fd, isock) == NOTOK) {
+#ifdef NODELAY
+ if (async)
+ switch (errno) {
+ case EINPROGRESS:
+ if (peers == NULL) {
+ peers = (struct sockaddr_in *)
+ calloc ((unsigned) getdtablesize (),
+ sizeof *peers);
+ if (peers == NULL) {
+ (void) tsaplose (td, DR_CONGEST, NULLCP,
+ "out of memory");
+ (void) close_tcp_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+
+ FD_ZERO (&inprogress);
+ }
+ FD_SET (fd, &inprogress);
+ peers[fd] = *isock;/* struct copy */
+ return OK;
+
+ case EISCONN:
+ goto done;
+
+ default:
+ break;
+ }
+#endif
+
+ (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+ (void) close_tcp_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+#ifdef NODELAY
+done: ;
+#endif
+
+#ifdef FIONBIO
+ if (async)
+ (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
+#else
+#ifdef O_NDELAY
+ if (async)
+ (void) fcntl (fd, F_SETFL, 0x00);
+#endif
+#endif
+
+ return DONE;
+}
+
+/* \f */
+
+#ifndef NODELAY
+/* ARGSUSED */
+#endif
+
+static int tcpretry (tb, td)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+#ifdef NODELAY
+#ifdef FIONBIO
+ int onoff;
+#endif
+ int fd = tb -> tb_fd;
+ fd_set mask;
+ struct sockaddr_in *isock = &peers[fd];
+
+ FD_ZERO (&mask);
+ FD_SET (fd, &mask);
+ if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
+ return OK;
+
+ if (!FD_ISSET (fd, &inprogress))
+ return DONE;
+
+ isock = &peers[fd];
+ if (join_tcp_server (fd, isock) == NOTOK) {
+ switch (errno) {
+ case EINPROGRESS:
+ return OK;
+
+ case EISCONN:
+ goto done;
+
+ case EINVAL: /* UNIX bug: could be any socket errno, e.g.,
+ ETIMEDOUT */
+ errno = ECONNREFUSED;
+ /* and fall */
+ default:
+ break;
+ }
+
+ (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+ FD_CLR (fd, &inprogress);
+ (void) close_tcp_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+done: ;
+
+#ifdef FIONBIO
+ (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
+#else
+#ifdef O_NDELAY
+ (void) fcntl (fd, F_SETFL, 0x00);
+#endif
+#endif
+
+ FD_CLR (fd, &inprogress);
+
+ return DONE;
+#else
+ return tsaplose (td, DR_OPERATION, NULLCP, "connection not in progress");
+#endif
+}
+
+/* \f init for read from network */
+
+#ifndef BRIDGE_X25
+static
+#endif
+int tcpinit (fd, t)
+int fd;
+register struct tsapkt *t;
+{
+ register int cc,
+ i;
+ register char *bp;
+
+ for (bp = (char *) &t -> t_pkthdr, i = TPKT_HDRLEN (t);
+ i > 0;
+ bp += cc, i -= cc)
+ switch (cc = read_tcp_socket (fd, bp, i)) {
+ case NOTOK:
+ case OK:
+ return DR_NETWORK;
+
+ default:
+ break;
+ }
+
+ if (t -> t_vrsn != TPKT_VRSN)
+ return DR_PROTOCOL;
+
+ if ((t -> t_length = ntohs (t -> t_length)) < TPKT_HDRLEN (t))
+ return DR_LENGTH;
+
+ return OK;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+char *tcpsave (fd, cp1, cp2, td)
+int fd;
+char *cp1,
+ *cp2;
+struct TSAPdisconnect *td;
+{
+ static char buffer[BUFSIZ];
+
+ (void) sprintf (buffer, "%c%d %s %s", NT_TCP, fd, cp1, cp2);
+
+ return buffer;
+}
+
+/* \f */
+
+int tcprestore (tb, buffer, td)
+register struct tsapblk *tb;
+char *buffer;
+struct TSAPdisconnect *td;
+{
+ int fd;
+ register char *cp;
+ char domain1[NSAP_DOMAINLEN + 1 + 5 + 1],
+ domain2[NSAP_DOMAINLEN + 1 + 5 + 1];
+ register struct NSAPaddr *na;
+ register struct tsapADDR *ta;
+
+ ta = &tb -> tb_initiating;
+ ta -> ta_present = 1;
+ na = &ta -> ta_addr;
+ na -> na_stack = NA_TCP;
+ na -> na_community = ts_comm_tcp_default;
+
+ if (sscanf (buffer, "%d %s %s", &fd, domain1, domain2) != 3 || fd < 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "bad initialization vector \"%s\"", buffer);
+
+ if (cp = index (domain1, '+')) {
+ *cp++ = NULL;
+ na -> na_port = htons ((u_short) atoi (cp));
+ }
+ (void) strncpy (na -> na_domain, domain1, sizeof na -> na_domain);
+
+ tb -> tb_fd = fd;
+ (void) TTService (tb);
+
+ ta = &tb -> tb_responding;
+ ta -> ta_present = 1;
+ na = &ta -> ta_addr;
+ na -> na_stack = NA_TCP;
+ na -> na_community = ts_comm_tcp_default;
+
+ if (cp = index (domain2, '+')) {
+ *cp++ = NULL;
+ na -> na_port = htons ((u_short) atoi (cp));
+ }
+ (void) strncpy (na -> na_domain, domain2, sizeof na -> na_domain);
+
+ return OK;
+}
+
+/* \f */
+
+int TTService (tb)
+register struct tsapblk *tb;
+{
+ struct tsapkt *t;
+
+ tb -> tb_flags |= TB_TCP;
+
+ tb -> tb_tsdusize = MAX1006
+ - (tb -> tb_tpduslop = sizeof t -> t_pkthdr + DT_MAGIC);
+
+ tb -> tb_retryfnx = tcpretry;
+
+ tb -> tb_initfnx = tcpinit;
+ tb -> tb_readfnx = read_tcp_socket;
+ tb -> tb_writefnx = tp0write;
+ tb -> tb_closefnx = close_tcp_socket;
+ tb -> tb_selectfnx = select_tcp_socket;
+
+ tp0init (tb);
+}
+#endif
--- /dev/null
+/* ts2x25.c - TPM: X.25 interface */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/ts2x25.c,v 7.5 91/02/22 09:47:24 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/ts2x25.c,v 7.5 91/02/22 09:47:24 mrose Interim $
+ *
+ *
+ * $Log: ts2x25.c,v $
+ * Revision 7.5 91/02/22 09:47:24 mrose
+ * Interim 6.8
+ *
+ * Revision 7.4 91/01/14 13:34:39 mrose
+ * loader
+ *
+ * Revision 7.3 90/07/09 14:51:23 mrose
+ * sync
+ *
+ * Revision 7.2 90/03/23 17:31:30 mrose
+ * 8
+ *
+ * Revision 7.1 89/12/07 01:07:39 mrose
+ * queued writes
+ *
+ * Revision 7.0 89/11/23 22:30:41 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+#ifdef X25
+#include "x25.h"
+#include <sys/ioctl.h>
+
+static fd_set inprogress;
+static struct NSAPaddr **peers = NULL;
+
+extern int errno;
+
+/* \f N-CONNECT.REQUEST */
+
+int x25open (tb, local, remote, td, async)
+register struct tsapblk *tb;
+struct NSAPaddr *local,
+ *remote;
+struct TSAPdisconnect *td;
+{
+ register int fd;
+ int onoff;
+
+ /*
+ * start_x25_client does nothing with its arguments in the CAMTEC
+ * case but there's less #ifdef code this way so...
+ */
+ if ((fd = start_x25_client (local)) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "socket", "unable to start");
+
+ if (async) {
+ if (ioctl (fd, FIONBIO, (onoff = 1, (char *) &onoff)) < 0) {
+ (void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO");
+ (void) close_x25_socket (fd);
+ return NOTOK;
+ }
+ }
+ tb -> tb_fd = fd;
+ (void) XTService (tb);
+
+ if (join_x25_server (fd, remote) == NOTOK) {
+ if (async)
+ switch (errno) {
+ case EINPROGRESS:
+ if (peers == NULL) {
+ peers = (struct NSAPaddr **)
+ calloc ((unsigned) getdtablesize (),
+ sizeof *peers);
+ if (peers == NULL) {
+ (void) tsaplose (td, DR_CONGEST, NULLCP,
+ "out of memory");
+ (void) close_x25_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+
+ FD_ZERO (&inprogress);
+ }
+ if (peers[fd] == NULL
+ && (peers[fd] = (struct NSAPaddr *)
+ malloc (sizeof **peers))
+ == NULL) {
+ (void) tsaplose (td, DR_CONGEST, NULLCP,
+ "out of memory");
+ (void) close_x25_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+ *(peers[fd]) = *remote; /* struct copy */
+ FD_SET (fd, &inprogress);
+ return OK;
+
+ case EISCONN:
+ goto done;
+
+ default:
+ break;
+ }
+
+ (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+ LLOG (x25_log, LLOG_NOTICE,
+ ("connection to %s failed", na2str (remote)));
+ (void) close_x25_socket (fd);
+ return (tb -> tb_fd = NOTOK);
+ }
+done: ;
+
+ if (async)
+ if (ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff)) < 0) {
+ (void) tsaplose (td, DR_CONGEST, "ioctl", "FIONBIO");
+ (void) close_x25_socket (fd);
+ return NOTOK;
+ }
+
+ (void) XTService (tb); /* in case pktsize changed... */
+ LLOG (x25_log, LLOG_NOTICE,
+ ("connection %d to %s", fd, na2str (remote)));
+
+ return DONE;
+}
+
+/* \f */
+
+static int x25retry (tb, td)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+ int onoff;
+ int fd = tb -> tb_fd;
+ fd_set mask;
+ struct NSAPaddr *remote = peers[fd];
+
+ FD_ZERO (&mask);
+ FD_SET (fd, &mask);
+ if (xselect (fd + 1, NULLFD, &mask, NULLFD, 0) < 1)
+ return OK;
+
+ if (!FD_ISSET (fd, &inprogress))
+ return DONE;
+
+ if (join_x25_server (fd, remote) == NOTOK) {
+ switch (errno) {
+ case EINPROGRESS:
+ return OK;
+
+ case EISCONN:
+ goto done;
+
+ case EINVAL: /* UNIX bug: could be any socket errno, e.g.,
+ ETIMEDOUT */
+ errno = ECONNREFUSED;
+ /* and fall */
+ default:
+ break;
+ }
+
+ (void) tsaplose (td, DR_REFUSED, "connection", "unable to establish");
+ FD_CLR (fd, &inprogress);
+ (void) close_x25_socket (fd);
+ LLOG (x25_log, LLOG_NOTICE,
+ ("connection to %s failed", na2str (remote)));
+ return (tb -> tb_fd = NOTOK);
+ }
+done: ;
+
+ (void) ioctl (fd, FIONBIO, (onoff = 0, (char *) &onoff));
+ FD_CLR (fd, &inprogress);
+
+ (void) XTService (tb); /* in case pktsize changed... */
+ LLOG (x25_log, LLOG_NOTICE,
+ ("connection %d to %s", fd, na2str (remote)));
+
+ return DONE;
+}
+
+/* \f init for read from network */
+
+static char nsdu[MAXNSDU];
+static char *np;
+static int bl;
+
+
+static int x25init (fd, t)
+int fd;
+register struct tsapkt *t;
+{
+ register int cc;
+
+/* XXX: cc should be set to the maximum acceptable NSDU length.
+ Longer NSDUs will be truncated without notification.
+ Should be configurable (or set during N-CONNECT and remembered) */
+
+ cc = sizeof nsdu;
+
+ switch (cc = read_x25_socket (fd, nsdu, cc)) {
+ case OK: /* no data ? */
+ case NOTOK:
+#ifdef SUN_X25
+ if (compat_log -> ll_events & LLOG_EXCEPTIONS)
+ (void) log_cause_and_diag(fd);
+#endif
+ return DR_NETWORK;
+
+ default:
+ t -> t_length = cc + sizeof t -> t_pkthdr;
+ break;
+ }
+
+ if (t -> t_length < TPKT_HDRLEN (t))
+ return DR_LENGTH;
+
+ t -> t_li = nsdu[0];
+ t -> t_code = nsdu[1];
+
+ np = nsdu + 2;
+ bl = t -> t_length - TPKT_HDRLEN (t);
+
+ t -> t_vrsn = TPKT_VRSN; /* Not really needed! */
+
+ return OK;
+}
+
+
+/* ARGSUSED */
+
+static int read_nsdu_buffer (fd, buffer, cc)
+int fd;
+register char *buffer;
+register int cc;
+{
+ if (cc > bl)
+ cc = bl;
+
+ if (cc > 0) {
+ bcopy (np, buffer, cc);
+ np += cc, bl -= cc;
+ }
+
+ return cc;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+char *x25save (fd, dte1, l1, dte2, l2, td)
+int fd;
+char *dte1;
+int l1;
+char *dte2;
+int l2;
+struct TSAPdisconnect *td;
+{
+ static char buffer[BUFSIZ];
+
+ (void) sprintf (buffer, "%c%d %*s %*s",
+ NT_X25, fd, l1, dte1, l2, dte2);
+
+ return buffer;
+}
+
+
+int x25restore (tb, buffer, td)
+register struct tsapblk *tb;
+char *buffer;
+struct TSAPdisconnect *td;
+{
+ int fd;
+ char dte1[NSAP_DTELEN + 1],
+ dte2[NSAP_DTELEN + 1];
+ register struct NSAPaddr *na;
+ register struct tsapADDR *ta;
+
+ if (sscanf (buffer, "%d %s %s", &fd, dte1, dte2) != 3 || fd < 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "bad initialization vector \"%s\"", buffer);
+
+ ta = &tb -> tb_initiating;
+ ta -> ta_present = 1;
+ na = &ta -> ta_addr;
+ na -> na_stack = NA_X25;
+ na -> na_community = ts_comm_x25_default;
+ bcopy(dte1, na -> na_dte, strlen(dte1));
+ na -> na_dtelen = strlen (na -> na_dte);
+
+ tb -> tb_fd = fd;
+ (void) XTService (tb);
+
+ ta = &tb -> tb_responding;
+ ta -> ta_present = 1;
+ na = &ta -> ta_addr;
+ na -> na_stack = NA_X25;
+ na -> na_community = ts_comm_x25_default;
+ bcopy(dte2, na -> na_dte, strlen(dte2));
+ na -> na_dtelen = strlen (na -> na_dte);
+
+#ifdef SUN_X25
+ (void) set_x25_facilities (tb -> tb_fd, -1, "Negotiated");
+#endif
+
+ return OK;
+}
+
+/* \f */
+
+int XTService (tb)
+register struct tsapblk *tb;
+{
+#ifndef UBC_X25
+ int maxnsdu = MAXNSDU;
+#else
+ int maxnsdu = X25_PACKETSIZE;
+#endif
+
+ tb -> tb_flags |= TB_X25;
+
+#ifdef notyet
+ if (recvpktsize > DT_MAGIC && recvpktsize < maxnsdu)
+ maxnsdu = recvpktsize;
+ if (sendpktsize > DT_MAGIC && sendpktsize < maxnsdu)
+ maxnsdu = sendpktsize;
+#endif
+ tb -> tb_tsdusize = maxnsdu - (tb -> tb_tpduslop = DT_MAGIC);
+
+ tb -> tb_retryfnx = x25retry;
+
+ tb -> tb_initfnx = x25init;
+ tb -> tb_readfnx = read_nsdu_buffer;
+ tb -> tb_writefnx = tp0write;
+ tb -> tb_closefnx = close_x25_socket;
+ tb -> tb_selectfnx = select_x25_socket;
+
+ tp0init (tb);
+}
+#else
+int _ts2x25_stub () {};
+#endif
--- /dev/null
+/* tsaperror.c - print out TPKT error codes */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaperror.c,v 7.3 91/02/22 09:47:26 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsaperror.c,v 7.3 91/02/22 09:47:26 mrose Interim $
+ *
+ *
+ * $Log: tsaperror.c,v $
+ * Revision 7.3 91/02/22 09:47:26 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 91/01/11 07:09:22 mrose
+ * jpo
+ *
+ * Revision 7.1 90/11/21 11:31:34 mrose
+ * sun
+ *
+ * Revision 7.0 89/11/23 22:30:43 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "tsap.h"
+#include "tp4.h"
+#ifdef SUNLINK_7_0
+#include <netosi/osi_layer.h>
+#include <netosi/cons_impl.h>
+#endif
+
+/* \f */
+
+static char *disc_err0[] = {
+ "Reason not specified",
+ "Congestion at TSAP",
+ "Session entity not attached to TSAP",
+ "Address unknown"
+};
+
+static int disc_err0_cnt = sizeof disc_err0 / sizeof disc_err0[0];
+
+
+static char *disc_err8[] = {
+ "Normal disconnect initiated by session entity",
+ "Remote transport entity congestion at connect time",
+ "Connection negotiation failed (proposed class(es) not supported)",
+ "Duplicate source reference detected for the same pair of NSAPs",
+ "Mismatched references",
+ "Protocol error",
+ "Not used",
+ "Reference overflow",
+ "Connect request refused on this network connection",
+ "Not used",
+ "Header or parameter length invalid",
+ "Network disconnect",
+ "Invalid parameter",
+ "Invalid operation",
+ "Timer expired",
+ "Indications waiting"
+};
+
+static int disc_err8_cnt = sizeof disc_err8 / sizeof disc_err8[0];
+
+/* \f */
+
+#ifdef SUNLINK_7_0
+static char *cons_err0 =
+ "Unspecified (undefined) CONS error";
+
+/* CONS Error 224 through 255 */
+static char *cons_err1[] = {
+ "CONS provider: undefined", /* R_CP_OSI_NETWORK_SERVICE_PROBLEM */
+ "CONS provider: disconnection-transient",
+ /* R_CP_DIS_TRANS */
+ "CONS provider: disconnection-permanent",
+ /* R_CP_DIS_PERM */
+ "CONS provider: connection rejection - reason unspecified (transient)",
+ /* R_CP_CON_REJ_UNSPEC_TRANS */
+ "CONS provider: connection rejection - reason unspecified (permanent)",
+ /* R_CP_CON_REJ_UNSPEC_PERM */
+ "CONS provider: connection rejection - QOS not available (transient)",
+ /* R_CP_CON_REJ_NO_QOS_TRANS */
+ "CONS provider: connection rejection - QOS not available (permanent)",
+ /* R_CP_CON_REJ_NO_QOS_PERM */
+ "CONS provider: connection rejection - NSAP unreachable (transient)",
+ /* R_CP_CON_REJ_NSAP_UNREACH_TRANS */
+ "CONS provider: connection rejection - NSAP unreachable (permanent)",
+ /* R_CP_CON_REJ_NSAP_UNREACH_PERM */
+ "CONS provider: RESET - reason unspecified",
+ /* R_CP_RESET_UNSPEC */
+ "CONS provider: RESET - congestion",
+ /* R_CP_RESET_CONGESTION */
+ "CONS provider: connection rejection - NSAP address unknown (permanent)",
+ /* R_CP_CON_REJ_NSAP_UNKNOWN_PERM */
+ "CONS provider: 236",
+ /* R_CP_X25_236 */
+ "CONS provider: 237",
+ /* R_CP_X25_237 */
+ "CONS provider: 238",
+ /* R_CP_X25_238 */
+ "CONS provider: 239",
+ /* R_CP_X25_239 */
+ "CONS user: undefined",
+ /* R_CU_HIGHER_LEVEL_INITIATED = 240 */
+ "CONS user: disconnection - normal",
+ /* R_CU_DIS_NORMAL */
+ "CONS user: disconnection - abnormal",
+ /* R_CU_DIS_ABNORMAL */
+ "CONS user: 243",
+ /* R_CU_DIS_INCOMPAT */
+ "CONS user: connection rejection - transient",
+ /* R_CU_CON_REJ_UNSPEC_TRANS */
+ "CONS user: connection rejection - permanent",
+ /* R_CU_CON_REJ_UNSPEC_PERM */
+ "CONS user: connection rejection - QOS not available (transient)",
+ /* R_CU_CON_REJ_NO_QOS_TRANS */
+ "CONS user: connection rejection - QOS not available (permanent)",
+ /* R_CU_CON_REJ_NO_QOS_PERM */
+ "CONS user: connection rejection - incompatible info in NS-user-data",
+ /* R_CU_CON_REJ_INCOMPAT */
+ "CONS user: 249",
+ /* R_CU_CON_UNREC_PROTO */
+ "CONS user: RESET - user resynchronization",
+ /* R_CU_RESET_USER_RESYNCH */
+ "CONS user: 251",
+ /* R_CU_X25_251 */
+ "CONS user: 252",
+ /* R_CU_X25_252 */
+ "CONS user: 253",
+ /* R_CU_X25_253 */
+ "CONS user: 254",
+ /* R_CU_X25_254 */
+ "CONS user: 255",
+ /* R_CU_X25_255 */
+};
+#endif
+
+/* \f */
+
+char *TErrString(code)
+register int code;
+{
+ register int fcode;
+ static char buffer[60];
+
+#ifdef SUNLINK_7_0
+ if (code > 0xff) {
+ /* CONS error code */
+ code -= 0x100;
+ if (code == R_CONS_UNDEFINED)
+ return cons_err0;
+ if (code >= R_CP_OSI_NETWORK_SERVICE_PROBLEM &&
+ code <= R_CU_X25_255)
+ return cons_err1[code - R_CP_OSI_NETWORK_SERVICE_PROBLEM];
+
+ (void) sprintf (buffer, "unknown CONS error code 0x%x", code);
+ return buffer;
+ }
+#endif
+
+ code &= 0xff;
+ if (code & DR_BASE) {
+ if ((fcode = code & ~DR_BASE) < disc_err8_cnt)
+ return disc_err8[fcode];
+ }
+ else
+ if (code < disc_err0_cnt)
+ return disc_err0[code];
+
+ (void) sprintf (buffer, "unknown error code 0x%x", code);
+ return buffer;
+}
--- /dev/null
+/* tsapinitiate.c - TPM: initiator */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.4 91/02/22 09:47:27 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsapinitiate.c,v 7.4 91/02/22 09:47:27 mrose Interim $
+ *
+ *
+ * $Log: tsapinitiate.c,v $
+ * Revision 7.4 91/02/22 09:47:27 mrose
+ * Interim 6.8
+ *
+ * Revision 7.3 90/08/08 14:03:13 mrose
+ * stuff
+ *
+ * Revision 7.2 90/07/09 14:51:26 mrose
+ * sync
+ *
+ * Revision 7.1 90/03/23 17:31:34 mrose
+ * 8
+ *
+ * Revision 7.0 89/11/23 22:30:44 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+#include "mpkt.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+
+static struct nsapent {
+ int ns_type;
+ int ns_stack;
+
+ IFP ns_open;
+} nsaps[] = {
+#ifdef TCP
+ NA_TCP, TS_TCP, tcpopen,
+#endif
+#ifdef X25
+ NA_X25, TS_X25, x25open,
+#endif
+#ifdef BRIDGE_X25
+ NA_BRG, TS_BRG, bridgeopen,
+#endif
+#ifdef TP4
+ NA_NSAP, TS_TP4, tp4open,
+#endif
+
+ NOTOK, TS_NONE, NULL
+};
+
+
+struct TSAPaddr *newtaddr (), *ta2norm (), *maketsbaddr ();
+
+/* \f T-(ASYN-)CONNECT.REQUEST */
+
+int TAsynConnRequest (calling, called, expedited, data, cc, qos,
+ tc, td, async)
+struct TSAPaddr *calling,
+ *called;
+int expedited,
+ cc,
+ async;
+char *data;
+struct QOStype *qos;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+ register int n;
+ SBV smask;
+ int result;
+
+ isodetailor (NULLCP, 0);
+
+#ifdef notdef
+ missingP (calling);
+#endif
+ missingP (called);
+ if ((n = called -> ta_naddr) <= 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "no NSAP addresses in called parameter");
+ if (n > NTADDR)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "too many NSAP addresses in called parameter");
+
+ if ((called = ta2norm (called)) == NULLTA)
+ return tsaplose (td, DR_PARAMETER, "invalid called parameter");
+ toomuchP (data, cc, TS_SIZE, "initial");
+#ifdef notdef
+ missingP (qos);
+#endif
+ missingP (td);
+
+ smask = sigioblock ();
+
+ result = TConnRequestAux (calling, called, expedited, data, cc, qos,
+ tc, td, async);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static int TConnRequestAux (calling, called, expedited, data, cc, qos,
+ tc, td, async)
+struct TSAPaddr *calling,
+ *called;
+char *data;
+int expedited,
+ cc,
+ async;
+struct QOStype *qos;
+register struct TSAPconnect *tc;
+register struct TSAPdisconnect *td;
+{
+ int result;
+ register struct tsapblk *tb;
+
+ if ((tb = newtblk ()) == NULL)
+ return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+
+ if (calling == NULLTA) {
+ static struct TSAPaddr tas;
+
+ calling = &tas;
+ bzero ((char *) calling, sizeof *calling);
+ }
+#ifdef notdef
+ if (called -> ta_selectlen > 0 && calling -> ta_selectlen == 0) {
+ calling -> ta_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff)));
+ calling -> ta_selectlen = sizeof calling -> ta_port;
+ }
+#endif
+
+ if (qos)
+ tb -> tb_qos = *qos; /* struct copy */
+
+ if ((tb -> tb_calling = (struct TSAPaddr *)
+ calloc (1, sizeof *tb -> tb_calling)) == NULL)
+ goto no_mem;
+ *tb -> tb_calling = *calling; /* struct copy */
+ bcopy (calling -> ta_selector, tb -> tb_initiating.ta_selector,
+ tb -> tb_initiating.ta_selectlen = calling -> ta_selectlen);
+
+ if ((tb -> tb_called = (struct TSAPaddr *)
+ calloc (1, sizeof *tb -> tb_called)) == NULL)
+ goto no_mem;
+ *tb -> tb_called = *called; /* struct copy */
+
+ if ((tb -> tb_cc = cc) > 0) {
+ if ((tb -> tb_data = malloc ((unsigned) cc)) == NULLCP) {
+no_mem: ;
+ (void) tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+ goto out;
+ }
+ bcopy (data, tb -> tb_data, cc);
+ }
+ tb -> tb_expedited = expedited;
+
+ if ((result = TConnAttempt (tb, td, async)) == NOTOK) {
+#ifdef MGMT
+ if (tb -> tb_manfnx)
+ (*tb -> tb_manfnx) (OPREQOUTBAD, tb);
+#endif
+ goto out;
+ }
+
+ if (async) {
+ tc -> tc_sd = tb -> tb_fd;
+ switch (result) {
+ case CONNECTING_1:
+ case CONNECTING_2:
+ return result;
+ }
+ }
+
+ if ((result = (*tb -> tb_retryPfnx) (tb, async, tc, td)) == DONE && !async)
+ result = OK;
+ return result;
+
+out: ;
+ freetblk (tb);
+
+ return NOTOK;
+}
+
+/* \f */
+
+static int TConnAttempt (tb, td, async)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+int async;
+{
+ register int n;
+ int didone,
+ l,
+ result;
+ register struct TSAPaddr *called, *calling;
+ struct TSAPaddr *realcalled;
+ register struct NSAPaddr *na, *la;
+ struct NSAPaddr *realna;
+ register struct TSAPdisconnect *te = td;
+ struct TSAPdisconnect tds;
+
+ calling = tb -> tb_calling;
+ called = tb -> tb_called;
+
+ didone = 0;
+ for (na = called -> ta_addrs, n = called -> ta_naddr - 1;
+ n >= 0;
+ na++, n--) {
+ register int *ip;
+ register char **ap;
+ register struct nsapent *ns;
+
+ realcalled = called;
+ realna = na;
+ for (ip = ts_communities; *ip; ip++)
+ if (*ip == na -> na_community)
+ break;
+ if (!*ip)
+ continue;
+ for (ip = tsb_communities, ap = tsb_addresses; *ip; ip++, ap++)
+ if (*ip == na -> na_community) {
+ if ((realcalled = maketsbaddr (*ap, na, called)) == NULLTA)
+ continue;
+ realna = realcalled -> ta_addrs;
+ break;
+ }
+
+ for (la = calling -> ta_addrs, l = calling -> ta_naddr - 1;
+ l >= 0;
+ la++, l--)
+ if (la -> na_community == na -> na_community)
+ break;
+ if (l < 0)
+ la = NULLNA;
+
+ for (ns = nsaps; ns -> ns_open; ns++)
+ if (ns -> ns_type == realna -> na_stack
+ && (ns -> ns_stack & ts_stacks))
+ break;
+ if (!ns -> ns_open)
+ continue;
+
+ didone = 1;
+ switch (ns -> ns_type) {
+ case NA_NSAP:
+ if ((result = (*ns -> ns_open) (tb, calling, la,
+ realcalled, realna,
+ te, async)) == NOTOK) {
+ te = &tds;
+ continue;
+ }
+ break;
+
+ default:
+ if ((result = (*ns -> ns_open) (tb, la, realna, te, async))
+ == NOTOK) {
+ te = &tds;
+ continue;
+ }
+ break;
+ }
+ break;
+ }
+
+ if (tb -> tb_fd == NOTOK) {
+ if (!didone)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "no supported NSAP addresses in, nor known TSBridges for, called parameter");
+
+ return NOTOK;
+ }
+
+ if (la) {
+ tb -> tb_initiating.ta_present = 1;
+ tb -> tb_initiating.ta_addr = *la; /* struct copy */
+ }
+ if (la && la != calling -> ta_addrs) {
+ struct NSAPaddr ns;
+
+ ns = calling -> ta_addrs[0]; /* struct copy */
+ calling -> ta_addrs[0] = *la; /* .. */
+ *la = ns; /* .. */
+ la = calling -> ta_addrs; /* .. */
+ }
+
+ bcopy (realcalled -> ta_selector, tb -> tb_responding.ta_selector,
+ tb -> tb_responding.ta_selectlen = realcalled -> ta_selectlen);
+ tb -> tb_responding.ta_present = 1;
+ tb -> tb_responding.ta_addr = *realna; /* struct copy */
+
+ if ((result = (*tb -> tb_connPfnx) (tb, tb -> tb_expedited, tb -> tb_data,
+ tb -> tb_cc, td)) == NOTOK)
+ return NOTOK;
+
+ if (result == OK)
+ result = CONNECTING_1;
+
+ return result;
+}
+
+/* \f T-ASYN-RETRY.REQUEST (pseudo) */
+
+int TAsynRetryRequest (sd, tc, td)
+int sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+ SBV smask;
+ int result;
+ register struct tsapblk *tb;
+ struct TSAPaddr *ta;
+
+ missingP (tc);
+ missingP (td);
+
+ smask = sigioblock ();
+
+ if ((tb = findtblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "invalid transport descriptor");
+ }
+ if (tb -> tb_flags & TB_CONN) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_OPERATION, NULLCP,
+ "transport descriptor connected");
+ }
+
+ ta = tb -> tb_called;
+
+ switch (result = (*tb -> tb_retryPfnx) (tb, 1, tc, td)) {
+ case NOTOK: /* try next nsap in list */
+ if (ta -> ta_naddr <= 1) {
+ freetblk (tb);
+ break;
+ }
+ *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1],
+ ta -> ta_naddr - 1); /* struct copy */
+
+ switch (result = TConnAttempt (tb, td, 1)) {
+ case DONE:
+ result = OK;
+ /* and fall... */
+ case CONNECTING_1:
+ case CONNECTING_2:
+ if (tb -> tb_fd != sd) {
+ (void) dup2 (tb -> tb_fd, sd);
+ (void) close (tb -> tb_fd);
+ tb -> tb_fd = sd;
+ }
+ break;
+
+ case NOTOK:
+ freetblk (tb);
+ break;
+ }
+ break;
+
+ case DONE:
+ if (tb -> tb_data) {
+ free (tb -> tb_data);
+ tb -> tb_data = NULLCP;
+ }
+ tb -> tb_cc = 0;
+ tb -> tb_expedited = 0;
+ break;
+
+ case CONNECTING_1:
+ case CONNECTING_2:
+ default:
+ break;
+ }
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f T-ASYN-NEXT.REQUEST (pseudo) */
+
+int TAsynNextRequest (sd, tc, td)
+int sd;
+struct TSAPconnect *tc;
+struct TSAPdisconnect *td;
+{
+ SBV smask;
+ int result;
+ register struct tsapblk *tb;
+ struct TSAPaddr *ta;
+
+ missingP (tc);
+ missingP (td);
+
+ smask = sigioblock ();
+
+ if ((tb = findtblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "invalid transport descriptor");
+ }
+ if (tb -> tb_flags & TB_CONN) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_OPERATION, NULLCP,
+ "transport descriptor connected");
+ }
+
+ ta = tb -> tb_called;
+
+ /* close previous connection attempt */
+ if (tb -> tb_fd != NOTOK)
+ (void) (*tb -> tb_closefnx) (tb -> tb_fd);
+ tb -> tb_fd = NOTOK;
+
+ if (ta -> ta_naddr <= 1) {
+ freetblk (tb);
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_PARAMETER, NULLCP, "no more NSAPs to try");
+ }
+ *tb -> tb_called = *newtaddr (ta, &ta -> ta_addrs[1],
+ ta -> ta_naddr - 1); /* struct copy */
+
+ switch (result = TConnAttempt (tb, td, 1)) {
+ case DONE:
+ result = OK;
+ /* and fall... */
+ case CONNECTING_1:
+ case CONNECTING_2:
+ if (tb -> tb_fd != sd) {
+ (void) dup2 (tb -> tb_fd, sd);
+ (void) close (tb -> tb_fd);
+ tb -> tb_fd = sd;
+ }
+ break;
+
+ case NOTOK:
+ freetblk (tb);
+ break;
+ }
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f */
+
+static struct TSAPaddr *newtaddr (ta, na, n)
+register struct TSAPaddr *ta;
+register struct NSAPaddr *na;
+int n;
+{
+ static struct TSAPaddr tzs;
+ register struct TSAPaddr *tz = &tzs;
+ register struct NSAPaddr *nz = tz -> ta_addrs;
+
+ bzero ((char *) tz, sizeof *tz);
+
+ if (tz -> ta_selectlen = ta -> ta_selectlen)
+ bcopy (ta -> ta_selector, tz -> ta_selector, ta -> ta_selectlen);
+ if (na)
+ for (tz -> ta_naddr = n; n > 0; n--)
+ *nz++ = *na++; /* struct copy */
+
+ return tz;
+}
+
+/* \f */
+
+struct TSAPaddr *ta2norm (ta)
+register struct TSAPaddr *ta;
+{
+ register int n,
+ *ip;
+ static struct TSAPaddr tzs;
+ register struct TSAPaddr *tz = &tzs;
+ register struct NSAPaddr *na,
+ *ca;
+
+ SLOG (addr_log, LLOG_TRACE, NULLCP,
+ ("ta2norm %s", taddr2str (ta)));
+
+ for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--)
+ if (na -> na_community == 0) {
+ SLOG (addr_log, LLOG_EXCEPTIONS, NULLCP,
+ ("ta2norm: empty subnet in NSAP address at offset %d",
+ na - ta -> ta_addrs));
+ return NULLTA;
+ }
+
+ bzero ((char *) tz, sizeof *tz);
+ bcopy (ta -> ta_selector, tz -> ta_selector,
+ tz -> ta_selectlen = ta -> ta_selectlen);
+ ca = tz -> ta_addrs;
+
+ for (ip = ts_communities; *ip; ip++)
+ for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1;
+ n >= 0;
+ na++, n--)
+ if (*ip == na -> na_community) {
+ *ca++ = *na; /* struct copy */
+ tz -> ta_naddr++;
+ }
+
+ for (na = ta -> ta_addrs, n = ta -> ta_naddr - 1; n >= 0; na++, n--) {
+ for (ip = ts_communities; *ip; ip++)
+ if (*ip == na -> na_community)
+ break;
+ if (!*ip) {
+ *ca++ = *na; /* struct copy */
+ tz -> ta_naddr++;
+ }
+ }
+
+ SLOG (addr_log, LLOG_TRACE, NULLCP,
+ ("ta2norm returns %s", taddr2str (tz)));
+
+ return tz;
+}
+
+/* \f */
+
+static struct TSAPaddr *maketsbaddr (cp, na, ta)
+char *cp;
+struct NSAPaddr *na;
+struct TSAPaddr *ta;
+{
+ static struct TSAPaddr newta;
+ register struct TSAPaddr *nta = &newta;
+ struct TSAPaddr *taz;
+ struct NSAPaddr *nna;
+
+ if ((taz = str2taddr (cp)) == NULLTA)
+ return taz;
+
+ *nta = *taz; /* struct copy */
+ if ((nna = na2norm (na)) == NULLNA)
+ return NULLTA;
+ if ((nta -> ta_selectlen = 2 + nna -> na_addrlen + ta -> ta_selectlen)
+ >= TSSIZE)
+ return NULLTA;
+ bcopy (nna -> na_address, &nta -> ta_selector[2], nna -> na_addrlen);
+ bcopy (ta -> ta_selector, &nta -> ta_selector[2 + nna -> na_addrlen],
+ ta -> ta_selectlen);
+ nta -> ta_selector[0] = nta -> ta_selector[1] = nna -> na_addrlen;
+ return nta;
+}
--- /dev/null
+/* tsaplose.c - TPM: you lose */
+
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaplose.c,v 7.2 91/02/22 09:47:36 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsaplose.c,v 7.2 91/02/22 09:47:36 mrose Interim $
+ *
+ *
+ * $Log: tsaplose.c,v $
+ * Revision 7.2 91/02/22 09:47:36 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 89/12/07 22:15:50 mrose
+ * touch-up
+ *
+ * Revision 7.0 89/11/23 22:30:51 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <varargs.h>
+#include "tpkt.h"
+#include "mpkt.h"
+#include "tailor.h"
+
+
+#ifdef LPP
+#undef MGMT
+#endif
+
+/* \f */
+
+#ifndef lint
+int tpktlose (va_alist)
+va_dcl
+{
+ int reason,
+ result;
+ register struct tsapblk *tb;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td;
+ va_list ap;
+
+ va_start (ap);
+
+ tb = va_arg (ap, struct tsapblk *);
+
+ td = va_arg (ap, struct TSAPdisconnect *);
+ if (td == NULL)
+ td = &tds;
+
+ reason = va_arg (ap, int);
+
+ result = _tsaplose (td, reason, ap);
+
+ va_end (ap);
+
+ if (td -> td_cc > 0) {
+ SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("tpktlose [%s] %*.*s", TErrString (td -> td_reason), td -> td_cc,
+ td -> td_cc, td -> td_data));
+ }
+ else
+ SLOG (tsap_log, LLOG_EXCEPTIONS, NULLCP,
+ ("tpktlose [%s]", TErrString (td -> td_reason)));
+
+#ifdef MGMT
+ if (tb -> tb_manfnx)
+ switch (reason) {
+ case DR_REMOTE:
+ case DR_CONGEST:
+ (*tb -> tb_manfnx) (CONGEST, tb);
+ break;
+
+ case DR_PROTOCOL:
+ case DR_MISMATCH:
+ (*tb -> tb_manfnx) (PROTERR, tb);
+ break;
+
+ case DR_SESSION:
+ case DR_ADDRESS:
+ case DR_CONNECT:
+ case DR_DUPLICATE:
+ case DR_OVERFLOW:
+ case DR_REFUSED:
+ (*tb -> tb_manfnx) (CONFIGBAD, tb);
+ break;
+
+ default:
+ (*tb -> tb_manfnx) (OPREQINBAD, tb);
+ }
+#endif
+
+ (*tb -> tb_losePfnx) (tb, reason, td);
+
+ return result;
+}
+#else
+/* VARARGS5 */
+
+int tpktlose (tb, td, reason, what, fmt)
+struct tsapblk *tb;
+struct TSAPdisconnect *td;
+int reason;
+char *what,
+ *fmt;
+{
+ return tpktlose (tb, td, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef lint
+int tsaplose (va_alist)
+va_dcl
+{
+ int reason,
+ result;
+ struct TSAPdisconnect *td;
+ va_list ap;
+
+ va_start (ap);
+
+ td = va_arg (ap, struct TSAPdisconnect *);
+ reason = va_arg (ap, int);
+
+ result = _tsaplose (td, reason, ap);
+
+ va_end (ap);
+
+ return result;
+
+}
+#else
+/* VARARGS4 */
+
+int tsaplose (td, reason, what, fmt)
+struct TSAPdisconnect *td;
+int reason;
+char *what,
+ *fmt;
+{
+ return tsaplose (td, reason, what, fmt);
+}
+#endif
+
+/* \f */
+
+#ifndef lint
+static int _tsaplose (td, reason, ap) /* what, fmt, args ... */
+register struct TSAPdisconnect *td;
+int reason;
+va_list ap;
+{
+ register char *bp;
+ char buffer[BUFSIZ];
+
+ if (td) {
+ bzero ((char *) td, sizeof *td);
+
+ asprintf (bp = buffer, ap);
+ bp += strlen (bp);
+
+ td -> td_reason = reason;
+ copyTSAPdata (buffer, bp - buffer, td);
+ }
+
+ return NOTOK;
+}
+#endif
--- /dev/null
+/* tsapmgmt.c - management info reporting routines */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapmgmt.c,v 7.4 91/02/22 09:47:38 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsapmgmt.c,v 7.4 91/02/22 09:47:38 mrose Interim $
+ *
+ *
+ * $Log: tsapmgmt.c,v $
+ * Revision 7.4 91/02/22 09:47:38 mrose
+ * Interim 6.8
+ *
+ * Revision 7.3 91/01/14 13:34:43 mrose
+ * loader
+ *
+ * Revision 7.2 90/06/12 02:19:52 mrose
+ * typo
+ *
+ * Revision 7.1 90/03/23 17:31:45 mrose
+ * 8
+ *
+ * Revision 7.0 89/11/23 22:30:53 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <varargs.h>
+#include "tpkt.h"
+#include "mpkt.h"
+
+
+#ifdef MGMT
+#include "internet.h"
+
+#define LOCALTHLD 128 /* local threshold for reporting (bytes) */
+
+/* \f */
+
+static long pid = OK;
+static int ManSoc;
+static struct MReport TsapInfo;
+static struct qbuf data;
+
+/* \f */
+
+/* VARARGS2 */
+
+int TManGen (va_alist)
+va_dcl
+{
+ int a,
+ result;
+ struct TSAPaddr *b;
+ unsigned int type;
+ register struct tsapblk *tb;
+ va_list ap;
+
+ va_start (ap);
+
+ type = va_arg (ap, unsigned int);
+ tb = va_arg (ap, struct tsapblk *);
+ a = 0, b = NULLTA;
+ switch (type) {
+ case USERDT:
+ case USERDR:
+ a = va_arg (ap, int);
+ break;
+
+ case STARTLISTEN:
+ case ENDLISTEN:
+ b = va_arg (ap, struct TSAPaddr *);
+ break;
+
+ default:
+ break;
+ }
+
+ result = TManGenAux (type, tb, a, b);
+
+ va_end (ap);
+
+ return result;
+}
+
+/* \f */
+
+#define SendMReport() write_udp_socket (ManSoc, &data)
+
+
+static int TManGenAux (type, tb, a, b)
+unsigned int type;
+struct tsapblk * tb;
+int a;
+struct TSAPaddr *b;
+{
+ if (pid == NOTOK)
+ return NOTOK;
+
+ if (pid == OK && ManInit () == NOTOK)
+ return (pid = NOTOK);
+
+ switch (TsapInfo.type = type) {
+ case USERDT:
+ tb -> tb_pdus++;
+ if ((tb -> tb_bytes += a) < LOCALTHLD)
+ break;
+ TsapInfo.cid = tb -> tb_fd;
+ TsapInfo.u.gp.a = tb -> tb_bytes;
+ TsapInfo.u.gp.b = tb -> tb_pdus;
+ tb -> tb_bytes = 0;
+ break;
+
+ case USERDR:
+ tb -> tb_pdur++;
+ if ((tb -> tb_byter += a) < LOCALTHLD)
+ return OK;
+ TsapInfo.cid = tb -> tb_fd;
+ TsapInfo.u.gp.a = tb -> tb_byter;
+ TsapInfo.u.gp.b = tb -> tb_pdur;
+ tb -> tb_byter = 0;
+ break;
+
+ case OPREQIN:
+ case OPREQOUT:
+ TsapInfo.cid = tb -> tb_fd;
+ bcopy (tb -> tb_responding.ta_selector,
+ TsapInfo.u.taddr.tsel,
+ TsapInfo.u.taddr.tsel_len =
+ tb -> tb_responding.ta_selectlen);
+ /* struct copy */
+ TsapInfo.u.taddr.nsap = tb -> tb_responding.ta_addr;
+ if (SendMReport () == NOTOK)
+ return NOTOK;
+
+ TsapInfo.type = SOURCEADDR;
+ bcopy (tb -> tb_initiating.ta_selector,
+ TsapInfo.u.taddr.tsel,
+ TsapInfo.u.taddr.tsel_len =
+ tb -> tb_initiating.ta_selectlen);
+ /* struct copy */
+ TsapInfo.u.taddr.nsap = tb -> tb_initiating.ta_addr;
+ break;
+
+ case DISCREQ:
+ TsapInfo.cid = tb -> tb_fd;
+ TsapInfo.u.gp.a = tb -> tb_bytes;
+ TsapInfo.u.gp.b = tb -> tb_byter;
+ TsapInfo.u.gp.c = tb -> tb_pdus;
+ TsapInfo.u.gp.d = tb -> tb_pdur;
+ break;
+
+ case PROTERR:
+ case CONGEST:
+ case CONFIGBAD:
+ case OPREQINBAD:
+ case OPREQOUTBAD:
+ TsapInfo.cid = tb -> tb_fd;
+ break;
+
+ case STARTLISTEN:
+ case ENDLISTEN:
+ bcopy (b -> ta_selector,
+ TsapInfo.u.taddr.tsel,
+ TsapInfo.u.taddr.tsel_len = b -> ta_selectlen);
+ TsapInfo.u.taddr.nsap = b -> ta_addrs[0]; /* struct copy */
+ break;
+
+ default:
+ return NOTOK;
+ }
+ return SendMReport ();
+}
+
+/* \f */
+
+static int ManInit () {
+ struct sockaddr_in sin;
+ register struct sockaddr_in *sock = &sin;
+ register struct servent *sp;
+ register struct hostent *hp;
+
+ if ((sp = getservbyname ("manager", "udp")) == NULL
+ || (hp = gethostbyname ("localhost")) == NULL)
+ return NOTOK;
+
+ bzero((char *) sock, sizeof *sock);
+ sock -> sin_family = hp -> h_addrtype;
+ inaddr_copy (hp, sock);
+ if ((ManSoc = start_udp_client (sock, 0, SO_DONTROUTE, 0)) == NOTOK)
+ return NOTOK;
+
+ sock -> sin_port = sp -> s_port;
+ if (join_udp_server (ManSoc, sock) == NOTOK)
+ return NOTOK;
+
+ TsapInfo.id = pid = getpid();
+ data.qb_data = (char *) &TsapInfo;
+ data.qb_len = sizeof TsapInfo;
+
+ return OK;
+}
+#else
+int _tsapmgmt_stub () {};
+#endif
--- /dev/null
+/* tsapmisc.c - miscellany tsap functions */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapmisc.c,v 7.3 91/02/22 09:47:39 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsapmisc.c,v 7.3 91/02/22 09:47:39 mrose Interim $
+ *
+ *
+ * $Log: tsapmisc.c,v $
+ * Revision 7.3 91/02/22 09:47:39 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/03/23 17:31:47 mrose
+ * 8
+ *
+ * Revision 7.1 90/03/06 09:34:18 mrose
+ * update
+ *
+ * Revision 7.0 89/11/23 22:30:54 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+#include <sys/ioctl.h>
+
+/* \f estimate of octets that might be returned */
+
+int TSelectOctets (sd, nbytes, td)
+int sd;
+long *nbytes;
+register struct TSAPdisconnect *td;
+{
+ int result;
+ long value;
+ SBV smask;
+ register struct tsapblk *tb;
+
+ missingP (nbytes);
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ result = OK;
+ if (tb -> tb_nreadfnx) {
+ if ((result = (*tb -> tb_nreadfnx) (tb, &value)) == NOTOK)
+ value = 0L;
+ }
+ else {
+#ifdef FIONREAD
+ if (ioctl (tb -> tb_fd, FIONREAD, (char *) &value) == NOTOK)
+ value = 0L;
+#endif
+
+ switch (tb -> tb_flags & (TB_TP0 | TB_TP4)) {
+ case TB_TCP:
+ case TB_X25:
+ case TB_BRG:
+ if (value > DT_MAGIC && tb -> tb_len == 0)
+ value -= DT_MAGIC;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (result == OK)
+ value += (long) tb -> tb_len;
+ *nbytes = value;
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f get TSAPs */
+
+int TGetAddresses (sd, initiating, responding, td)
+int sd;
+struct TSAPaddr *initiating,
+ *responding;
+register struct TSAPdisconnect *td;
+{
+ SBV smask;
+ register struct tsapblk *tb;
+
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if (initiating)
+ copyTSAPaddrX (&tb -> tb_initiating, initiating);
+ if (responding)
+ copyTSAPaddrX (&tb -> tb_responding, responding);
+
+ (void) sigiomask (smask);
+
+ return OK;
+}
+
+/* \f define transport manager */
+
+#ifdef MGMT
+int TSetManager (sd, fnx, td)
+int sd;
+IFP fnx;
+register struct TSAPdisconnect *td;
+{
+ SBV smask;
+ register struct tsapblk *tb;
+
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ tb -> tb_manfnx = fnx;
+
+ (void) sigiomask (smask);
+
+ return OK;
+}
+#endif
--- /dev/null
+/* tsaprespond.c - TPM: responder */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaprespond.c,v 7.2 91/02/22 09:47:42 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsaprespond.c,v 7.2 91/02/22 09:47:42 mrose Interim $
+ *
+ *
+ * $Log: tsaprespond.c,v $
+ * Revision 7.2 91/02/22 09:47:42 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/03/23 17:31:49 mrose
+ * 8
+ *
+ * Revision 7.0 89/11/23 22:30:55 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include "tpkt.h"
+#include "tailor.h"
+
+/* \f T-CONNECT.INDICATION */
+
+int TInit (vecp, vec, ts, td)
+register int vecp;
+register char **vec;
+register struct TSAPstart *ts;
+register struct TSAPdisconnect *td;
+{
+ register struct tsapblk *tb;
+
+ isodetailor (NULLCP, 0);
+
+ if (vecp < 3)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "bad initialization vector");
+ missingP (vec);
+ missingP (ts);
+ missingP (td);
+
+ if ((tb = newtblk ()) == NULL)
+ return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+
+ vec += vecp - 2;
+ switch (*vec[0]) {
+ case NT_TCP:
+#ifdef TCP
+ if (tcprestore (tb, vec[0] + 1, td) == NOTOK)
+ goto out;
+ break;
+#else
+ goto not_supported;
+#endif
+
+ case NT_X25:
+#ifdef X25
+ if (x25restore (tb, vec[0] + 1, td) == NOTOK)
+ goto out;
+ break;
+#else
+ goto not_supported;
+#endif
+
+ case NT_BRG:
+#ifdef BRIDGE_X25
+ if (bridgerestore (tb, vec[0] + 1, td) == NOTOK)
+ goto out;
+ break;
+#else
+ goto not_supported;
+#endif
+
+ case NT_BSD:
+#ifdef BSD_TP4
+ if (tp4restore (tb, vec[0] + 1, td) == NOTOK)
+ goto out;
+ break;
+#else
+ goto not_supported;
+#endif
+
+ case NT_SUN:
+#ifdef SUN_TP4
+ if (tp4restore (tb, vec[0] + 1, td) == NOTOK)
+ goto out;
+ break;
+#else
+ goto not_supported;
+#endif
+
+ default:
+ (void) tsaplose (td, DR_PARAMETER, NULLCP,
+ "unknown network type: 0x%x (%c)", *vec[0], *vec[0]);
+ goto out;
+ }
+ bzero (vec[0], strlen (vec[0]));
+
+ if ((*tb -> tb_startPfnx) (tb, vec[1], ts, td) == NOTOK)
+ goto out;
+ bzero (vec[1], strlen (vec[1]));
+
+ *vec = NULL;
+
+ return OK;
+
+not_supported: ;
+ (void) tsaplose (td, DR_PARAMETER, NULLCP,
+ "not configured for network type: 0x%x (%c)",
+ *vec[0], *vec[0]);
+
+out: ;
+ freetblk (tb);
+
+ return NOTOK;
+}
+
+/* \f T-CONNECT.RESPONSE */
+
+int TConnResponse (sd, responding, expedited, data, cc, qos, td)
+int sd;
+register struct TSAPaddr *responding;
+int expedited,
+ cc;
+char *data;
+struct QOStype *qos;
+register struct TSAPdisconnect *td;
+{
+ int result;
+ register struct tsapblk *tb;
+ struct tsapADDR tas;
+
+ if ((tb = findtblk (sd)) == NULL || (tb -> tb_flags & TB_CONN))
+ return tsaplose (td, DR_PARAMETER, NULLCP, "invalid transport descriptor");
+#ifdef notdef
+ missingP (responding);
+#endif
+ if (responding) {
+ copyTSAPaddrY (responding, &tas);
+ if (bcmp ((char *) &tb -> tb_responding, (char *) &tas, sizeof tas))
+ tb -> tb_responding = tas; /* struct copy */
+ else
+ responding = NULLTA;
+ }
+ if (expedited && !(tb -> tb_flags & TB_EXPD))
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "expedited service not available");
+ toomuchP (data, cc, TC_SIZE, "initial");
+#ifdef notdef
+ missingP (qos);
+#endif
+ missingP (td);
+
+ if (!expedited)
+ tb -> tb_flags &= ~TB_EXPD;
+
+ if ((result = (*tb -> tb_acceptPfnx) (tb, responding ? 1 : 0, data, cc,
+ qos, td)) == NOTOK)
+ freetblk (tb);
+#ifdef X25
+ else
+ if (tb -> tb_flags & TB_X25)
+ LLOG (x25_log, LLOG_NOTICE,
+ ("connection %d from %s",
+ sd, na2str (&tb -> tb_initiating.ta_addr)));
+#endif
+
+ return result;
+}
--- /dev/null
+/* tsaprovider.c - implement the transport service */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.7 91/02/22 09:47:43 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsaprovider.c,v 7.7 91/02/22 09:47:43 mrose Interim $
+ *
+ *
+ * $Log: tsaprovider.c,v $
+ * Revision 7.7 91/02/22 09:47:43 mrose
+ * Interim 6.8
+ *
+ * Revision 7.6 90/11/21 11:31:36 mrose
+ * sun
+ *
+ * Revision 7.5 90/10/29 18:39:17 mrose
+ * updates
+ *
+ * Revision 7.4 90/08/08 14:14:08 mrose
+ * update
+ *
+ * Revision 7.3 90/03/23 17:31:50 mrose
+ * 8
+ *
+ * Revision 7.2 90/01/11 18:38:09 mrose
+ * real-sync
+ *
+ * Revision 7.1 89/12/07 01:07:53 mrose
+ * queued writes
+ *
+ * Revision 7.0 89/11/23 22:30:56 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+#include "mpkt.h"
+#include "isoservent.h"
+#include "tailor.h"
+
+
+#define selmask(fd,m,n) \
+{ \
+ FD_SET (fd, &(m)); \
+ if ((fd) >= (n)) \
+ (n) = (fd) + 1; \
+}
+
+/* \f DATA */
+
+static int once_only = 0;
+static struct tsapblk tsapque;
+static struct tsapblk *THead = &tsapque;
+
+
+#ifndef SIGPOLL
+static int TPid = NOTOK;
+#endif
+
+
+extern int xselect_blocking_on_intr;
+
+/* \f T-DATA.REQUEST */
+
+int TDataRequest (sd, data, cc, td)
+int sd;
+char *data;
+int cc;
+struct TSAPdisconnect *td;
+{
+ SBV smask,
+ imask;
+ SFP istat;
+ int result;
+ struct udvec uvs[2];
+ register struct udvec *uv = uvs;
+ register struct tsapblk *tb;
+
+ missingP (data);
+ if (cc <= 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "illegal value for TSDU length (%d)", cc);
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+ (void) signal (SIGINT, istat);
+ imask = siginblock ();
+ }
+
+ uv -> uv_base = data, uv -> uv_len = cc, uv++;
+ uv -> uv_base = NULL;
+
+ result = (*tb -> tb_writePfnx) (tb, uvs, 0, td);
+
+ if (istat != SIG_DFL)
+ (void) siginmask (imask);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f T-EXPEDITED-DATA.REQUEST */
+
+int TExpdRequest (sd, data, cc, td)
+int sd;
+char *data;
+int cc;
+struct TSAPdisconnect *td;
+{
+ SBV smask,
+ imask;
+ SFP istat;
+ int result;
+ struct udvec uvs[2];
+ register struct udvec *uv = uvs;
+ register struct tsapblk *tb;
+
+ missingP (data);
+ toomuchP (data, cc, TX_SIZE, "expedited");
+ if (cc <= 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "illegal value for XSDU length (%d)", cc);
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+ (void) signal (SIGINT, istat);
+ imask = siginblock ();
+ }
+
+ uv -> uv_base = data, uv -> uv_len = cc, uv++;
+ uv -> uv_base = NULL;
+
+ if (tb -> tb_flags & TB_EXPD)
+ result = (*tb -> tb_writePfnx) (tb, uvs, 1, td);
+ else
+ result = tsaplose (td, DR_OPERATION, NULLCP,
+ "expedited service unavailable");
+
+ if (istat != SIG_DFL)
+ (void) siginmask (imask);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f T-WRITE.REQUEST (pseudo; write user data vectors) */
+
+int TWriteRequest (sd, uv, td)
+int sd;
+struct udvec *uv;
+struct TSAPdisconnect *td;
+{
+ register int n;
+ SBV smask,
+ imask;
+ SFP istat;
+ int result;
+ register struct tsapblk *tb;
+ register struct udvec *vv;
+
+ missingP (uv);
+ n = 0;
+ for (vv = uv; vv -> uv_base; vv++)
+ n += vv -> uv_len;
+ if (n == 0)
+ return tsaplose (td, DR_PARAMETER, NULLCP, "zero-length TSDU");
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+ (void) signal (SIGINT, istat);
+ imask = siginblock ();
+ }
+
+ result = (*tb -> tb_writePfnx) (tb, uv, 0, td);
+
+ if (istat != SIG_DFL)
+ (void) siginmask (imask);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f T-READ.REQUEST (pseudo; synchronous read) */
+
+int TReadRequest (sd, tx, secs, td)
+int sd;
+register struct TSAPdata *tx;
+int secs;
+register struct TSAPdisconnect *td;
+{
+ SBV smask,
+ imask;
+ SFP istat;
+ int nfds,
+ oob,
+ result;
+ fd_set ifds,
+ efds,
+ mask;
+ register struct tsapblk *tb;
+
+ missingP (tx);
+ missingP (td);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if ((istat = signal (SIGINT, SIG_DFL)) != SIG_DFL) {
+ (void) signal (SIGINT, istat);
+ imask = siginblock ();
+ }
+
+ nfds = 0;
+ FD_ZERO (&mask);
+ selmask (tb -> tb_fd, mask, nfds);
+
+ for (;;) {
+ ifds = efds = mask; /* struct copy */
+
+ if (tb -> tb_checkfnx == NULLIFP || (*tb -> tb_checkfnx) (tb) != OK)
+ switch ((*tb -> tb_selectfnx) (nfds, &ifds, NULLFD, &efds, secs)) {
+ case NOTOK: /* let read function find error... */
+ ifds = mask;
+ break;
+
+ case OK:
+ result = tsaplose (td, DR_TIMER, NULLCP, NULLCP);
+ goto out;
+
+ default:
+ break;
+ }
+ else
+ FD_ZERO (&efds);
+
+ if ((oob = FD_ISSET (tb -> tb_fd, &efds))
+ || FD_ISSET (tb -> tb_fd, &ifds))
+ result = (*tb -> tb_readPfnx) (tb, tx, td, secs != NOTOK, oob);
+ else
+ result = DONE;
+ if (result != DONE)
+ break;
+ if (secs != NOTOK) {
+ result = tsaplose (td, DR_TIMER, NULLCP, NULLCP);
+ break;
+ }
+ }
+out: ;
+
+ if (istat != SIG_DFL)
+ (void) siginmask (imask);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f T-DISCONNECT.REQUEST */
+
+int TDiscRequest (sd, data, cc, td)
+int sd;
+char *data;
+int cc;
+register struct TSAPdisconnect *td;
+{
+ SBV smask;
+ int result;
+ register struct tsapblk *tb;
+
+ toomuchP (data, cc, TD_SIZE, "disconnect");
+
+ smask = sigioblock ();
+
+ if ((tb = findtblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "invalid transport descriptor");
+ }
+
+ result = (*tb -> tb_discPfnx) (tb, data, cc, td);
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f set asynchronous event indications */
+
+static SFD DATAser ();
+
+
+int TSetIndications (sd, data, disc, td)
+int sd;
+IFP data,
+ disc;
+struct TSAPdisconnect *td;
+{
+ SBV smask;
+ int result;
+ register struct tsapblk *tb;
+
+ if (data || disc) {
+ missingP (data);
+ missingP (disc);
+ }
+
+ _iosignals_set = 1;
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if (tb -> tb_DataIndication = data) {
+ tb -> tb_flags |= TB_ASYN;
+ xselect_blocking_on_intr = 1;
+ }
+ else {
+ tb -> tb_flags &= ~TB_ASYN;
+ xselect_blocking_on_intr = 0;
+ }
+ tb -> tb_DiscIndication = disc;
+
+ result = TWakeUp (tb, td);
+
+ /* Kick the signal handling routine once to make it hand up the
+ * indications that were queued in the kernel when TSetIndications
+ * was called.
+ * TBD: We could be more efficient by only doing this for only
+ * one file descriptor.
+ */
+ (void) DATAser(0, 0L, ((struct sigcontext *) NULL));
+
+ (void) sigiomask (smask);
+
+ return result;
+}
+
+/* \f map transport descriptors for select() */
+
+int TSelectMask (sd, mask, nfds, td)
+int sd;
+fd_set *mask;
+int *nfds;
+register struct TSAPdisconnect *td;
+{
+ SBV smask;
+ register struct tsapblk *tb;
+
+ missingP (mask);
+ missingP (nfds);
+
+ smask = sigioblock ();
+
+ if ((tb = findtblk (sd)) == NULL) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_PARAMETER, NULLCP,
+ "invalid transport descriptor");
+ }
+
+ if (tb -> tb_checkfnx && (*tb -> tb_checkfnx) (tb) == OK) {
+ (void) sigiomask (smask);
+ return tsaplose (td, DR_WAITING, NULLCP, NULLCP);
+ }
+
+ selmask (tb -> tb_fd, *mask, *nfds);
+
+ (void) sigiomask (smask);
+
+ return OK;
+}
+
+/* \f NSAP interface: N-DATA.INDICATION */
+
+/* ARGSUSED */
+
+static SFD DATAser (sig, code, sc)
+int sig;
+long code;
+struct sigcontext *sc;
+{
+ int n,
+ nfds,
+ oob,
+ sd;
+ fd_set ifds,
+ efds,
+ imask,
+ emask;
+#ifndef BSDSIGS
+ SBV smask;
+#endif
+ IFP disc;
+ register struct tsapblk *tb,
+ *tb2;
+ struct TSAPdata txs;
+ register struct TSAPdata *tx = &txs;
+ struct TSAPdisconnect tds;
+ register struct TSAPdisconnect *td = &tds;
+
+#ifndef BSDSIGS
+ (void) signal (SIGEMT, DATAser);
+
+ smask = sigioblock ();
+#endif
+
+ for (;;) {
+ n = 0;
+ FD_ZERO (&ifds);
+ FD_ZERO (&efds);
+ for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+ if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) {
+ nfds = 0;
+ FD_ZERO (&imask);
+ selmask (tb -> tb_fd, imask, nfds);
+ emask = imask; /* struct copy */
+ if ((*tb -> tb_selectfnx) (nfds, &imask, NULLFD, &emask, 0)
+ > OK) {
+ if (FD_ISSET (tb -> tb_fd, &imask))
+ FD_SET (tb -> tb_fd, &ifds);
+ if (FD_ISSET (tb -> tb_fd, &emask))
+ FD_SET (tb -> tb_fd, &efds);
+ n++;
+ }
+ }
+
+ if (n == 0)
+ break;
+
+ for (tb = THead -> tb_forw; tb != THead; tb = tb2) {
+ tb2 = tb -> tb_forw;
+
+ sd = tb -> tb_fd;
+ if ((oob = FD_ISSET (sd, &efds)) || FD_ISSET (sd, &ifds)) {
+ disc = tb -> tb_DiscIndication;
+ switch ((*tb -> tb_readPfnx) (tb, tx, td, 1, oob)) {
+ case NOTOK:
+ (*disc) (sd, td);
+ break;
+
+ case OK:
+ (*tb -> tb_DataIndication) (sd, tx);
+ break;
+
+ case DONE: /* partially assembled TSDU */
+ break;
+ }
+ }
+ }
+ }
+
+#ifndef SIGPOLL
+ (void) kill (TPid, SIGEMT);
+#endif
+
+#ifndef BSDSIGS
+ (void) sigiomask (smask);
+#endif
+}
+
+/* \f */
+
+#ifndef SIGPOLL
+static int TWakeUp (tb, td)
+register struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+ int i,
+ nfds;
+ fd_set mask;
+ char buf1[10],
+ buf2[10],
+ buf3[10];
+ register struct isoservent *is;
+ static int inited = 0;
+
+ if (TPid > OK) {
+ (void) kill (TPid, SIGTERM);
+ TPid = NOTOK;
+ }
+
+ nfds = 0;
+ FD_ZERO (&mask);
+ for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+ if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN))
+ selmask (tb -> tb_fd, mask, nfds);
+
+ if (nfds == 0)
+ return OK;
+
+ if (nfds > sizeof (int) * 8)
+ return tsaplose (td, DR_CONGEST, NULLCP, "you lose");
+ if (!inited) {
+#ifndef BSDSIGS
+ int smask = sigsetmask (sigblock (0) & ~sigmask (SIGEMT));
+#endif
+
+ (void) signal (SIGEMT, DATAser);
+#ifndef BSDSIGS
+ (void) sigiomask (smask);
+#endif
+ inited++;
+ }
+
+ if ((is = getisoserventbyname ("isore", "tsap")) == NULL)
+ return tsaplose (td, DR_CONGEST, NULLCP,
+ "ISO service tsap/isore not found");
+
+ (void) sprintf (buf1, "%d", nfds);
+ *is -> is_tail++ = buf1;
+ (void) sprintf (buf2, "0x%x", mask.fds_bits[0]);
+ *is -> is_tail++ = buf2;
+ (void) sprintf (buf3, "%d", getpid ());
+ *is -> is_tail++ = buf3;
+ *is -> is_tail = NULL;
+
+ for (i = 0; i < 5; i++)
+ switch (TPid = vfork ()) {
+ case NOTOK:
+ continue;
+
+ case OK:
+ (void) signal (SIGEMT, SIG_DFL);
+ (void) execv (*is -> is_vec, is -> is_vec);
+ _exit (1);
+
+ default:
+ return OK;
+ }
+
+ return tsaplose (td, DR_CONGEST, "isore", "unable to fork");
+}
+#else
+#ifdef BSDSIGS
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#else
+#include <sys/stropts.h>
+#endif
+
+
+static int TWakeUp (tb, td)
+register struct tsapblk *tb;
+struct TSAPdisconnect *td;
+{
+ int result;
+#ifndef SUNOS4
+ int pgrp;
+#endif
+ static int inited = 0;
+
+ if (tb -> tb_flags & TB_ASYN) {
+ if (!inited) {
+ (void) signal (SIGPOLL, DATAser);
+
+ inited++;
+ }
+
+#ifdef BSDSIGS
+#ifdef SUNOS4
+ if (fcntl (tb -> tb_fd, F_SETOWN, getpid ()) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETOWN");
+#else
+ pgrp = -getpid ();
+ if (ioctl (tb -> tb_fd, SIOCSPGRP, (char *) &pgrp) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "ioctl SIOCSPGRP %d",
+ pgrp);
+#endif
+ if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL");
+ result |= FASYNC;
+ if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x",
+ result);
+#else
+#ifdef notdef
+ if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK)
+ result = 0;
+ result |= S_INPUT;
+ if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x",
+ result);
+#else
+ return tsaplose (td, DR_CONGEST, NULLCP,
+ "asynchronous operations not yet supported under SVR3");
+#endif
+#endif
+ }
+ else {
+#ifdef BSDSIGS
+ if ((result = fcntl (tb -> tb_fd, F_GETFL, 0x00)) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "fcntl F_GETFL");
+ result &= ~FASYNC;
+ if (fcntl (tb -> tb_fd, F_SETFL, result) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "fcntl F_SETFL 0x%x",
+ result);
+#else
+ if (ioctl (tb -> tb_fd, I_GETSIG, &result) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "ioctl I_GETSIG");
+ result &= ~S_INPUT;
+ if (ioctl (tb -> tb_fd, I_SETSIG, result) == NOTOK)
+ return tsaplose (td, DR_CONGEST, "failed", "ioctl I_SETSIG 0x%x",
+ result);
+#endif
+ }
+
+ return OK;
+}
+#endif
+
+/* \f INTERNAL */
+
+struct tsapblk *newtblk () {
+ register struct tsapblk *tb;
+
+ tb = (struct tsapblk *) calloc (1, sizeof *tb);
+ if (tb == NULL)
+ return NULL;
+
+ tb -> tb_fd = NOTOK;
+
+ tb -> tb_qbuf.qb_forw = tb -> tb_qbuf.qb_back = &tb -> tb_qbuf;
+ tb -> tb_qwrites.qb_forw = tb -> tb_qwrites.qb_back = &tb -> tb_qwrites;
+
+ if (once_only == 0) {
+ THead -> tb_forw = THead -> tb_back = THead;
+ once_only++;
+ }
+
+ insque (tb, THead -> tb_back);
+
+ return tb;
+}
+
+
+freetblk (tb)
+register struct tsapblk *tb;
+{
+ SBV smask;
+#ifndef SIGPOLL
+ struct TSAPdisconnect tds;
+#endif
+
+ if (tb == NULL)
+ return;
+
+ smask = sigioblock ();
+
+ if (tb -> tb_fd != NOTOK) {
+ (void) (*tb -> tb_closefnx) (tb -> tb_fd);
+#ifdef MGMT
+ if (tb -> tb_manfnx)
+ (*tb -> tb_manfnx) (DISCREQ, tb);
+#endif
+ }
+
+ if (tb -> tb_retry)
+ freetpkt (tb -> tb_retry);
+
+ if (tb -> tb_calling)
+ free ((char *) tb -> tb_calling);
+ if (tb -> tb_called)
+ free ((char *) tb -> tb_called);
+ if (tb -> tb_data)
+ free (tb -> tb_data);
+
+#ifndef SIGPOLL
+ if ((tb -> tb_flags & TB_ASYN) && TPid > OK) {
+ (void) kill (TPid, SIGTERM);
+ TPid = NOTOK;
+ }
+#endif
+
+ QBFREE (&tb -> tb_qbuf);
+
+ if (tb -> tb_queuePfnx)
+ (*tb -> tb_queuePfnx) (tb, 0, (struct TSAPdisconnect *) 0);
+ QBFREE (&tb -> tb_qwrites);
+
+ remque (tb);
+
+ free ((char *) tb);
+
+#ifndef SIGPOLL
+ for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+ if (tb -> tb_fd != NOTOK && (tb -> tb_flags & TB_ASYN)) {
+ (void) TWakeUp (tb, &tds);
+ break;
+ }
+#endif
+
+ (void) sigiomask (smask);
+}
+
+/* \f */
+
+struct tsapblk *findtblk (sd)
+register int sd;
+{
+ register struct tsapblk *tb;
+
+ if (once_only == 0)
+ return NULL;
+
+ for (tb = THead -> tb_forw; tb != THead; tb = tb -> tb_forw)
+ if (tb -> tb_fd == sd)
+ return tb;
+
+ return NULL;
+}
+
+/* \f */
+
+int copyTSAPaddrX (in, out)
+struct tsapADDR *in;
+struct TSAPaddr *out;
+{
+ bzero ((char *) out, sizeof *out);
+
+ bcopy (in -> ta_selector, out -> ta_selector,
+ out -> ta_selectlen = in -> ta_selectlen);
+
+ if (in -> ta_present) {
+ out -> ta_addrs[0] = in -> ta_addr; /* struct copy */
+ out -> ta_naddr = 1;
+ }
+}
+
+
+int copyTSAPaddrY (in, out)
+struct TSAPaddr *in;
+struct tsapADDR *out;
+{
+ bzero ((char *) out, sizeof *out);
+
+ bcopy (in -> ta_selector, out -> ta_selector,
+ out -> ta_selectlen = in -> ta_selectlen);
+
+ if (out -> ta_present = (in -> ta_naddr >= 1) ? 1 : 0)
+ out -> ta_addr = in -> ta_addrs[0]; /* struct copy */
+}
--- /dev/null
+/* tsapstate.c - TPM: hack state */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/tsap/RCS/tsapstate.c,v 7.3 91/02/22 09:47:45 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/tsap/RCS/tsapstate.c,v 7.3 91/02/22 09:47:45 mrose Interim $
+ *
+ *
+ * $Log: tsapstate.c,v $
+ * Revision 7.3 91/02/22 09:47:45 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/03/23 17:31:54 mrose
+ * 8
+ *
+ * Revision 7.1 90/03/22 08:38:12 mrose
+ * touch-up
+ *
+ * Revision 7.0 89/11/23 22:30:58 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <stdio.h>
+#include <signal.h>
+#include "tpkt.h"
+
+/* \f */
+
+int TSaveState (sd, vec, td)
+int sd;
+char **vec;
+register struct TSAPdisconnect *td;
+{
+ SBV smask;
+ register struct tsapblk *tb;
+ static char buffer[sizeof *tb * 2 + 1];
+
+ missingP (vec);
+
+ smask = sigioblock ();
+
+ tsapPsig (tb, sd);
+
+ if (tb -> tb_len > 0) {
+ (void) sigiomask (smask);
+
+ return tsaplose (td, DR_WAITING, NULLCP, NULLCP);
+ }
+
+ buffer[explode (buffer, (u_char *) tb, sizeof *tb)] = NULL;
+ *vec++ = buffer;
+ *vec = NULL;
+
+ tb -> tb_fd = NOTOK;
+
+ freetblk (tb);
+
+ (void) sigiomask (smask);
+
+ return OK;
+}
+
+/* \f */
+
+int TRestoreState (buffer, ts, td)
+char *buffer;
+register struct TSAPstart *ts;
+register struct TSAPdisconnect *td;
+{
+ struct tsapblk tbs;
+ register struct tsapblk *tb;
+
+ missingP (buffer);
+ missingP (ts);
+
+ if ((tb = newtblk ()) == NULL)
+ return tsaplose (td, DR_CONGEST, NULLCP, "out of memory");
+
+ if (implode ((u_char *) &tbs, buffer, strlen (buffer)) != sizeof tbs) {
+ (void) tsaplose (td, DR_PARAMETER, NULLCP, "bad state vector");
+ goto out1;
+ }
+
+ if (findtblk (tbs.tb_fd)) {
+ (void) tsaplose (td, DR_PARAMETER, NULLCP, "transport descriptor active");
+ goto out1;
+ }
+ tb -> tb_fd = tbs.tb_fd;
+ tb -> tb_flags = tbs.tb_flags & (TB_CONN | TB_EXPD | TB_TP0 | TB_TP4);
+ tb -> tb_srcref = tbs.tb_srcref;
+ tb -> tb_dstref = tbs.tb_dstref;
+ tb -> tb_initiating = tbs.tb_initiating; /* struct copy */
+ tb -> tb_responding = tbs.tb_responding; /* struct copy */
+
+ switch (tb -> tb_flags & (TB_TP0 | TB_TP4)) {
+#ifdef TCP
+ case TB_TCP:
+ (void) TTService (tb);
+ break;
+#endif
+
+#ifdef X25
+ case TB_X25:
+ (void) XTService (tb);
+ break;
+#endif
+
+#ifdef BRIDGE_X25
+ case TB_BRG:
+ (void) BTService (tb);
+ break;
+#endif
+
+#ifdef TP4
+ case TB_TP4:
+ (void) tp4init (tb);
+ break;
+#endif
+
+ default:
+ (void) tsaplose (td, DR_PARAMETER, NULLCP, "network type not set");
+ tb -> tb_fd = NOTOK;
+ goto out1;
+ }
+
+ tb -> tb_tsdusize = tbs.tb_tsdusize;
+
+ bzero ((char *) ts, sizeof *ts);
+ ts -> ts_sd = tb -> tb_fd;
+ copyTSAPaddrX (&tb -> tb_initiating, &ts -> ts_calling);
+ copyTSAPaddrX (&tb -> tb_responding, &ts -> ts_called);
+ if (tb -> tb_flags & TB_EXPD)
+ ts -> ts_expedited = 1;
+ ts -> ts_tsdusize = tb -> tb_tsdusize;
+ ts -> ts_qos = tb -> tb_qos; /* struct copy */
+
+ return OK;
+
+out1: ;
+ freetblk (tb);
+
+ return NOTOK;
+}
--- /dev/null
+: 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
--- /dev/null
+: run this script through /bin/sh
+
+M=BSD42 O= L=/usr/lib/lint
+
+for A in $*
+do
+ case $A in
+ -bsd42)
+ M=BSD42
+ ;;
+
+ -bsd44)
+ M=BSD44
+ ;;
+
+ -sys5) M=SYS5
+ exit 0
+ if test ! -f ${L}/lint1; then
+ L=/usr/lib
+ if test ! -f ${L}/lint1; then
+ echo "inst-lint: unable to find lint1" 1>&2
+ exit 0
+ fi
+ fi
+ ;;
+
+ -mips) M=SYS5
+ ;;
+
+ -ros) M=ROS
+ ;;
+
+ -*) O="$O $A"
+ ;;
+
+ *) case $M in
+ BSD42) echo /lib/cpp -C -Dlint $O $A \| \
+ /usr/lib/lint/lint1 -v \> $A.ln
+ /lib/cpp -C -Dlint $O $A | \
+ /usr/lib/lint/lint1 -v > $A.ln
+ ;;
+
+ BSD44) echo lint -Clint $O $A
+ lint -Clint $O $A
+ echo mv llib-lint.ln $A.ln
+ mv llib-lint.ln $A.ln
+ ;;
+
+ SYS5) echo /bin/cc -E -C -Dlint $O $A \| \
+ ${L}/lint1 -v \> $A.ln
+ /bin/cc -E -C -Dlint $O $A | \
+ ${L}/lint1 -v > $A.ln
+ ;;
+
+ MIPS) echo lint -o /usr/lib/cmplrs/cc/lint/$A.ln $O $A
+ lint -o /usr/lib/cmplrs/cc/lint/$A.ln $O $A
+ ;;
+
+ ROS) echo lint -c -v $O $A
+ lint -c -v $O $A
+ F="`basename $A`"
+ if [ $F != $A ]; then
+ echo mv $F.ln $A.ln
+ mv $F.ln $A.ln
+ fi
+ ;;
+
+ *) echo "inst-lint: mode botch" 1>&2
+ exit 1
+ ;;
+ esac
+ ;;
+ esac
+done
+
+exit 0
--- /dev/null
+: run this script through /bin/sh
+
+M=BSD42 L= O= S= Q= SHD= MAJ= MIN=
+
+while [ $# -gt 0 ]
+do
+ A="$1"
+ case $A in
+ -bsd42|-mips)
+ M=BSD42
+ ;;
+ -shared)SHD=T
+ ;;
+
+ -sys5) M=SYS5
+ ;;
+
+ -aix) M=AIX
+ ;;
+
+ -ros) M=ROS
+ ;;
+
+ -ranlib)
+ case $M in
+ BSD42|ROS)
+ echo ranlib "$L"
+ case "$L" in
+ /*) (cd /usr/tmp; ranlib "$L")
+ ;;
+
+ *) ranlib "$L"
+ ;;
+ esac
+ ;;
+
+ SYS5|AIX|old)
+ ;;
+
+ *) echo "make-lib: mode botch" 1>&2
+ exit 1
+ ;;
+ esac
+ exit 0
+ ;;
+
+ -quick) Q=T
+ ;;
+
+ -major) MAJ="$2"
+ shift
+ ;;
+ -minor) MIN="$2"
+ shift
+ ;;
+ -*) S="$S`echo $A | sed -e s%-%%`"
+ ;;
+
+ *) if [ "x$L" = x ]; then
+ L="$A"
+ else
+ O="$O $A"
+ fi
+ ;;
+ esac
+ shift
+done
+
+case $M in
+ BSD42|ROS)
+ if [ "x$SHD" = xT ]; then
+ if [ "$M" = ROS ]; then
+ echo "Can't build shared libraries for ROS" 1>&2
+ exit 1
+ fi
+ if [ "x$MAJ" = x -o "x$MIN" = x ]; then
+ echo "Missing major or minor number for library" 1>&2
+ exit 1
+ fi
+ rm -rf tmp-shared
+ mkdir tmp-shared
+ case "$L" in
+ /*) LP="$L";;
+ *) LP="../$L";;
+ esac
+ (cd tmp-shared; ar x "$LP"
+ LSO="`echo $LP | sed 's%.a$%%'`".so.$MAJ.$MIN
+ echo ld -o "$LSO" -assert pure-text *.o
+ ld -o "$LSO" -assert pure-text *.o
+ )
+ rm -rf tmp-shared
+ else
+ echo ar q"$S" "$L" $O
+ ar q"$S" "$L" $O
+ if [ "x$Q" != xT ]; then
+ echo ranlib "$L"
+ ranlib "$L"
+ fi
+ fi
+ ;;
+
+ SYS5) if [ "x$SHD" = xT ]; then
+ echo "Can't build shared libraries for Sys 5 (yet)" 1>&2
+ exit 1
+ fi
+ echo ar ql"$S" "$L" $O
+ ar ql"$S" "$L" $O
+ ;;
+
+ AIX) if [ "x$SHD" = xT ]; then
+ echo "Can't build shared libraries for AIX (yet)" 1>&2
+ exit 1
+ fi
+ echo ar rlv"$S" "$L" \`lorder $O \| tsort\`
+ ar rlv"$S" "$L" `lorder $O | tsort`
+ ;;
+
+ old) if [ "x$SHD" = xT ]; then
+ echo "Can't build shared libraries for old style" 1>&2
+ exit 1
+ fi
+ echo ar r"$S" "$L" \`lorder $O \| tsort\`
+ ar r"$S" "$L" `lorder $O | tsort`
+ ;;
+
+ *) echo "make-lib: mode botch" 1>&2
+ exit 1
+ ;;
+esac
+
+exit 0
--- /dev/null
+: run this script through /bin/sh
+
+: this hacks past a bug in make...
+exec 3<&- 4<&- 5<&- 6<&- 7<&-
+
+OFS="$IFS" IFS=:
+
+if [ "x$1" = x ]; then echo 'usage: version.sh module' 1>&2; exit 1; fi
+
+for A in rprompt hostname uname who
+do
+ for D in $PATH
+ do
+ if [ ! -f $D/$A ]; then
+ continue
+ fi
+ case $A in
+ rprompt) LOCAL=`$A %h`
+ ;;
+ hostname) LOCAL=`$A`
+ ;;
+ uname) LOCAL=`$A -n`
+ ;;
+ who) LOCAL=`$A am i | sed -e 's%^\(.*\)!.*$%\1%'`
+ ;;
+ esac
+ break
+ done
+ if [ "x$LOCAL" != x ]; then
+ break
+ fi
+done
+
+IFS=
+
+if [ ! -r version.major ]; then echo 0 > version.major; fi
+if [ ! -r version.minor ]; then echo 1 > version.minor; fi
+if [ ! -r version.local ]; then echo 0 > version.local; fi
+echo `cat version.major` `cat version.minor` `cat version.local` $1 $2 > version
+rm -f version.c version.local
+
+awk ' { major = $1; minor = $2; local = $3 + 1; sfw = $4; \
+ if (NF >= 5) note = $5; else note = ""; }\
+END { printf "char *%sversion = \"%s%s %d.%d #%d ", sfw, sfw, note, major, minor, local; \
+ printf "%d\n", local > "version.local"; }' < version
+echo '('$LOCAL') of '`date`'";'
+
+rm -f version
--- /dev/null
+###############################################################################
+# Instructions to Make, for compilation of ISODE VT processes
+###############################################################################
+
+###############################################################################
+#
+# $Header: /f/osi/vt/RCS/Makefile,v 7.3 91/02/22 09:47:50 mrose Interim $
+#
+#
+# $Log: Makefile,v $
+# Revision 7.3 91/02/22 09:47:50 mrose
+# Interim 6.8
+#
+# Revision 7.2 90/12/23 18:43:28 mrose
+# update
+#
+# Revision 7.1 90/07/09 14:51:45 mrose
+# sync
+#
+# Revision 7.0 89/11/23 22:31:25 mrose
+# Release 6.0
+#
+###############################################################################
+
+###############################################################################
+#
+# NOTICE
+#
+# Acquisition, use, and distribution of this module and related
+# materials are subject to the restrictions of a license agreement.
+# Consult the Preface in the User's Manual for the full terms of
+# this agreement.
+#
+###############################################################################
+
+
+.SUFFIXES: .py .c .o
+
+.c.o:; $(CC) $(CFLAGS) $(INCLUDES) -c $*.c
+
+.py.c:; $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) $<
+
+
+LIBES = $(TOPDIR)libisode.a
+LLIBS = $(TOPDIR)llib-lisode
+VTH = vtpm.h $(HDIR)acsap.h $(HDIR)psap.h $(HDIR)manifest.h \
+ $(HDIR)config.h $(HDIR)general.h $(HDIR)psap2.h $(HDIR)logger.h
+CFILES = vtpm.c vtuser.c vt_telnet.c map.c \
+ actions1.c actions5.c states1.c states5.c
+OFILES = vtpm.o vtuser.o vt_telnet.o map.o \
+ actions1.o actions5.o states1.o states5.o
+PYFILES = bk_content.py rcv_asq.py rcv_asr.py rcv_text.py send_asq.py \
+ send_asr.py send_text.py send_udq.py rcv_udq.py print_vt.py
+HFILES = eventmsg.h sector1.h sector5.h vtpm.h
+PYFILES-C= BK_CONTENT.c RCV_ASQ.c RCV_ASR.c RCV_TEXT.c RCV_UDQ.c \
+ SEND_ASQ.c SEND_ASR.c SEND_TEXT.c SEND_UDQ.c PRINT_VT.c
+PYFILES-O= BK_CONTENT.o RCV_ASQ.o RCV_ASR.o RCV_TEXT.o RCV_UDQ.o \
+ SEND_ASQ.o SEND_ASR.o SEND_TEXT.o SEND_UDQ.o PRINT_VT.o
+
+
+##################################################################
+# Here it is...
+##################################################################
+
+all: vtd vt
+inst-all: inst-vtd inst-vt manuals
+install: inst-all clean
+lint: l-vtd l-vt
+
+
+##################################################################
+# vtd
+##################################################################
+
+inst-vtd: $(SBINDIR)iso.vt
+
+$(SBINDIR)iso.vt: xvtd
+ -cp $@ ziso.vt
+ -rm -f $@
+ cp xvtd $@
+ -@ls -gls $@
+ -@echo ""
+
+vtd: xvtd
+
+xvtd: vtd.o $(OFILES) libvt.a
+ $(LDCC) $(LDFLAGS) -o $@ vtd.o $(OFILES) libvt.a \
+ $(LIBES) $(LSOCKET)
+
+vtd.o: $(VTH) sector1.h $(HDIR)tailor.h
+vtpm.o: $(VTH) eventmsg.h sector1.h
+vtuser.o: $(VTH) sector1.h sector5.h
+vt_telnet.o: $(VTH) sector1.h
+map.o: $(VTH) sector1.h
+actions1.o: $(VTH) sector1.h
+actions5.o: $(VTH) sector1.h
+states1.o: $(VTH)
+states5.o:
+
+l-vtd: $(PYFILES-C) true
+ $(LINT) $(LFLAGS) vtd.c $(CFILES) $(PYFILES-C) $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+
+##################################################################
+# vt
+##################################################################
+
+inst-vt: $(BINDIR)vt
+
+$(BINDIR)vt: xvt
+ -cp $@ zxvt
+ -rm -f $@
+ cp xvt $@
+ -@ls -gls $@
+ -@echo ""
+
+vt: xvt
+
+xvt: vt.o $(OFILES) libvt.a
+ $(LDCC) $(LDFLAGS) -o $@ vt.o $(OFILES) libvt.a \
+ $(LIBES) $(LSOCKET)
+
+vt.o: $(VTH) sector1.h $(HDIR)tailor.h
+
+l-vt: $(PYFILES-C) true
+ $(LINT) $(LFLAGS) vt.c $(CFILES) $(PYFILES-C) $(LLIBS) \
+ | grep -v "warning: possible pointer alignment problem"
+
+
+##################################################################
+# libvt
+##################################################################
+
+libvt.a: $(PYFILES-O)
+ -rm -f $@
+ @$(UTILDIR)make-lib.sh $(SYSTEM) $(ARFLAGS) $@ $(PYFILES-O)
+ -@ls -l $@
+ -@echo "VT library built normally"
+
+BK_CONTENT.c: bk_content.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ bk_content.py
+
+RCV_ASQ.c: rcv_asq.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ rcv_asq.py
+
+RCV_ASR.c: rcv_asr.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ rcv_asr.py
+
+RCV_TEXT.c: rcv_text.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ rcv_text.py
+
+RCV_UDQ.c: rcv_udq.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ rcv_udq.py
+
+SEND_ASQ.c: send_asq.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ send_asq.py
+
+SEND_ASR.c: send_asr.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ send_asr.py
+
+SEND_TEXT.c: send_text.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ send_text.py
+
+SEND_UDQ.c: send_udq.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ send_udq.py
+
+PRINT_VT.c: print_vt.py $(TOPDIR)pepy/xpepy
+ $(TOPDIR)pepy/xpepy -a PY_advise -m $(PYFLAGS) -o $@ \
+ print_vt.py
+
+
+##################################################################
+# manual pages
+##################################################################
+
+MANUALS = vtd.8c vt.1c
+
+manuals:; @$(UTILDIR)inst-man.sh $(MANOPTS) $(MANUALS)
+ -@echo ""
+
+
+##################################################################
+# clean
+##################################################################
+
+clean:; rm -f *.ph *.o *.a $(PYFILES-C) x* z* _* core
+
+grind:; iprint Makefile
+ tgrind -lc vt.c vtd.c $(HFILES) $(CFILES)
+ tgrind -lpepy -d $(TOPDIR)pepy/grindefs ($PYFILES)
+ @echo $(MANUALS) | \
+ tr " " "\012" | \
+ sed -e 's%.*%itroff -man &%" | \
+ sh -ve
+
+true:;
--- /dev/null
+/* actions1.c - VTPM: FSM sector 1 actions */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/actions1.c,v 7.2 91/02/22 09:47:52 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/actions1.c,v 7.2 91/02/22 09:47:52 mrose Interim $
+ *
+ *
+ * $Log: actions1.c,v $
+ * Revision 7.2 91/02/22 09:47:52 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/10/23 20:44:45 mrose
+ * update
+ *
+ * Revision 7.0 89/11/23 22:31:26 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+#include "sector1.h"
+
+/************************************************************************/
+/* This file contains the functions that are executed when the */
+/* VT Protocol machine is in a Sector 1 state and a protocol */
+/* event occurs. The state transition matrix is specified in */
+/* Table 32 of ISO 9041 (July 1987 version). The actions which */
+/* this collection of functions perform are specified in Table 33 */
+/* of ISO 9041. */
+/************************************************************************/
+
+extern int sd; /*Global Session Descriptor (ISODE) */
+
+#define invalid_result(str,pe) \
+ adios (NULLCP, "%s: invalid result (%s)", (str), \
+ pe_error ((p) -> pe_errno))
+
+int
+a1_0(pe) /*NDQ-ntr in states 50B or 51Q (Release awaiting peer)*/
+ /*Also RTQ in state 51T (Release awaiting peer)*/
+PE pe;
+{
+ /*If quarantined data delivery were supported, we would do:
+ /* ++vnt;
+ /* enque(pe);
+ /*For now, only supporting simple or no delivery control, so give pe
+ /*to application here.
+ */
+
+ vdatind(SEQUENCED,pe); /*Deliver the NDQ to application*/
+ return(OK);
+}
+\f
+
+int
+a1_1(pe) /*NDQ-tr in states 50B or 51Q (Release Awaiting Peer)*/
+PE pe;
+{
+ /* Same comment as in a1_0 above */
+ vdatind(SEQUENCED,pe); /*Deliver the NDQ to application*/
+ vnt = 0;
+ return(OK);
+}
+\f
+
+int
+a1_2(pe) /*VASSreq from user in state 01 (No Association)*/
+PE pe;
+{
+ dr_pm_st = DEFINED; /*Draft-VTE param. status = Defined
+ /*(SetVTPmS(P) in 9041) */
+ /*Set draft-VTE parameter values per profile (SetVTPmV(P) in 9041)*/
+
+ asq(pe); /*Send the ASQ PDU*/
+
+ vsmd = 0; /*Very TEMPORARY -- A-Mode only
+ Should be done in VT-user or application call
+ */
+ if(vsmd) state = S1_02S;
+ else state = S1_02B;
+ return(OK);
+}
+\f
+
+int
+a1_3(pe) /*VASSrsp from user in state 03B (Associate -- Awaiting user)*/
+PE pe;
+{
+ PE p;
+ vrsl = -1;
+ for(p = first_member(pe); p; p = next_member(pe,p))
+ /*Step through elements in sequence*/
+ {
+ if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+ /*If the result element*/
+ {
+ if( (vrsl = prim2num(p)) == NOTOK)
+ invalid_result ("a1_3", p);
+ break;
+ }
+ }
+ if(vrsl < 0) /*If no result field*/
+ adios(NULLCP, "a1_3: no result field");
+ if(vrsl == FAILURE)
+ {
+ clear_vte();
+ (void) asr(pe,FAILURE);
+ }
+ else
+ {
+ /*Set draft-VTE parameters according to list in primitive
+ /* (SetVTPmV(L) in 9041)
+ /*Set status of draft-VTE parameters above to defined
+ /* (SetVTPmSDe(L)
+ /*Set current VTE from draft VTE (SetCuVTE) */
+
+ vena = TRUE; /*Current VTE agreed to*/
+ waca = TRUE;
+ (void) asr(pe,SUCCESS);
+ if(vrsl == SUCCESS)
+ {
+ sector = 5;
+ state = S5_400B;
+ }
+ else state = S1_10B;
+ }
+ return(OK);
+}
+\f
+
+int
+a1_4(pe) /*VASSrsp from user in state 03S (Associate -- Awaiting user)*/
+PE pe;
+{
+ PE p;
+ vrsl = -1;
+ for(p = first_member(pe); p; p = next_member(pe,p))
+ /*Step through elements in sequence*/
+ {
+ if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+ /*If the result element*/
+ {
+ if( (vrsl = prim2num(p)) == NOTOK)
+ invalid_result ("a1_4", p);
+ break;
+ }
+ }
+ if(vrsl < 0) /*If no result field*/
+ adios(NULLCP,"a1_4: no result field");
+ if(vrsl == FAILURE)
+ {
+ clear_vte(); /*Discard VTE (DisVTE)*/
+ (void) asr(pe,FAILURE); /*Send the ASR to peer*/
+ }
+ else
+ {
+ /*Set draft-VTE parameters according to list in primitive
+ /* (SetVTPmV(L) in 9041)
+ /*Set status of draft-VTE parameters above to defined
+ /* (SetVTPmSDe(L)
+ /*Set current VTE from draft VTE (SetCuVTE) */
+
+ vena = TRUE; /*Current VTE agreed to*/
+ (void) asr(pe,SUCCESS);
+ if(vrsl == SUCCESS)
+ {
+ sector = 5;
+ if(vtok)state = S5_40T;
+ else state = S5_40N;
+ }
+ else
+ {
+ if(vtok) state = S1_10T;
+ else state = S1_10N;
+ }
+ }
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_5(pe) /*RTQ (Token Request) in state 10B
+ (Environment not agreed)*/
+PE pe;
+{
+ give_token(); /*Need a call to lower layer in ISODE to do this*/
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_6(pe) /*VGVTreq from user in 10T*/
+PE pe;
+{
+ give_token(); /*Need a call to lower layer in ISODE to do this*/
+ state = S1_10N;
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_7(pe) /*VRELreq from user in state 10B (Env. not agreed)*/
+ /*GTQ in 50B*/
+PE pe;
+{
+ if(vtok)
+ {
+ vt_disconnect(); /*May be only TEMP*/
+ state = S1_51Q;
+ }
+ else
+ {
+ request_token();
+ /*Need call to ISODE to request token*/
+ state = S1_50B;
+
+/*Probably need to release the NULL PE for VRELreq that got us here*/
+
+ }
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_8(pe) /*VRELreq in 10T*/
+PE pe;
+{
+ vt_disconnect(); /*May be only TEMP--check function*/
+ state = S1_51T;
+
+/*Release NULL PE from VT USER*/
+
+ return(OK);
+}
+\f
+int
+a1_9(pe) /*VRELrsp in 51R & 51N (Release -- Awaiting User)*/
+PE pe;
+{
+
+
+/* vrsl = -1;
+/* for(p = first_member(pe); p; p = next_member(pe,p) )
+/* /*Get Result parameter*/
+/* {
+/* if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,0) )
+/* {
+/* if( (vrsl = prim2num(p)) == NOTOK)
+/* invalid_result ("a1_9", p);
+/* break;
+/* }
+/* }
+/* if(vrsl < 0)
+/* adios(NULLCP,"a1_9: no result field");
+/*
+/* we should look in the pdu and see what the result is, but
+/* since we know our vt-user is an agreeable fellow, we can
+/* assume success
+*/
+
+ vrsl = SUCCESS;
+ if(vrsl == SUCCESS)
+ {
+ if(vns > 0) /*If data left to send*/
+ {
+ advise(LLOG_NOTICE,NULLCP, "Sending remaining data (a1_9() )");
+ send_all(); /*Send remaining data (NDQseq(Vns)-ntr)*/
+ vns = 0;
+ }
+ send_rlr(pe); /*Send the RLR which User built*/
+ clear_vte(); /*Erase the Environment*/
+ state = S1_01;
+/* system("reset"); */
+ finalbye ();
+ advise(LLOG_NOTICE,NULLCP,"association released by terminal service");
+ (void)fflush (stdout);
+ exit(0);
+ }
+ else /*Result was failure*/
+ {
+ send_rlr(pe); /*Send the RLR*/
+ if(vena) /*If agreement on VTE*/
+ {
+ sector = 5;
+ if(vsmd) state = S5_40N; /*If S-Mode*/
+ else state = S5_400B;
+ }
+ else
+ {
+ if(vsmd) state = S1_10N;
+ else state = S1_10B;
+ }
+ }
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_10(pe) /*VRQTreq(request token) n state 10N*/
+PE pe;
+{
+ request_token(); /*TEMP -- Need an ISODE call to really do this
+ since there is no VTP PDU*/
+
+/*Probably need to free the NullPE that triggered this*/
+
+ state = S1_10N; /*Should be here already. Do this to follow
+ the spec literally*/
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_11(pe) /*VSNEGreq (User Start Negotiation)*/
+PE pe;
+{
+
+/*MIN not implemented*/
+/*Probably need to send back a negative Acknowledgement*/
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_12(pe) /*VSNEGreq*/
+PE pe;
+{
+
+/*MIN not implemented*/
+/*Probably need to send back a Negative Acknowledgement*/
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_13(pe) /*VSWPreq (User Switch profile request)*/
+PE pe;
+{
+
+ /*Switch Profile not implemented*/
+ /*Should probably send back a negative acknowledgement*/
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_14(pe) /*VSWPreq*/
+PE pe;
+{
+
+ /*Switch Profile not implented*/
+ /*Should Probably send back a negative acknowledgement*/
+
+ return(OK);
+}
+\f
+
+int
+a1_15(pe) /*ASR in state 2B (Assoc. awaiting target) */
+PE pe;
+{
+ PE p;
+
+ vrsl = -1;
+ for(p = first_member(pe); p; p = next_member(pe,p) )
+ {
+ if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+ {
+ if( (vrsl = prim2num(p)) == NOTOK)
+ invalid_result ("a1_15", p);
+ break;
+ }
+ }
+ if(vrsl < 0)
+ adios(NULLCP,"a1_15: no result field");
+ if(vrsl == FAILURE)
+ {
+ clear_vte();
+ state = S1_01;
+ return(FAILURE); /*Notify user of ASR (VASScnf)*/
+ }
+ else
+ {
+
+ /*Set draft-VTE param. according to list in primitive or protocol
+ /*element (SetVTPmV(L)).
+ /*Set status of draft-VTE params. listed in primitive or protocol
+ /*element to defined (SetVTPmSDe(L))
+ /*Set current-VTE from draft-VTE (SetCuVTE) */
+
+ vena = 1;
+ waci = 1;
+ if(vrsl == SUCCESS)
+ {
+ sector = 5;
+ state = S5_400B;
+ }
+ else state = S1_10B;
+ }
+ return(SUCCESS); /*Notify user of ASR (VASScnf)*/
+}
+\f
+int
+a1_16(pe) /*ASR in state 2S (Assoc. awaiting target) */
+PE pe;
+{
+ PE p;
+
+ vrsl = -1;
+ for(p = first_member(pe); p; p = next_member(pe,p) )
+ {
+ if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,2) )
+ {
+ if( (vrsl = prim2num(p)) == NOTOK)
+ invalid_result ("a1_16", p);
+ break;
+ }
+ }
+ if(vrsl < 0)
+ adios(NULLCP,"a1_16: no result field");
+ if(vrsl == FAILURE)
+ {
+ clear_vte();
+ state = S1_01;
+ return(FAILURE); /*Notify user of ASR (VASScnf)*/
+ }
+ else
+ {
+
+ /*Set draft-VTE param. according to list in primitive or protocol
+ /*element (SetVTPmV(L)).
+ /*Set status of draft-VTE params. listed in primitive or protocol
+ /*element to defined (SetVTPmSDe(L))
+ /*Set current-VTE from draft-VTE (SetCuVTE) */
+
+ vena = 1;
+ if(vrsl == SUCCESS)
+ {
+ sector = 5;
+ if(vtok) state = S5_40T;
+ else state = S5_40N;
+ }
+ else
+ {
+ if(vtok) state = S1_10T;
+ else state = S1_10N;
+ }
+ }
+ return(SUCCESS); /*Notify user of ASR (VASScnf) */
+}
+\f
+
+int
+a1_17(pe) /*ASQ in state 01 (No Association)*/
+PE pe;
+{
+
+ int result;
+
+ result = read_asq(pe); /*Unpack ASQ*/
+ if(result == PROFILE_NG)
+ {
+ (void)send_bad_asr(PROFILE_NG); /*Send Failure ASR with reason*/
+ return(NOTOK);
+ }
+ if(result == 0)
+ {
+ (void)send_bad_asr(0); /*Send failure ASR w/ no reason*/
+ return(NOTOK);
+ }
+
+ /*SetVTPmS(P)*/
+ /*SetVTPmV(P)*/
+ dr_pm_st = DEFINED;
+ vsmd = 0;
+ vtok = 1; /*For Telnet & transparent profiles*/
+ if(vsmd) state = S1_03S; /*If S-Mode*/
+ else state = S1_03B;
+ result = vassind(pe); /*doesn't really use pe but for consistency
+ with version 1*/
+ return(result);
+}
+\f
+
+int
+a1_18(pe) /*UDQ (uncontrolled data) in 51T (Release Awaiting Peer)*/
+PE pe;
+{
+ vdatind(SEQUENCED,pe); /*Want to do VDATind-h but this is all that's
+ now available*/
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_19(pe) /*GTQ in 10N or VRTQreq in 10T*/
+PE pe;
+{
+ vtok = TRUE;
+ vgvt_ind(); /*VGVTind -- Tell user we have token (as if he cares)*/
+ state = S1_10T;;
+ return(OK);
+}
+\f
+
+int
+a1_20(pe) /*RLR (Release Response) in 51Q or 51T (Release Awaiting Peer)*/
+PE pe;
+{
+
+ PE p;
+
+ vrsl = -1;
+ for(p = first_member(pe); p; p = next_member(pe,p) )
+ {
+ if(PE_ID(p->pe_class,p->pe_id) == PE_ID(PE_CLASS_CONT,0) )
+ /*If result element*/
+ {
+ if( (vrsl = prim2num(p)) == NOTOK)
+ invalid_result ("a1_20", p);
+ break;
+ }
+ }
+ if(vrsl < 0) /*if no result field*/
+ adios(NULLCP,"a1_20: no result field");
+ if(vrsl == SUCCESS)
+ {
+ /*VRELcnf -- Confirm the release to user -- for now, use the
+ original mechanism (closing TELNET) -- should be changed
+ especially for forms mode*/
+
+ vrelcnf();
+ if(vnt > 0)
+ /*Should never happen until Quarantined Delivery
+ supported*/
+ {
+ /*VDATind-n(Vnt)*/
+ vnt = 0;
+ }
+ clear_vte();
+ state = S1_01;
+ }
+ else /*Release Failed*/
+ {
+ if(vena)
+ {
+ sector = 5;
+ if(vsmd) state = S5_40T;
+ else state = S5_400B;
+ }
+ else
+ {
+ if(vsmd) state = S1_10T;
+ else state = S1_10B;
+ }
+ }
+ return(OK);
+}
+\f
+
+int
+a1_21(pe) /*DLQ (Deliver Request) in 50B or 51Q (Release Awaiting Peer)*/
+PE pe;
+{
+ if( (vra = prim2flag(pe)) == NOTOK)
+ adios(NULLCP,"a1_21: incorrect DLQ");
+ if(vra)
+ {
+ vrsl = FAILURE;
+ vrea = COLL_DET;
+ /*VRELcnf required in spec but there's really nothing to tell
+ the user*/
+ }
+ if(vnt > 0) /*Should not happen unless Quarantine Delivery supported*/
+ {
+ /*VDATind-n(Vnt)*/
+ vnt = 0;
+ }
+ vdelind(pe,vra); /*Also irrelevant without Quarantine*/
+ if(vra)
+ {
+ sector = 5;
+ state = S5_402B;
+ }
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_22(pe) /*RLQ (Release Request) in 50B*/
+PE pe;
+{
+
+ vrsl = FAILURE;
+ vrea = COLL_DET;
+ /*VRELcnf -- Confirm to user telling of failure due to collision --
+ but user can't do anything now anyway. */
+
+ if(vnt > 0) /*Shouldn't happen without Quarantine Delivery Ctrl*/
+ {
+ /*VDATind-n(Vnt)*/
+ vnt = 0;
+ }
+ (void)vrelind(); /*Tell user that peer requested release*/
+ state = S1_51R;
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_23(pe) /*SNQ (Start negotiation) in 50B*/
+PE pe;
+{
+ /*Switch Negotiation not implemented.
+ Should probably send back negative acknowledgement. */
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_24(pe) /*SPQ (Switch Profile Request) in state 50B*/
+PE pe;
+{
+ /*Profile Switch not implemented.
+ Should probably send back negative acknowledgement. */
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_25(pe) /*RLQ (Release Request) in 10B (Environment not agreed) */
+PE pe;
+{
+ (void)vrelind();
+ state = S1_51R;
+ return(OK);
+}
+
+/* ARGSUSED */
+int
+a1_26(pe) /*RLQ (Release Request) in state 10N*/
+PE pe;
+{
+ (void)vrelind();
+ state = S1_51R;
+ return(OK);
+
+}
+\f
+
+/* ARGSUSED */
+int
+a1_27(pe) /*RTQ (Request Token) in state 10T*/
+PE pe;
+{
+ vrtq_ind(); /*Tell Application that peer requested token*/
+
+ /*Probably some ISODE call to give token directly instead of telling
+ user */
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_28(pe) /*SNQ (Start Negotiation) in 10N*/
+PE pe;
+{
+ /*MIN not implemented.
+ Need to return NAK. */
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_29(pe) /*SNQ (Start Negotiation) in 10B*/
+PE pe;
+{
+ /*MIN not implemented.
+ Need to send NAK to peer. */
+
+ return(OK);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_30(pe) /*SPQ (Switch Profile Request) in 10B & 10N*/
+PE pe;
+{
+ /*Switch Profile not implemented.
+ Should send NAK to peer. */
+
+ return(OK);
+}
+
+\f
+/* ARGSUSED */
+
+int
+a1_100(pe) /*APQ (VT-P-ABORT -- Abort from VTPM) in any state*/
+PE pe;
+{
+ state = S1_01; /*For rigor*/
+ adios(NULLCP, "protocol abort -- association terminated");
+}
+
+\f
+/* ARGSUSED */
+
+int
+a1_101(pe) /*AUQ (VT-U-ABORT -- Abort from VT User) in any state*/
+PE pe;
+{
+ state = S1_01;
+ adios(NULLCP,"user abort -- association terminated");
+}
+
+\f
+
+/* ARGSUSED */
+int
+a1_102(pe) /*VUABreq (Abort by User) in any state*/
+PE pe;
+{
+
+ PE pe_auq;
+ char *reason = "Association Closed by User";
+
+ pe_auq = str2prim(reason,strlen(reason),PE_CLASS_CONT,AUQ_PDU);
+ if(pe_auq == NULLPE)
+ adios(NULLCP, "a1_102: AUQ build failure (out of memory)");
+ if(AcUAbortRequest(sd,&pe_auq,1,aci) == NOTOK)
+ acs_adios (&aci -> aci_abort, "A-ABORT.REQUEST");
+ state = S1_01;
+
+ finalbye ();
+ exit(1);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_103(pe) /*VTAB (Irrecoverable exception condition) in any state*/
+PE pe;
+{
+
+ PE pe_apq;
+
+ advise(LLOG_NOTICE,NULLCP, "Irrecoverable Exception Condition -- Aborting\n");
+ pe_apq = num2prim((integer)1,PE_CLASS_CONT,APQ_PDU);
+ /*1 is value for Local Error. 0 if for Protocol
+ Error. Assume 1 for now. */
+ if(pe_apq == NULLPE)
+ adios(NULLCP,"a1_103: APQ build failure (out of memory)");
+ if(AcUAbortRequest(sd,&pe_apq,1,aci) == NOTOK)
+ acs_adios (&aci -> aci_abort, "A-ABORT.REQUEST");
+
+ state = S1_01; /*For completeness*/
+
+ finalbye ();
+ exit(1);
+}
+\f
+
+/* ARGSUSED */
+int
+a1_107(pe) /*Generic Action*/
+PE pe;
+{
+ /*Stay in this state*/
+ return(OK);
+}
+
--- /dev/null
+/* actions5.c - VTPM: FSM sector 5 actions */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/actions5.c,v 7.1 91/02/22 09:47:54 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/actions5.c,v 7.1 91/02/22 09:47:54 mrose Interim $
+ *
+ *
+ * $Log: actions5.c,v $
+ * Revision 7.1 91/02/22 09:47:54 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:27 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+#include "sector1.h"
+
+/************************************************************************/
+/* This file contains the functions that are executed when the */
+/* VT Protocol machine is in a Sector 5 state and a protocol */
+/* event occurs. The state transition matrix is specified in */
+/* Table 32 of ISO 9041 (July 1987 version). The actions which */
+/* this collection of functions perform are specified in Table 40 */
+/* of ISO 9041. */
+/************************************************************************/
+
+extern int sd; /*Global Session Descriptor (ISODE) */
+
+ /* xx1x xxxx = awaiting ack from peer i.e., 420 */
+ /* xxxx xx1x = awaiting ack from user */
+
+ /* T = got token, N = no got token */
+
+
+ /*
+ req: usr==>vtpm
+ ind: vtpm==>usr
+ */
+int
+ce_104(pe) /* common event 104 */
+PE pe;
+{
+ /* if (vnt > 0) */
+ if(pe != NULLPE) vdatind(SEQUENCED,pe);
+ vnt = 0;
+ return(OK);
+}
+
+int
+ce_105() /* common event 105 */
+{
+ /* if (vns > 0) for(... */
+ if(p_ondq != NULLPE)
+ (void)p_data(p_ondq); /* send NDQ */
+ vns = 0;
+ return(OK);
+}
+
+
+/* ARGSUSED */
+int
+a5_0(pe) /*VDATreq-sqtr in states 400B or 402B */
+ /* V data request addressing sequenced trigger co */
+PE pe;
+{
+ return(ce_105());
+/*
+ ==> SAMESTATE;
+*/
+}
+
+
+/* ARGSUSED */
+int
+a5_1(pe) /*VDATreq-n in states 400B, 402B or 40T */
+ /* V data request addressing sequenced trigger co */
+PE pe;
+{
+
+ /*
+ vns++;
+ ==> SAMESTATE
+ */
+ return(ce_105()); /*Autonomous Event to Ship it*/
+}
+
+
+int
+a5_2(pe) /*NDQ-tr in states 400B, 420B */
+PE pe;
+{
+ /*
+ vnt++;
+ */
+
+ return(ce_104(pe));
+ /*
+ ==> SAMESTATE
+ */
+}
+
+
+int
+a5_3(pe) /*NDQ-ntr in states 400B, 420B */
+PE pe;
+{
+ /*
+ vnt++;
+ */
+ /*
+ ==> SAMESTATE
+ */
+ return(ce_104(pe)); /*Autonomous Event to Deliver to User*/
+}
+
+int
+a5_5(pe) /* VBRKreq */
+PE pe;
+{
+ vtok = 0; /* giving the token away */
+ vnt = 0;
+ vns = 0;
+ /* vtkp was set in vbrkreq so it could be coded in to the pe */
+ (void)p_resync_req(pe,SYNC_RESTART); /* send break request */
+ state = S5_61;
+ return(OK);
+}
+
+int
+a5_6(pe) /* VBRKrsp in state 62 */
+PE pe;
+{
+ (void)p_resync_resp(pe); /* send out break response */
+ if (vsmd && vtok)
+ state = S5_40T;
+ else
+ if (vsmd)
+ state = S5_40N;
+ else {
+ vtkp = INITIATOR;
+ if (vtok)
+ vtkp = ACCEPTOR;
+ state = S5_400B;
+ }
+ return(OK);
+}
+
+int
+a5_9(pe) /*VDELreq in states 400B, 402B */
+PE pe;
+{
+ if (dcno) /* no delivery control */
+ {
+ advise(LLOG_DEBUG,NULLCP,"a5_9: dcno hasn't been set");
+ /* ==> SAMESTATE */
+ return(NOTOK);
+ }
+ (void)ce_105();
+ /* send out dlq */
+ /* this will be replace by the new-fangled pepy schtuff;
+ will use this now for compatability */
+
+ (void)p_data(pe);
+ state = (vra) ? state + 2 : state; /* pretty neeto eh? */
+ return(OK);
+}
+
+int
+a5_11(pe) /*HDQ request in 400B*/
+PE pe;
+{
+ (void) p_typed_data(pe);
+ return(OK);
+}
+
+/*ARGSUSED*/
+int
+a5_17(pe) /*VRELreq in states 400B */
+PE pe;
+{
+/* ce_105(); */
+ sector = 1;
+ if(vtok)
+ {
+ state = S1_51Q; /*Must change state first because
+ vt_disconnect gets RLR & calls
+ state machine again. */
+ vt_disconnect(); /*May be only TEMP*/
+ }
+ else
+ {
+ request_token();
+ /*Need call to ISODE to request token*/
+ state = S1_50B;
+ }
+
+ return(OK);
+}
+
+int
+a5_28(pe) /*UDQ request in 400B*/
+PE pe;
+{
+ (void) p_typed_data(pe);
+ return(OK);
+}
+
+int
+a5_31(pe) /* BKR in 61 */
+PE pe;
+{
+ if (vsmd && vtok) state = S5_40T;
+ else if (vsmd) state = S5_40N;
+ else state = S5_400B;
+ vbrkcnf(pe);
+ return(OK);
+}
+
+int
+a5_32(pe) /* BKQ could occur in any state except 62 */
+PE pe;
+{
+ vnt = 0;
+ vns = 0;
+ /*
+ vbrkind clears queues etc.
+ and then map the break character to user
+ and sets vtok to 1
+ (we should have received the token)
+ */
+ state = S5_62;
+ vbrkind(pe);
+ return(OK);
+}
+
+int
+a5_34(pe) /*UDQ in 400B*/
+PE pe;
+{
+ if(pe != NULLPE) vudatind(pe);
+ return(OK);
+}
+
+int
+a5_35(pe) /* DEL in states 400B, 420B */
+PE pe;
+{
+
+ if ((vra = prim2flag(pe)) == NOTOK)
+ adios("a5_35: bogus PDU (%s)", pe_error (pe -> pe_errno));
+ (void)ce_104(NULLPE);
+ vdelind(pe,vra);
+ state = (vra) ? state + 2 : state;
+ return(OK);
+}
+
+
+int
+a5_38(pe) /* RLQ in states 400B */
+PE pe;
+{
+
+ (void)ce_104(pe);
+ sector = 1;
+ state = S1_51R;
+ (void)vrelind();
+ return(OK);
+}
+
+int
+a5_106(pe)
+PE pe;
+{
+ if(pe != NULLPE) vhdatind(pe);
+ return(OK);
+}
--- /dev/null
+-- VTPM: encode/decode BKQ/BKR PDU
+
+-- $Header: /f/osi/vt/RCS/bk_content.py,v 7.1 91/02/22 09:47:55 mrose Interim $
+--
+--
+-- $Log: bk_content.py,v $
+-- Revision 7.1 91/02/22 09:47:55 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:28 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+VT DEFINITIONS ::=
+%{
+
+#include "vtpm.h"
+#include "sector5.h"
+#include <stdio.h>
+
+#undef PEPYPARM
+#define PEPYPARM int *
+%}
+
+BEGIN
+
+SECTIONS build unbuild none
+
+----------------------------------------------------------------------------
+
+BKQ-pdu ::= CHOICE <<1>>
+
+{
+ bkqpdu[8] IMPLICIT BKQcontent [[p (PEPYPARM)parm]]
+}
+
+BKR-pdu
+::= CHOICE <<1>>
+{
+ bkrpdu[9] IMPLICIT BKRcontent [[p (PEPYPARM)parm]]
+}
+
+ExplicitPointer
+%{
+ EXPL_PTR *arg = (EXPL_PTR *)parm;
+%}
+ ::= SEQUENCE
+{
+ x [0] IMPLICIT INTEGER
+ [[i arg->xval ]]
+ OPTIONAL <<arg->xval != NULLCOORD>>,
+ y [1] IMPLICIT INTEGER
+ [[i arg->yval ]]
+ OPTIONAL <<arg->yval != NULLCOORD>>,
+ z [2] IMPLICIT INTEGER
+ [[i arg->zval ]]
+ OPTIONAL <<arg->zval != NULLCOORD>>
+}
+
+--------------------------------------------------------------------------------
+
+BKQcontent
+%{
+ BRcnt *arg = (BRcnt *)parm;
+%}
+ ::= SEQUENCE
+{
+ token INTEGER [[i arg->BKQcont.token_val]]
+ {
+ initiator(0),
+ acceptor (1),
+ accChoice(2)
+ }
+ OPTIONAL <<arg->BKQcont.token_val != NOBKTOK >>,
+ ExplicitPointer [[p (PEPYPARM)&(arg->BKQcont.ExplPtr)]]
+}
+
+
+--------------------------------------------------------------------------------
+
+BKRcontent
+%{
+ BRcnt *arg = (BRcnt *)parm;
+%}
+ ::= SEQUENCE
+{
+ token INTEGER [[i arg->BKRcont.token_val]]
+ {
+ initiator(0),
+ acceptor (1)
+ }
+ OPTIONAL <<arg->BKRcont.token_val != NOBKTOK >>,
+
+ ExplicitPointer [[p (PEPYPARM)&(arg->BKRcont.ExplPtr)]]
+}
+
+
+--------------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+
+END
+
--- /dev/null
+/* eventmsg.h - VTPM: states */
+
+/*
+ * $Header: /f/osi/vt/RCS/eventmsg.h,v 7.1 91/02/22 09:47:56 mrose Interim $
+ *
+ *
+ * $Log: eventmsg.h,v $
+ * Revision 7.1 91/02/22 09:47:56 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:29 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+char *eventname[] = {
+ "* NOT USED *",
+ "VASSreq",
+ "VASSrsp",
+ "VBRKreq",
+ "VBRKrsp",
+ "VDACKreq",
+ "VDATreq_u",
+ "VDATreq_h",
+ "VDATreq_n",
+ "VDATreq_sqtr",
+ "VDELreq",
+ "VENEGreq",
+ "VENEGrsp",
+ "VGVTreq",
+ "VNACCreq",
+ "VNINVreq",
+ "VNOFFreq",
+ "VNREJreq",
+ "VRELreq",
+ "VRELrsp",
+ "VRQTreq",
+ "VSNEQreq",
+ "VSNEQrsp",
+ "VSWPreq",
+ "VSWPrsp",
+ "VUABreq",
+ "APQ",
+ "ASQ",
+ "ASR",
+ "AUQ",
+ "BKQ",
+ "BKR",
+ "DAQ",
+ "DLQ",
+ "EDQ",
+ "ENQ",
+ "ENR",
+ "GTQ",
+ "NAQ",
+ "NDQ_ntr",
+ "NDQ_tr",
+ "NJQ",
+ "NIQ",
+ "NOQ",
+ "RLQ",
+ "RLR",
+ "RTQ",
+ "SPQ",
+ "SPR",
+ "SNQ",
+ "SNR",
+ "UDQ",
+ "AUTO",
+ "VTAB",
+ "PAB",
+ "VACKind",
+ "VASSind",
+ "VASScnf",
+ "VBRKind",
+ "VBRKcnf",
+ "VDATind_u",
+ "VDATind_h",
+ "VDATind_n",
+ "VDATind_Vnt",
+ "VDELind",
+ "VENEGind",
+ "VENEGcnf",
+ "VGVTind",
+ "VNINVind",
+ "VNOFFind",
+ "VNACCind",
+ "VNREJind",
+ "VPABind",
+ "VRELind",
+ "VRELcnf",
+ "VRQTind",
+ "VSNEGind",
+ "VSNEGcnf",
+ "VSWPind",
+ "VSWPcnf",
+ "VUABind",
+ "NDQseq_ntr",
+ "NDQseq_tr",
+ "NDQ_x_tr",
+ "NDQ_x_ntr"
+ };
--- /dev/null
+: run this script through /bin/sh
+M=/bin/make
+if [ -f /usr/bin/make ]; then
+ M=/usr/bin/make
+fi
+
+exec $M TOPDIR=../ -f ../config/CONFIG.make -f Makefile ${1+"$@"}
--- /dev/null
+/* map.c - VT telnet profile mappings */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/map.c,v 7.2 91/02/22 09:47:58 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/map.c,v 7.2 91/02/22 09:47:58 mrose Interim $
+ *
+ *
+ * $Log: map.c,v $
+ * Revision 7.2 91/02/22 09:47:58 mrose
+ * Interim 6.8
+ *
+ * Revision 7.1 90/07/09 14:51:50 mrose
+ * sync
+ *
+ * Revision 7.0 89/11/23 22:31:31 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#define DO_LOCAL_ECHO
+#undef PEPYPARM
+#define PEPYPARM int *
+
+
+#include "vtpm.h"
+#include "sector1.h"
+
+#include <sys/ioctl.h>
+#ifdef BSD44
+#include <sys/termios.h>
+#endif
+
+extern char erase_char;
+extern char erase_line;
+#ifdef BSD44
+extern struct termios oterm;
+#else
+extern struct sgttyb ottyb;
+extern struct tchars otc;
+#endif
+extern char intr_char;
+extern char ni_image;
+extern char na_image;
+extern char nego_state;
+extern char kb_image;
+extern char di_image;
+extern char sync_image;
+extern char ga_image;
+extern int my_right;
+extern int cur_emode;
+extern char *myhostname;
+extern int pty;
+extern int transparent;
+extern int showoptions;
+extern int debug;
+extern int telnet_profile;
+
+TEXT_UPDATE *ndq_queue, *deq(); /*Incoming (From Net) NDQ's*/
+
+map(ndq) /*Parse the given NDQ (could contain several updates).
+ Pass individual updates to appropriate processing
+ routine.
+ */
+PE ndq;
+{
+
+ TEXT_UPDATE *ud;
+
+ if(unbuild_NDQPDU_NDQpdu(ndq,1,NULLIP,NULLVP,(PEPYPARM)0) == NOTOK)
+ {
+ advise (LLOG_NOTICE,NULLCP, "NDQ parse failure (%s)", PY_pepy);
+ return;
+ }
+ while(ud = deq(&ndq_queue) )
+ {
+ if(ud->type_sw == DISPLAY_OBJ)
+ {
+ display_ud(&ud->updates.do_list);
+ free((char *)ud->updates.do_list.do_name);
+ }
+ else if(ud->type_sw == CTRL_OBJ)
+ {
+ control_ud(&ud->updates.co_list);
+ free((char *)ud->updates.co_list.co_name);
+ }
+ else
+ advise(LLOG_NOTICE,NULLCP, "Invalid Update");
+ free((char *)ud);
+ }
+ pe_free(ndq);
+}
+
+\f
+display_ud(doptr) /*Handle Display Updates*/
+DO_UPDATE *doptr;
+{
+
+ int i;
+ char *pt;
+#ifdef BSD44
+ struct termios term;
+#else
+ struct sgttyb ttyb;
+#endif
+
+ switch(doptr->do_type) {
+
+ case DO_NEXT_X:
+ if(putch('\r') == NOTOK) {
+ if(debug)
+ advise(LLOG_NOTICE,NULLCP, "DROPPED CHAR");
+ return;
+ }
+
+ if(my_right == INITIATOR) {
+ if(putch('\n') == NOTOK) /*Current Telnet only gives
+ CR to PTY*/
+ {
+ advise(LLOG_NOTICE,NULLCP, "DROPPED CHAR");
+ return;
+ }
+ }
+ break;
+
+ case DO_NEXT_Y:
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Next Y Array");
+ break;
+
+ case DO_PTR_REL: /*Ignore for TELNET since next update must
+ be erase. */
+ break;
+
+ case DO_PTR_ABS: /*Ignore for TELNET since must have been
+ preceeded by erase line. */
+ break;
+
+ case DO_TEXT:
+ for(pt = doptr->do_cmd.text_ud.text_ptr, i = 0;
+ i < doptr->do_cmd.text_ud.text_count; ++pt,++i)
+ {
+ if(putch(*pt) == NOTOK)
+ {
+ advise(LLOG_NOTICE,NULLCP, "DROPPED CHAR");
+ return;
+ }
+ }
+ free(doptr->do_cmd.text_ud.text_ptr);
+ break;
+
+ case DO_RPT_TEXT:
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Repeat Text");
+ break;
+
+ case DO_ATTR:
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Write Attribute");
+ attrib_hdlr(doptr);
+ break;
+
+ case DO_ERASE:
+ if((doptr->do_cmd.erase.start_erase.ptr_type == 0) &&
+ (doptr->do_cmd.erase.end_erase.ptr_type == 0) )
+ {
+ if(my_right == ACCEPTOR)
+ {
+#ifdef BSD44
+ if (tcgetattr(pty, &term) == -1)
+ perror("ioctl");
+ else
+ (void)putch(erase_char=term.c_cc[VERASE]); /* XXX what if _POSIX_VDISABLE */
+#else
+ if (ioctl(pty,TIOCGETP,(char*)&ttyb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ (void)putch(ttyb.sg_erase);
+ erase_char = ttyb.sg_erase;
+#endif
+ }
+ else (void)putch(erase_char);
+ }
+ else if((doptr->do_cmd.erase.start_erase.ptr_type == 3) &&
+ (doptr->do_cmd.erase.end_erase.ptr_type == 6))
+ {
+ if(my_right == ACCEPTOR)
+ {
+#ifdef BSD44
+ if (tcgetattr(pty, &term) == -1)
+ perror("ioctl");
+ else
+ (void)putch(erase_line=term.c_cc[VKILL]); /* XXX what if _POSIX_VDISABLE */
+#else
+ if (ioctl(pty,TIOCGETP,(char*)&ttyb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ (void)putch(ttyb.sg_kill);
+ erase_line = ttyb.sg_kill;
+#endif
+ }
+ else (void)putch(erase_line);
+ }
+ break;
+
+ case DO_PREV_X:
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Previous X-Array\n");
+ break;
+
+ case DO_PREV_Y:
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Previous Y-Array\n");
+ break;
+ } /*End Switch*/
+}
+\f
+
+control_ud(coptr) /*Handle Control Object Updates*/
+CO_UPDATE *coptr;
+{
+
+ char active = 0;
+#ifdef BSD44
+ struct termios term;
+#else
+ struct sgttyb sb;
+#endif
+
+ if(!telnet_profile)
+ {
+ if((my_right == INITIATOR) && (!strcmp(coptr->co_name,"E")))
+ /*The Echo Control Object in Default Profile is WACA*/
+ def_echo(coptr);
+ else
+ advise(LLOG_NOTICE,NULLCP, "Received Invalid CO Update under Default Profile\n");
+ return;
+ }
+ if(coptr->co_type != 1) /*Only Booleans allowed in TELNET*/
+ {
+ advise(LLOG_NOTICE,NULLCP, "Invalid CO Type\n");
+ return;
+ }
+ if(coptr->co_cmd.bool_update.mask_count == 0) active = 0xff;
+ else active = *coptr->co_cmd.bool_update.mask;
+
+ if(my_right == INITIATOR)
+ {
+ if(!strcmp(coptr->co_name,"DI") )
+ {
+ if(active & AYT_OBJ)
+ /*If This CO contains potential update to Are You There bit*/
+ {
+ if( (di_image & AYT_OBJ) !=
+ (AYT_OBJ & *coptr->co_cmd.bool_update.value))
+ /*If this bit was toggled*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled AYT in DI\n");
+ di_image ^= AYT_OBJ; /*Save the new value*/
+ }
+ }
+ if(active & AO_OBJ)
+ /*If potential update to Abort Output bit*/
+ {
+ if( (di_image & AO_OBJ) !=
+ (AO_OBJ & *coptr->co_cmd.bool_update.value))
+ /*Toggled AO bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled AO in DI\n");
+ di_image ^= AO_OBJ; /*Record it*/
+ }
+ }
+ if(active & IP_OBJ)
+ /*If potential update to Interrupt Process bit*/
+ {
+ if( (di_image & IP_OBJ) !=
+ (IP_OBJ & *coptr->co_cmd.bool_update.value))
+ /*Toggled AO bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled IP in DI/n");
+ di_image ^= IP_OBJ;
+ }
+ }
+ if(active & DM_OBJ)
+ {
+ if( (di_image & DM_OBJ) !=
+ (DM_OBJ & *coptr->co_cmd.bool_update.value) )
+
+ /*Toggled DM Bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled DM in DI\n");
+ di_image ^= DM_OBJ;
+ }
+ }
+ if(active & BRK_OBJ)
+ {
+ if( (di_image & BRK_OBJ) !=
+ (BRK_OBJ & *coptr->co_cmd.bool_update.value) )
+ /*Toggled Break Bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled BRK in DI\n");
+ di_image ^= BRK_OBJ;
+ }
+ }
+ }
+ else if( !strcmp(coptr->co_name,"NA") )
+ {
+ if(active & ECHO_OBJ)
+ /*Update to Echo Control Object*/
+ {
+ if(ECHO_OBJ & *coptr->co_cmd.bool_update.value)
+ /*Request from Server for Remote Echo*/
+ {
+ na_image |= ECHO_OBJ;
+ if(showoptions)
+ (void)printf("Remote Echo Update Received\r\n");
+ if(ECHO_OBJ & nego_state) /*If now in Remote Echo*/
+ {
+ if(ni_image & ECHO_OBJ) /*No request outstatnding*/
+ {
+ if(showoptions)
+ (void)printf("Server Request ignored--Now in Remote echo\r\n");
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Request for Local Echo Denied by Server\r\n");
+ ni_image |= ECHO_OBJ;
+ }
+ }
+ else /*Else Not in Remote Echo*/
+ {
+ if(ni_image & ECHO_OBJ) /*I Requested Remote Echo*/
+ /*This must be confirmation*/
+ {
+ if(showoptions)
+ (void)printf("Server agreed to do Remote Echo\r\n");
+ }
+ else /*Request to do Remote Echo*/
+ {
+ if(showoptions)
+ (void)printf("Server Requested Remote Echo\r\n");
+ ni_image |= ECHO_OBJ;
+ vt_set_nego(ni_image,ECHO_OBJ);/*Respond "WILL"*/
+ }
+ (void) tmode(1);
+ nego_state |= ECHO_OBJ;
+ cur_emode = ECHO_NOW; /*Want Server to Echo*/
+ }
+ }
+ else /*Request from server for Local Echo*/
+ {
+ if(showoptions)
+ (void)printf("NA--Local Echo\r\n");
+ cur_emode = NOT_ECHO_NOW;
+ na_image &= ~ECHO_OBJ;
+ if(nego_state & ECHO_OBJ) /*If now in Remote Echo*/
+ {
+ if(ni_image & ECHO_OBJ) /*If no request pending*/
+ /*Must be request from sender*/
+ {
+ if(showoptions)
+ (void)printf("Server requested Local Echo -- O.K.\r\n");
+ ni_image &= ~ECHO_OBJ;
+ vt_set_nego(ni_image,ECHO_OBJ);/*Respond "WILL"*/
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("User request for Local Echo Accepted\r\n");
+ }
+ nego_state &= ~ECHO_OBJ;
+ /* sb = ottyb;
+ /* sb.sg_flags |= ECHO|CRMOD|CBREAK;
+ /* ioctl(fileno(stdin),TIOCSETP,(char*)&sb);
+ */
+ (void)tmode(2);
+ }
+ else /*Else now in Local Echo*/
+ {
+ if(ni_image & ECHO_OBJ) /*If requeset pending*/
+ /*Must be negative response*/
+ {
+ ni_image &= ~ECHO_OBJ;
+ if(showoptions)
+ (void)printf("Request for Remote Echo Denied by Server\r\n");
+ }
+ else /*Else no request pending*/
+ {
+ if(showoptions)
+ (void)printf("Server Request Ignored--Now in Local Echo\r\n");
+ }
+ }
+ }
+ }
+ if(active & SUP_GA)
+ /*Update to Suppress Go Ahead Control Object*/
+ {
+ if(SUP_GA & *coptr->co_cmd.bool_update.value)
+ {
+ if(showoptions)
+ (void)printf("Suppress Go Ahead\r\n");
+ na_image |= SUP_GA;
+ if((ni_image & SUP_GA) == (nego_state & SUP_GA))
+ /*If no outstanding request from User*/
+ {
+ if(!(nego_state & SUP_GA))
+ /*If not currently in Suppress Go Ahead*/
+ {
+ ni_image |= SUP_GA;
+ vt_set_nego(ni_image,SUP_GA);/*Reply "Will"*/
+ }
+ }
+ nego_state |= SUP_GA;/*Either here now or entering*/
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Go Ahead\r\n");
+ na_image &= ~SUP_GA;
+ if( (ni_image & SUP_GA) == (nego_state & SUP_GA) )
+ /*Must be request from Server*/
+ {
+ ni_image |= SUP_GA;
+ vt_set_nego(ni_image,SUP_GA);/*Reply "Won't"*/
+ }
+ else /*Else response to my request to Suppress*/
+ {
+ if(showoptions)
+ (void)printf("Server refuses to Suppress Go Ahead\r\n");
+ ni_image &= ~SUP_GA; /*Give Up*/
+ /*May want to terminate Association here*/
+ }
+ }
+ }
+ if(active & DISP_BIN)
+ /*Update to WACA Binary Repertoire*/
+ {
+ if(DISP_BIN & *coptr->co_cmd.bool_update.value)
+ {
+ if(showoptions)
+ (void)printf("WACA requested Binary Repertoire on DI\r\n");
+ if((ni_image & DISP_BIN) == (nego_state & DISP_BIN))
+ /*No request outstanding from Initiator*/
+ {
+ if(!(nego_state & DISP_BIN)) /*If not now binary*/
+ {
+ ni_image |= DISP_BIN;
+ vt_set_nego(ni_image,DISP_BIN); /*Send "Will"*/
+ }
+ }
+ nego_state |= DISP_BIN;
+ ni_image |= DISP_BIN;
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("WACA requested ASCII Repertoire on DI\r\n");
+ if((ni_image & DISP_BIN) == (nego_state & DISP_BIN))
+ {
+ if(nego_state & DISP_BIN) /*If not now ASCII*/
+ {
+ ni_image &= ~DISP_BIN;
+ vt_set_nego(ni_image,DISP_BIN);
+ }
+ }
+ nego_state &= ~DISP_BIN;
+ ni_image &= ~DISP_BIN;
+ }
+ }
+ if(active & KBD_BIN)
+ /*Update to WACI Binary Repertoire*/
+ {
+ if(KBD_BIN & *coptr->co_cmd.bool_update.value)
+ {
+ if(showoptions)
+ (void)printf("WACA requested Binary Repertoire on KB\r\n");
+ if((ni_image & KBD_BIN) == (nego_state & KBD_BIN))
+ /*If no initiator request outstanding*/
+ {
+ if(!(nego_state & KBD_BIN))/*If not now binary*/
+ {
+ ni_image |= KBD_BIN;
+ vt_set_nego(ni_image,KBD_BIN); /*Reply "Will"*/
+ switch_rep(2);
+ /*Send Attribute update to use Binary Repertoire*/
+ }
+ }
+ else /*Else a response to Initiator Request*/
+ {
+ if(ni_image & KBD_BIN) /*Positive response*/
+ switch_rep(2);
+ }
+ ni_image |= KBD_BIN;
+ nego_state |= KBD_BIN;
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Acceptor requested ASCII Repertoire on KB\r\n");
+ if((ni_image & KBD_BIN) == (nego_state & KBD_BIN))
+ /*Request from Acceptor*/
+ {
+ if(nego_state & KBD_BIN) /*If not now ASCII*/
+ {
+ ni_image &= ~KBD_BIN;
+ vt_set_nego(ni_image,KBD_BIN); /*Reply "Will"*/
+ switch_rep(1);/*Send Attr to ASCII*/
+ }
+ }
+ else /*Else response to Initiator Request*/
+ {
+ if( !(ni_image & KBD_BIN))/*Positive response*/
+ switch_rep(1);
+ }
+ ni_image &= ~KBD_BIN;
+ nego_state &= ~KBD_BIN;
+ }
+ }
+ }
+ }
+ else /*Else Server (Display) side*/
+ {
+ if(!strcmp(coptr->co_name,"KB") )
+ /*Server receives updates to the Keyboard*/
+ {
+ if(active & AYT_OBJ)
+ /*If This CO contains potential update to Are You There bit*/
+ {
+ if( (kb_image & AYT_OBJ) !=
+ (AYT_OBJ & *coptr->co_cmd.bool_update.value))
+ /*If this bit was toggled*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled AYT in KB");
+ kb_image ^= AYT_OBJ; /*Save the new value*/
+ if (vt_text("[associated with terminal service on ", strlen("[associated with terminal service on ")) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ if (vt_text(myhostname,strlen(myhostname)) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ if (vt_text("]\r\n",3) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ vtsend();
+ }
+ }
+ if(active & AO_OBJ)
+ /*If potential update to Abort Output bit*/
+ {
+ if( (kb_image & AO_OBJ) !=
+ (AO_OBJ & *coptr->co_cmd.bool_update.value))
+ /*Toggled AO bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled AO in KB");
+ kb_image ^= AO_OBJ; /*Record it*/
+ }
+ }
+ if(active & IP_OBJ)
+ /*If potential update to Interrupt Process bit*/
+ {
+ if( (kb_image & IP_OBJ) !=
+ (IP_OBJ & *coptr->co_cmd.bool_update.value))
+ /*Toggled IP bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled IP in KB");
+ kb_image ^= IP_OBJ;
+ kill_proc();
+ }
+ }
+ if(active & DM_OBJ)
+ {
+ if( (kb_image & DM_OBJ) !=
+ (DM_OBJ & *coptr->co_cmd.bool_update.value))
+ {
+ /*Toggled DM BIt*/
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled DM in KB");
+ kb_image ^= DM_OBJ;
+ }
+ }
+ if(active & BRK_OBJ)
+ /*If potential update to Break Bit*/
+ {
+ if( (kb_image & BRK_OBJ) !=
+ (BRK_OBJ & *coptr->co_cmd.bool_update.value))
+ /*Toggled BREAK bit*/
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled BREAK in KB");
+ kb_image ^= BRK_OBJ;
+ kill_proc();
+ }
+ }
+ }
+ else if( !strcmp(coptr->co_name,"NI") )
+ {
+ if(active & ECHO_OBJ)
+ /*Update to Echo Control Object*/
+ {
+ if(ECHO_OBJ & *coptr->co_cmd.bool_update.value)
+ /*Request from User for Remote Echo*/
+ {
+ ni_image |= ECHO_OBJ;
+ if(showoptions)
+ (void)printf("Remote Echo Update Received\n");
+ if(ECHO_OBJ & nego_state) /*If now in Remote Echo*/
+ {
+ if(na_image & ECHO_OBJ) /*No request outstatnding*/
+ advise(LLOG_NOTICE,NULLCP, "User Request ignored--Now in Remote echo");
+ else /*Must be user's response to a request*/
+ {
+ if(showoptions)
+ (void)printf("Request for Local Echo Denied by User\n");
+ na_image |= ECHO_OBJ;
+ }
+ }
+ else /*Else Not in Remote Echo*/
+ {
+ if(na_image & ECHO_OBJ) /*I Requested Remote Echo*/
+ /*This must be confirmation*/
+ {
+ if(showoptions)
+ (void)printf("User agreed to do Remote Echo\n");
+ }
+ else /*Request to do Remote Echo*/
+ {
+ if(showoptions)
+ (void)printf("User Requested Remote Echo--O.K.\n");
+ na_image |= ECHO_OBJ;
+ vt_set_nego(na_image,ECHO_OBJ);/*Respond "WILL"*/
+ }
+#ifdef BSD44
+ realptyecho(1);
+#else
+ if (ioctl(pty,TIOCGETP,(char*)&sb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ sb.sg_flags |= ECHO; /*Turn on Echo*/
+ if (ioctl(pty,TIOCSETP,(char*)&sb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+#endif
+ nego_state |= ECHO_OBJ;
+ cur_emode = NOT_ECHO_NOW; /*Don't Want user to Echo*/
+ }
+ }
+ else /*Request from user for Local Echo*/
+ {
+ if(showoptions)
+ (void)printf("NI--Local Echo\n");
+ cur_emode = NOT_ECHO_NOW;
+ ni_image &= ~ECHO_OBJ;
+ if(nego_state & ECHO_OBJ) /*If now in Remote Echo*/
+ {
+ if(na_image & ECHO_OBJ) /*If no request pending*/
+ /*Must be request from user*/
+ {
+
+#ifdef DO_LOCAL_ECHO
+ if(showoptions)
+ (void)printf("User requested Local Echo -- O.K.\n");
+
+ na_image &= ~ECHO_OBJ;
+ nego_state &= ~ECHO_OBJ;
+#ifdef BSD44
+ ptyecho(0);
+#else
+ setmode(0,ECHO);
+#endif
+#else
+ na_image |= ECHO_OBJ;
+ if(showoptions)
+ (void)printf("User requested Local Echo -- Denied\n");
+#endif
+
+ vt_set_nego(na_image,ECHO_OBJ); /*Respond "WILL"*/
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Server request for Local Echo Accepted\n");
+ nego_state &= ~ECHO_OBJ;
+#ifdef BSD44
+ ptyecho(0);
+#else
+ setmode(0,ECHO);
+#endif
+ }
+ }
+ else /*Else now in Local Echo*/
+ {
+ if(na_image & ECHO_OBJ) /*If requeset pending*/
+ /*Must be negative response*/
+ {
+ na_image &= ~ECHO_OBJ;
+ if(showoptions)
+ (void)printf("Request for Remote Echo Denied by User\n");
+ }
+ else /*Else no request pending*/
+ {
+ if(showoptions)
+ (void)printf("User Request Ignored--Now in Local Echo\n");
+ }
+ }
+ }
+ }
+ if(active & SUP_GA)
+ /*Update to Suppress Go Ahead Control Object*/
+ {
+ if(SUP_GA & *coptr->co_cmd.bool_update.value)
+ {
+ if(showoptions)
+ (void)printf("Suppress Go Ahead\n");
+ ni_image |= SUP_GA;
+ if((na_image & SUP_GA) == (nego_state &SUP_GA))
+ /*If no request from Acceptor outstanding*/
+ {
+ if(!(nego_state & SUP_GA))
+ /*If not currently in Supress Go Ahead*/
+ {
+ na_image |= SUP_GA;
+ vt_set_nego(na_image,SUP_GA);/*Reply "Will"*/
+ }
+ }
+ nego_state |= SUP_GA; /*Entering or already there*/
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Don't Suppress Go Ahead\n");
+ ni_image &= ~SUP_GA;
+ if((na_image & SUP_GA) == (nego_state & SUP_GA))
+ /*Must be request from Initiator*/
+ {
+ na_image |= SUP_GA;
+ vt_set_nego(na_image,SUP_GA);/*Reply "Won't"*/
+ }
+ else /*Else reply to my request*/
+ {
+ if(showoptions)
+ (void)printf("User refuses to Suppress Go Ahead\n");
+ na_image &= ~SUP_GA; /*Give up*/
+ }
+ }
+ }
+ if(active & DISP_BIN)
+ /*Update to WACI Binary Repertoire*/
+ {
+ if(DISP_BIN & *coptr->co_cmd.bool_update.value)
+ {
+ if(showoptions)
+ (void)printf("Initiator requested Binary Repertoire on DI\n");
+ if((na_image & DISP_BIN) == (nego_state & DISP_BIN))
+ /*No request outstanding from Acceptor*/
+ {
+ if(!(nego_state & DISP_BIN)) /*If not now binary*/
+ {
+ na_image |= DISP_BIN;
+ vt_set_nego(na_image,DISP_BIN); /*Send "Will"*/
+ switch_rep(2);
+ }
+ }
+ else /*Else a response to Acceptor request*/
+ {
+ if(na_image & KBD_BIN) /*Positive Response*/
+ switch_rep(2);
+ }
+ nego_state |= DISP_BIN;
+ na_image |= DISP_BIN;
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Initiator requested ASCII Repertoire on DI\n");
+ if((na_image & DISP_BIN) == (nego_state & DISP_BIN))
+ {
+ if(nego_state & DISP_BIN) /*If not now ASCII*/
+ {
+ na_image &= ~DISP_BIN;
+ vt_set_nego(na_image,DISP_BIN);
+ switch_rep(1);
+ }
+ }
+ else
+ {
+ if(!(na_image & KBD_BIN)) /*Positive Response*/
+ switch_rep(1);
+ }
+ nego_state &= ~DISP_BIN;
+ na_image &= ~DISP_BIN;
+ }
+ }
+ if(active & KBD_BIN)
+ /*Update to WACI Binary Repertoire*/
+ {
+ if(KBD_BIN & *coptr->co_cmd.bool_update.value)
+ {
+ if(showoptions)
+ (void)printf("Initiator requested Binary Repertoire on KB\n");
+ if((na_image & KBD_BIN) == (nego_state & KBD_BIN))
+ /*If no Acceptor request outstanding*/
+ {
+ if(!(nego_state & KBD_BIN))/*If not now binary*/
+ {
+ na_image |= KBD_BIN;
+ vt_set_nego(na_image,KBD_BIN); /*Reply "Will"*/
+ }
+ }
+ na_image |= KBD_BIN;
+ nego_state |= KBD_BIN;
+ }
+ else
+ {
+ if(showoptions)
+ (void)printf("Initiator requested ASCII Repertoire on KB\n");
+ if((na_image & KBD_BIN) == (nego_state & KBD_BIN))
+ /*Request from Initator*/
+ {
+ if(nego_state & KBD_BIN) /*If not now ASCII*/
+ {
+ na_image &= ~KBD_BIN;
+ vt_set_nego(na_image,KBD_BIN); /*Reply "Will"*/
+ }
+ }
+ na_image &= ~KBD_BIN;
+ nego_state &= ~KBD_BIN;
+ }
+ }
+ }
+ }
+ if( !strcmp(coptr->co_name,"SY") ) /*SYNCHRONIZE CO can be written
+ by Initiator or Acceptor*/
+ {
+ if(active & SYNC)
+ /*Potential Update to Synch*/
+ {
+ if( (SYNC & *coptr->co_cmd.bool_update.value) !=
+ (SYNC & sync_image) )
+ {
+ advise(LLOG_NOTICE,NULLCP, "Toggled SYNC");
+ sync_image ^= SYNC;
+ }
+ }
+ }
+ if( !strcmp(coptr->co_name,"GA") )
+ {
+ if(active & GO_AHEAD)
+ /*Potential Update to Go Ahead*/
+ {
+ if( (GO_AHEAD & *coptr->co_cmd.bool_update.value) !=
+ (GO_AHEAD & ga_image) )
+ {
+ if(debug)
+ advise(LLOG_DEBUG,NULLCP, "Toggled Go Ahead");
+ ga_image ^= GO_AHEAD;
+ }
+ }
+ }
+
+}
+\f
+attrib_hdlr(doptr) /*Handle Write Attribute Display Object Update*/
+DO_UPDATE *doptr;
+{
+
+
+ if(doptr->do_cmd.wrt_attrib.attr_id == 0)
+ /*If switching repertoires*/
+ {
+ if(doptr->do_cmd.wrt_attrib.attr_ext == 2)
+ /*If Modal extent*/
+ {
+ if(doptr->do_cmd.wrt_attrib.attr_val == 1)
+ {
+ if(showoptions)
+ if(my_right == INITIATOR)
+ (void)printf("Switching to ASCII Repertoire\r\n");
+ transparent = 0;
+ }
+ else if(doptr->do_cmd.wrt_attrib.attr_val == 2)
+ {
+ if(showoptions)
+ if(my_right == INITIATOR)
+ (void)printf("Switching to Transparent profile.\r\n");
+ transparent = 1;
+ }
+ else (void)printf("Attribute for unavailable repertoire\n");
+ }
+ else (void)printf("Attribute update with invalid extent (%d)\n",
+ doptr->do_cmd.wrt_attrib.attr_ext);
+ }
+ else
+ advise(LLOG_NOTICE,NULLCP, "Attribute Update with invalid I.D. (%d)\n", doptr->do_cmd.wrt_attrib.attr_id);
+}
+
+/* \f TTY */
+
+#ifdef BSD44
+extern struct termios oterm;
+
+int
+tmode(f)
+ int f;
+{
+ static int prevmode = 0;
+ struct termios term;
+ int onoff, old;
+
+ if (prevmode == f)
+ return (f);
+ old = prevmode;
+ prevmode = f;
+ term = oterm;
+ switch (f) {
+ case 0:
+ onoff = 0;
+ break;
+ case 1:
+ case 2:
+ onoff = 1;
+ if (f == 1)
+ {
+ term.c_lflag &= ~ECHO;
+ term.c_oflag &= ~OPOST;
+ }
+ else
+ {
+ term.c_lflag |= ECHO;
+ term.c_oflag |= OPOST;
+ }
+ term.c_lflag &= ~(IEXTEN|ISIG|ICANON);
+ break;
+ default:
+ return old;
+ }
+ if (tcsetattr(fileno(stdin), TCSAFLUSH, &term) == -1)
+ perror("tcsetattr");
+ if (ioctl(fileno(stdin), FIONBIO, (char*)&onoff) == -1) {
+ perror("ioctl");
+ }
+ return (old);
+}
+
+#else
+
+extern struct tchars otc;
+extern struct ltchars oltc;
+extern struct sgttyb ottyb;
+
+/* struct tchars notc = { -1, 3, -1, -1, -1, -1 };*/
+struct tchars notc = {
+ -1, -1, -1, -1, -1, -1 };
+struct ltchars noltc = {
+ -1, -1, -1, -1, -1, -1 };
+
+int
+tmode(f)
+register int f;
+{
+ static int prevmode = 0;
+ struct tchars *tc;
+ struct ltchars *ltc;
+ struct sgttyb sb;
+ int onoff, old;
+
+ if (prevmode == f)
+ return (f);
+ old = prevmode;
+ prevmode = f;
+ sb = ottyb;
+ switch (f) {
+
+ case 0:
+ onoff = 0;
+ tc = &otc;
+ ltc = &oltc;
+ break;
+
+ case 1:
+ case 2:
+ if (f == 1)
+ {
+ sb.sg_flags |= CBREAK;
+ sb.sg_flags &= ~(ECHO|CRMOD);
+ sb.sg_erase = sb.sg_kill = -1;
+ }
+ else
+ {
+ sb.sg_flags &= CBREAK;
+ sb.sg_flags |= ECHO|CRMOD;
+ }
+ tc = ¬c;
+ notc.t_stopc = otc.t_stopc;
+ notc.t_startc = otc.t_startc;
+ ltc = &noltc;
+ onoff = 1;
+ break;
+
+ default:
+ return old;
+ }
+ if (ioctl(fileno(stdin), TIOCSLTC, (char *)ltc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(fileno(stdin), TIOCSETC, (char *)tc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(fileno(stdin), TIOCSETP, (char *)&sb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(fileno(stdin), FIONBIO, (char*)&onoff) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(fileno(stdout), FIONBIO, (char*)&onoff) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ return (old);
+}
+#endif
+
+kill_proc() /*Terminate current UNIX process using UNIX interrupt char*/
+{
+#ifdef BSD44
+ struct termios term;
+
+ if (tcgetattr(pty, &term) == -1)
+ perror("tcgetattr");
+ else if (term.c_cc[VINTR] != _POSIX_VDISABLE)
+ (void) putch(term.c_cc[VINTR]);
+#else
+ if(ioctl(pty,TIOCGETC,(char *)&otc) == -1)
+ {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ (void) putch(otc.t_intrc);
+#endif
+}
+
+def_echo(coptr) /*Handle Default Profile Echo Ctrl Object*/
+CO_UPDATE *coptr;
+{
+
+ char active = 0;
+
+ if(coptr->co_cmd.bool_update.mask_count == 0) active = 0xff;
+ else active = *coptr->co_cmd.bool_update.mask;
+
+ if (active & ECHO_OBJ) {
+ if(*coptr->co_cmd.bool_update.value & ECHO_OBJ)
+ /*True means do local echo*/
+ (void) tmode(2);
+ else
+ (void) tmode(1);
+ }
+}
+#ifdef BSD44
+static realptyecho(on)
+{
+ struct termios term;
+
+ if (tcgetattr(pty, &term) == -1) {
+ perror("tcgetattr");
+ return;
+ }
+ if (on)
+ term.c_lflag |= ECHO;
+ else
+ term.c_lflag &= ECHO;
+ if (tcsetattr(pty, TCSAFLUSH, &term) == -1) {
+ perror("tcsetattr");
+ return;
+ }
+}
+#endif
--- /dev/null
+-- VTPM: print VT PDUs
+
+-- $Header: /f/osi/vt/RCS/print_vt.py,v 7.1 91/02/22 09:48:00 mrose Interim $
+--
+--
+-- $Log: print_vt.py,v $
+-- Revision 7.1 91/02/22 09:48:00 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:33 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+VT DEFINITIONS ::=
+
+BEGIN
+
+SECTIONS none none print
+
+PDUs ::=
+ CHOICE {
+ asqpdu[0]
+ IMPLICIT ASQcontent,
+
+ asrpdu[1]
+ IMPLICIT ASRcontent,
+
+ ndqpdu[6]
+ IMPLICIT NDQcontent,
+
+ udqpdu[7]
+ IMPLICIT COupdate,
+
+ bkqpdu[8]
+ IMPLICIT BKQcontent,
+
+ bkrpdu[9]
+ IMPLICIT BKRcontent
+ }
+
+ASQcontent ::=
+ SEQUENCE {
+ [0]
+ IMPLICIT INTEGER,
+
+ [1]
+ IMPLICIT ImplemIdent
+ OPTIONAL,
+
+ [2]
+ IMPLICIT BIT STRING,
+
+ [3]
+ IMPLICIT Profile
+ OPTIONAL,
+
+ [4]
+ IMPLICIT BIT STRING,
+
+ [5]
+ IMPLICIT INTEGER
+ OPTIONAL
+ }
+
+ImplemIdent ::=
+ SEQUENCE {
+ impIdent[0]
+ IMPLICIT OBJECT IDENTIFIER
+ OPTIONAL,
+
+ impName[1]
+ IMPLICIT PrintableString
+ OPTIONAL,
+
+ impVersion[2]
+ IMPLICIT PrintableString
+ OPTIONAL
+ }
+
+Profile ::=
+ SEQUENCE {
+ name
+ OBJECT IDENTIFIER
+ OPTIONAL,
+
+ ProfileArgList
+ OPTIONAL
+ }
+
+ProfileArgList ::=
+ SEQUENCE OF
+ CHOICE {
+ specialArgs[0]
+ IMPLICIT SEQUENCE {
+ identifier
+ INTEGER,
+
+ offeredValues
+ CHOICE {
+ boolean[0]
+ IMPLICIT BIT STRING,
+
+ integer[1]
+ IMPLICIT IntOffer,
+
+ string[2]
+ IMPLICIT SET OF
+ PrintableString
+ }
+ },
+
+ vteParams[1]
+ IMPLICIT ParamOfferList
+ }
+
+ParamOfferList ::=
+ SEQUENCE {
+ displayObjects[0]
+ IMPLICIT CDSOffer
+ OPTIONAL,
+
+ controlObjects[1]
+ IMPLICIT CSSOffer
+ OPTIONAL,
+
+ deviceObjects[2]
+ IMPLICIT DEVOffer
+ OPTIONAL,
+
+ deliveryControl[3]
+ IMPLICIT BIT STRING
+ OPTIONAL
+ }
+
+CDSOffer ::=
+ SET OF
+ SEQUENCE {
+ objectName
+ PrintableString,
+
+ ObjectOffer
+ }
+
+CSSOffer ::=
+ NULL
+
+DEVOffer ::=
+ NULL
+
+ObjectOffer ::=
+ SEQUENCE {
+ dimensionOffer[0]
+ IMPLICIT BIT STRING
+ OPTIONAL,
+
+ xParamOffer[1]
+ IMPLICIT DimOffer
+ OPTIONAL,
+
+ yParamOffer[2]
+ IMPLICIT DimOffer
+ OPTIONAL,
+
+ zParamOffer[3]
+ IMPLICIT DimOffer
+ OPTIONAL,
+
+ erasuroffer[4]
+ IMPLICIT BIT STRING
+ OPTIONAL,
+
+ repOfferList[5]
+ IMPLICIT CompRepOffer
+ OPTIONAL,
+
+ empOfferList[6]
+ IMPLICIT CompEmpOffer
+ OPTIONAL,
+
+ foreColorList[7]
+ IMPLICIT ColorOffer
+ OPTIONAL,
+
+ backColorList[8]
+ IMPLICIT ColorOffer
+ OPTIONAL,
+
+ objectAccRight[9]
+ IMPLICIT BIT STRING
+ OPTIONAL
+ }
+
+DimOffer ::=
+ SEQUENCE {
+ bound[0]
+ IMPLICIT SEQUENCE {
+ unbounded
+ NULL
+ OPTIONAL,
+
+ limit
+ IntOffer
+ OPTIONAL
+ }
+ OPTIONAL,
+
+ addressing[1]
+ IMPLICIT BIT STRING
+ OPTIONAL,
+
+ absolute[2]
+ IMPLICIT BIT STRING
+ OPTIONAL,
+
+ window[3]
+ IMPLICIT SEQUENCE {
+ unbounded
+ NULL
+ OPTIONAL,
+
+ limit
+ IntOffer
+ OPTIONAL
+ }
+ OPTIONAL
+ }
+
+CompRepOffer ::=
+ SEQUENCE {
+ repCapability[0]
+ IMPLICIT IntOffer
+ OPTIONAL,
+
+ [1]
+ IMPLICIT SEQUENCE OF
+ RepFontOffer
+ OPTIONAL
+ }
+
+RepFontOffer ::=
+ CHOICE {
+ NULL,
+
+ SEQUENCE {
+ repertoire[0]
+ IMPLICIT PrintableString
+ OPTIONAL,
+
+ fontCapability[1]
+ IMPLICIT IntOffer
+ OPTIONAL,
+
+ [2]
+ IMPLICIT SEQUENCE OF
+ PrintableString
+ OPTIONAL
+ }
+ }
+
+CompEmpOffer ::=
+ SEQUENCE {
+ empCap[0]
+ IMPLICIT IntOffer
+ OPTIONAL,
+
+ SEQUENCE OF
+ PrintableString
+ OPTIONAL
+ }
+
+ColorOffer ::=
+ SEQUENCE {
+ colorCap[0]
+ IMPLICIT IntOffer
+ OPTIONAL,
+
+ colorNames
+ SEQUENCE OF
+ PrintableString
+ OPTIONAL
+ }
+
+IntOffer ::=
+ SEQUENCE OF
+ CHOICE {
+ indivValue[0]
+ IMPLICIT INTEGER,
+
+ range[1]
+ IMPLICIT SEQUENCE {
+ INTEGER,
+
+ INTEGER
+ }
+ }
+
+ASRcontent ::=
+ SEQUENCE {
+ userReason[0]
+ IMPLICIT PrintableString
+ OPTIONAL,
+
+ provReason[1]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ [2]
+ IMPLICIT INTEGER,
+
+ [3]
+ IMPLICIT ImplemIdent
+ OPTIONAL,
+
+ [4]
+ IMPLICIT BIT STRING,
+
+ [5]
+ IMPLICIT ArgumValueList,
+
+ [6]
+ IMPLICIT BIT STRING,
+
+ [7]
+ IMPLICIT INTEGER
+ OPTIONAL
+ }
+
+ArgumValueList ::=
+ SET OF
+ Squat
+
+Squat ::=
+ CHOICE {
+ specArgs[0]
+ IMPLICIT SpecialArgs,
+
+ vteParams[1]
+ IMPLICIT ParamValueList
+ }
+
+SpecialArgs ::=
+ SEQUENCE {
+ identifier
+ INTEGER,
+
+ value
+ CHOICE {
+ BOOLEAN,
+
+ INTEGER,
+
+ PrintableString
+ }
+ }
+
+ParamValueList ::=
+ SEQUENCE {
+ displayObjects[0]
+ IMPLICIT CDSValues
+ OPTIONAL,
+
+ controlObjects[1]
+ IMPLICIT CSSValues
+ OPTIONAL,
+
+ deviceObjects[2]
+ IMPLICIT DEVValues
+ OPTIONAL,
+
+ deliveryControl[3]
+ IMPLICIT INTEGER
+ OPTIONAL
+ }
+
+CDSValues ::=
+ SET OF
+ SEQUENCE {
+ objectName
+ PrintableString,
+
+ ObjectOffer
+ }
+
+CSSValues ::=
+ NULL
+
+DEVValues ::=
+ NULL
+
+DimValue ::=
+ SEQUENCE {
+ bound[0]
+ CHOICE {
+ unbounded
+ NULL,
+
+ limit
+ INTEGER
+ }
+ OPTIONAL,
+
+ addressing[1]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ absolute[2]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ window[3]
+ CHOICE {
+ unbounded
+ NULL,
+
+ limit
+ INTEGER
+ }
+ OPTIONAL
+ }
+
+CompRepValue ::=
+ SEQUENCE {
+ repCapability[0]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ [1]
+ IMPLICIT SEQUENCE OF
+ RepFontValue
+ OPTIONAL
+ }
+
+RepFontValue ::=
+ CHOICE {
+ NULL,
+
+ SEQUENCE {
+ repertoire[0]
+ IMPLICIT PrintableString
+ OPTIONAL,
+
+ fontCapability[1]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ [2]
+ IMPLICIT SEQUENCE OF
+ PrintableString
+ OPTIONAL
+ }
+ }
+
+CompEmpValue ::=
+ SEQUENCE {
+ empCap[0]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ SEQUENCE OF
+ PrintableString
+ OPTIONAL
+ }
+
+ColorValue ::=
+ SEQUENCE {
+ colorCap[0]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ colorNames
+ SEQUENCE OF
+ PrintableString
+ }
+
+NDQcontent ::=
+ SEQUENCE OF
+ VTsdi
+
+VTsdi ::=
+ CHOICE {
+ echoNow[0]
+ IMPLICIT SEQUENCE OF
+ ObjectUpdate,
+
+ notEchoNow[1]
+ IMPLICIT SEQUENCE OF
+ ObjectUpdate
+ }
+
+ObjectUpdate ::=
+ CHOICE {
+ display[0]
+ IMPLICIT SEQUENCE {
+ doName
+ PrintableString,
+
+ SEQUENCE OF
+ DOupdate
+ },
+
+ control[1]
+ IMPLICIT COupdate
+ }
+
+DOupdate ::=
+ CHOICE {
+ nextXarray[0]
+ IMPLICIT NULL,
+
+ nextYarray[1]
+ IMPLICIT NULL,
+
+ ptr-relative[2]
+ IMPLICIT ExplicitPointer,
+
+ ptr-absolute[3]
+ IMPLICIT Pointer,
+
+ text[4]
+ IMPLICIT OCTET STRING,
+
+ repeatText[5]
+ IMPLICIT SEQUENCE {
+ finishAddress
+ Pointer,
+
+ OCTET STRING
+ },
+
+ writeAttr[6]
+ IMPLICIT SEQUENCE {
+ AttrId,
+
+ AttrExtent
+ },
+
+ erase[7]
+ IMPLICIT SEQUENCE {
+ startErase
+ Pointer,
+
+ endErase
+ Pointer,
+
+ eraseAttr
+ BOOLEAN
+ },
+
+ previousXarray[8]
+ IMPLICIT NULL,
+
+ previousYarray[9]
+ IMPLICIT NULL
+ }
+
+COupdate ::=
+ SEQUENCE {
+ coName
+ PrintableString,
+
+ objectUpdate
+ CHOICE {
+ characterUpdate[0]
+ IMPLICIT PrintableString,
+
+ booleanUpdate[1]
+ IMPLICIT SEQUENCE {
+ values[0]
+ IMPLICIT BIT STRING,
+
+ mask[1]
+ IMPLICIT BIT STRING
+ },
+
+ symbolicUpdate[2]
+ IMPLICIT INTEGER,
+
+ integerUpdate[3]
+ IMPLICIT INTEGER,
+
+ bitStringUpdate[4]
+ IMPLICIT BIT STRING
+ }
+ }
+
+ExplicitPointer ::=
+ SEQUENCE {
+ x[0]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ y[1]
+ IMPLICIT INTEGER
+ OPTIONAL,
+
+ z[2]
+ IMPLICIT INTEGER
+ OPTIONAL
+ }
+
+Pointer ::=
+ CHOICE {
+ current[0]
+ IMPLICIT NULL,
+
+ start[1]
+ IMPLICIT NULL,
+
+ startY[2]
+ IMPLICIT NULL,
+
+ startX[3]
+ IMPLICIT NULL,
+
+ end[4]
+ IMPLICIT NULL,
+
+ endY[5]
+ IMPLICIT NULL,
+
+ endX[6]
+ IMPLICIT NULL,
+
+ coords[7]
+ IMPLICIT ExplicitPointer
+ }
+
+AttrId ::=
+ CHOICE {
+ graphCharRep[0]
+ IMPLICIT INTEGER,
+
+ foreColor[1]
+ IMPLICIT INTEGER,
+
+ backColor[2]
+ IMPLICIT INTEGER,
+
+ emphasis[3]
+ IMPLICIT INTEGER,
+
+ font[4]
+ IMPLICIT INTEGER
+ }
+
+AttrExtent ::=
+ CHOICE {
+ global[0]
+ IMPLICIT NULL,
+
+ addrExtent[1]
+ IMPLICIT SEQUENCE {
+ beginning
+ Pointer,
+
+ ending
+ Pointer
+ },
+
+ modalExtent[2]
+ IMPLICIT NULL
+ }
+
+BKQcontent ::=
+ SEQUENCE {
+ token
+ INTEGER {
+ initiator(0),
+ acceptor(1),
+ accChoice(2)
+ }
+ OPTIONAL,
+
+ ExplicitPointer
+ }
+
+BKRcontent ::=
+ SEQUENCE {
+ token
+ INTEGER {
+ initiator(0),
+ acceptor(1)
+ }
+ OPTIONAL,
+
+ ExplicitPointer
+ }
+
+END
--- /dev/null
+-- VTPM: decode ASQ PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_asq.py,v 7.1 91/02/22 09:48:02 mrose Interim $
+--
+--
+-- $Log: rcv_asq.py,v $
+-- Revision 7.1 91/02/22 09:48:02 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:34 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+ASQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m,n,q;
+
+#ifdef PEPYTEST
+
+char *myname;
+ASQ_MSG ud;
+
+rcv_asq(pe)
+PE pe;
+{
+ int i,j;
+
+ if(unbuild_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,&ud) == NOTOK)return;
+
+ (void)printf("\n\n\nASQ Message:\n");
+ (void)printf("Class = %d Valid_Imp = %d Functional Units(%d) = %x\n",
+ ud.class,ud.valid_imp,ud.func_units.bitcount,ud.func_units.bitstring);
+ (void)printf("Version = %x Valid_coll = %d Valid_Prof = %d\n",
+ ud.version.bitstring,ud.valid_coll,ud.valid_prof);
+ if(ud.valid_prof)printf("OID_true = %d\n",
+ ud.asq_profile.oid_true);
+
+ if(!ud.valid_prof)
+ return;
+ (void)printf("Specials=%d CDS=%d CSS=%d DEV=%d\n",
+ ud.asq_profile.num_sp_param,
+ ud.asq_profile.num_cds_objects,ud.asq_profile.num_css_objects,
+ ud.asq_profile.num_dev_objects);
+
+ for(i=0; i < ud.asq_profile.num_sp_param; i++)
+ {
+ (void)printf("\n");
+ (void)printf("Special Num = %d Special Type = %d ",
+ ud.asq_profile.sp_offer_list[i].param_num,
+ ud.asq_profile.sp_offer_list[i].param_type);
+ if(ud.asq_profile.sp_offer_list[i].param_type == 0)
+ {
+ (void)printf("Boolean = %c\n",
+ ud.asq_profile.sp_offer_list[i].args.bool_arg);
+ }
+ else if(ud.asq_profile.sp_offer_list[i].param_type == 1)
+ {
+ (void)printf("Integer type = %d Integer value = %d\n",
+ ud.asq_profile.sp_offer_list[i].args.int_arg.type,
+ ud.asq_profile.sp_offer_list[i].args.int_arg.value);
+ }
+ else (void)printf("Invalid type\n");
+ }
+
+
+ for(i=0; i<ud.asq_profile.num_cds_objects; i++)
+ {
+ (void)printf("\n");
+ (void)printf("name: %s x=%d y=%d z=%d\n",
+ ud.asq_profile.cds_offer_list[i].obj_name,
+ ud.asq_profile.cds_offer_list[i].valid_x_dim,
+ ud.asq_profile.cds_offer_list[i].valid_y_dim,
+ ud.asq_profile.cds_offer_list[i].valid_z_dim);
+
+ (void)printf("erase=%d repertoire=%d emphasis=%d\n",
+ ud.asq_profile.cds_offer_list[i].erasure.bitcount,
+ ud.asq_profile.cds_offer_list[i].valid_rep_list,
+ ud.asq_profile.cds_offer_list[i].valid_emp_list);
+
+ (void)printf("ForeColor=%d BackColor=%d Access Right=%d\n",
+ ud.asq_profile.cds_offer_list[i].valid_fore_color,
+ ud.asq_profile.cds_offer_list[i].valid_back_color,
+ ud.asq_profile.cds_offer_list[i].access_right.bitcount);
+
+ if(ud.asq_profile.cds_offer_list[i].valid_x_dim)
+ {
+ (void)printf("Bound=%d Add=%d Abs=%d Window=%d\n",
+ ud.asq_profile.cds_offer_list[i].x_dim.bound_type,
+ ud.asq_profile.cds_offer_list[i].x_dim.addressing.bitcount,
+ ud.asq_profile.cds_offer_list[i].x_dim.absolute.bitcount,
+ ud.asq_profile.cds_offer_list[i].x_dim.window_type);
+
+ if(ud.asq_profile.cds_offer_list[i].x_dim.window_type)
+ {
+ (void)printf("windowtype=%d windowvalue=%d\n",
+ ud.asq_profile.cds_offer_list[i].x_dim.window.type,
+ ud.asq_profile.cds_offer_list[i].x_dim.window.value);
+ }
+ }
+ if(ud.asq_profile.cds_offer_list[i].valid_rep_list)
+ {
+ (void)printf("\n");
+ (void)printf("validcap=%d Number of Repertoires=%d\n",
+ ud.asq_profile.cds_offer_list[i].rep_offer.valid_cap,
+ ud.asq_profile.cds_offer_list[i].rep_offer.num_reps);
+ for(j=0;j<ud.asq_profile.cds_offer_list[i].rep_offer.num_reps;j++)
+ {
+ (void)printf("\n");
+ (void)printf("reptype=%d fontcap=%d numfonts=%d\n",
+ ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].rep_type, ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].valid_font_cap, ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].num_fonts);
+ if(ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].rep_type == 2)
+ (void)printf("Repertoire = %s\n", ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[j].rep_assign);
+ }
+ }
+ }
+}
+
+#endif
+
+
+#define bitstr2int(arg,val,cnt) \
+{ \
+ char *cp; \
+ \
+ cp = bitstr2strb (arg, &cnt); \
+ val = strb2int (cp, cnt); \
+ free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+ASQpdu ::= CHOICE
+
+{
+ asqpdu [0] IMPLICIT ASQcontent [[p (PEPYPARM)parm]]
+}
+
+ASQcontent
+%{
+ ASQ_MSG *arg =
+ (ASQ_MSG *) parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->valid_imp = 0;
+ arg->valid_prof = 0;
+ arg->valid_coll = 0;
+%}
+{
+ [0] IMPLICIT INTEGER [[i arg->class]],
+
+ [1] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+ %{arg->valid_imp = 1;%}
+ OPTIONAL,
+
+ [2] IMPLICIT BIT STRING
+ %{ bitstr2int ($$, arg->func_units.bitstring, arg->func_units.bitcount); %},
+
+ [3] IMPLICIT Profile [[p (PEPYPARM)&(arg->asq_profile)]]
+ %{arg->valid_prof = 1;%}
+ OPTIONAL,
+
+ [4] IMPLICIT BIT STRING
+ %{ bitstr2int ($$, arg->version.bitstring, arg->version.bitcount); %}
+ OPTIONAL,
+
+ [5] IMPLICIT INTEGER [[i arg->coll_winner]]
+ %{arg->valid_coll = 1;%}
+ OPTIONAL
+}
+
+ImplemIdent
+%{
+ IMPLEM_ID *arg = (IMPLEM_ID *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->oid_true = 0;
+ arg->name_true = 0;
+ arg->version_true = 0;
+%}
+{
+ impIdent [0] IMPLICIT OBJECT IDENTIFIER
+ [[O arg->imp_oid]]
+ %{arg->oid_true = 1;%}
+ OPTIONAL,
+
+ impName [1] IMPLICIT PrintableString
+ [[s arg->name]]
+ %{arg->name_true = 1;%}
+ OPTIONAL,
+
+ impVersion [2] IMPLICIT PrintableString
+ [[s arg->version]]
+ %{arg->version_true = 1;%}
+}
+
+Profile
+%{
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->oid_true = 0;
+ arg->num_sp_param = 0;
+ arg->num_cds_objects = 0;
+ arg->num_css_objects = 0;
+ arg->num_dev_objects = 0;
+ arg->del_ctrl.bitcount = 0;
+%}
+{
+ name OBJECT IDENTIFIER [[O arg->prof_oid]]
+ %{arg->oid_true = 1;%},
+
+ ProfileArgList [[p parm]]
+ OPTIONAL
+
+}
+
+ProfileArgList
+%{
+ int k;
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+
+%} ::=
+SEQUENCE OF %{
+
+ q = arg->num_sp_param;
+%}
+
+ CHOICE
+ {
+ specialArgs [0] IMPLICIT SEQUENCE
+ {
+ identifier INTEGER
+ [[i arg->sp_offer_list[q].param_num]],
+
+ offeredValues CHOICE
+ {
+ boolean [0] IMPLICIT BIT STRING
+ [[x arg->sp_offer_list[q].args.bool_arg $ k]]
+ %{arg->sp_offer_list[q].param_type = 0;%},
+
+ integer [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->sp_offer_list[q].args.int_arg)]]
+ %{arg->sp_offer_list[q].param_type = 1;%},
+
+ string [2] IMPLICIT SET OF <<j=0; j<1; j++>>
+ PrintableString
+ [[s arg->sp_offer_list[q].args.string_arg]]
+ %{arg->sp_offer_list[q].param_type = 2;%}
+ }
+
+ %{++arg->num_sp_param;
+ if(arg->num_sp_param >= MAXSPARGS) return(OK);
+ %}
+ },
+
+ vteParams [1] IMPLICIT ParamOfferList [[p parm]]
+
+ }
+
+ParamOfferList
+%{
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::= SEQUENCE
+{
+ displayObjects [0] IMPLICIT CDSOffer [[p parm]]
+ OPTIONAL,
+
+-- controlObjects [1] IMPLICIT CSSOffer [[p parm]]
+-- OPTIONAL,
+
+-- deviceObjects [2] IMPLICIT DEVOffer [[p parm]]
+-- OPTIONAL,
+
+ deliveryControl [3] IMPLICIT BIT STRING
+ %{ bitstr2int ($$,
+ arg->del_ctrl.bitstring,
+ arg->del_ctrl.bitcount); %}
+ OPTIONAL
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below. PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous. At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSOffer
+%{
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::=
+SET OF
+%{
+ l = arg->num_cds_objects;
+%} SEQUENCE
+{
+ objectName PrintableString
+ [[s arg->cds_offer_list[l].obj_name]],
+
+ ObjectOffer [[p (PEPYPARM)&(arg->cds_offer_list[l])]]
+
+ %{ ++arg->num_cds_objects;
+ if(arg->num_cds_objects >= MAXCDSOBJ) return(OK);
+ %}
+}
+
+--CSSOffer ::= NULL
+
+--DEVOffer ::= NULL
+
+ObjectOffer
+%{
+ CDS_OFFER *arg = (CDS_OFFER *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->dimensions.bitcount = 0;
+ arg->valid_x_dim = 0;
+ arg->valid_y_dim = 0;
+ arg->valid_z_dim = 0;
+ arg->erasure.bitcount = 0;
+ arg->valid_rep_list = 0;
+ arg->valid_emp_list = 0;
+ arg->valid_fore_color = 0;
+ arg->valid_back_color = 0;
+ arg->access_right.bitcount = 0;
+%}
+{
+ dimensionOffer [0] IMPLICIT BIT STRING
+ %{ bitstr2int ($$,
+ arg->dimensions.bitstring,
+ arg->dimensions.bitcount); %}
+ OPTIONAL,
+
+ xParamOffer [1] IMPLICIT DimOffer [[p (PEPYPARM)&(arg->x_dim)]]
+ %{arg->valid_x_dim = 1;%}
+ OPTIONAL,
+
+ yParamOffer [2] IMPLICIT DimOffer [[p (PEPYPARM)&(arg->y_dim)]]
+ %{arg->valid_y_dim = 1;%}
+ OPTIONAL,
+
+ zParamOffer [3] IMPLICIT DimOffer [[p (PEPYPARM)&(arg->z_dim)]]
+ %{arg->valid_z_dim = 1;%}
+ OPTIONAL,
+
+-- erasuroffer [4] IMPLICIT BIT STRING
+-- %{ bitstr2int ($$,
+-- arg->erasure.bitstring,
+-- arg->erasure.bitcount); %}
+-- OPTIONAL,
+
+ repOfferList [5] IMPLICIT CompRepOffer [[p (PEPYPARM)&(arg->rep_offer)]]
+ %{arg->valid_rep_list = 1;%}
+ OPTIONAL,
+
+-- empOfferList [6] IMPLICIT CompEmpOffer [[p (PEPYPRAM)&(arg->emp_offer)]]
+-- %{arg->valid_emp_list = 1;%}
+-- OPTIONAL,
+
+-- foreColorList [7] IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->fore_color_list)]]
+-- %{arg->valid_fore_color = 1;%}
+-- OPTIONAL,
+
+-- backColorList [8] IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->back_color_list)]]
+-- %{arg->valid_back_color = 1;%}
+-- OPTIONAL,
+
+ objectAccRight [9] IMPLICIT BIT STRING
+ %{ bitstr2int ($$,
+ arg->access_right.bitstring,
+ arg->access_right.bitcount); %}
+ OPTIONAL
+}
+
+DimOffer
+%{
+ DIMEN_PARAM *arg = (DIMEN_PARAM *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->bound_type = 0;
+ arg->addressing.bitcount = 0;
+ arg->absolute.bitcount = 0;
+ arg->window_type = 0;
+%}
+
+{
+ bound [0] IMPLICIT SEQUENCE
+ {
+ unbounded NULL
+ %{arg->bound_type = 1;%}
+ OPTIONAL,
+
+ limit IntOffer [[p (PEPYPARM)&(arg->bound)]]
+ %{arg->bound_type = 2;%}
+ }
+ OPTIONAL,
+
+ addressing [1] IMPLICIT BIT STRING
+ %{ bitstr2int ($$,
+ arg->addressing.bitstring,
+ arg->addressing.bitcount); %}
+ OPTIONAL,
+
+ absolute [2] IMPLICIT BIT STRING
+ %{ bitstr2int ($$,
+ arg->absolute.bitstring,
+ arg->absolute.bitcount); %}
+ OPTIONAL,
+
+ window [3] IMPLICIT SEQUENCE
+ {
+ unbounded NULL
+ %{arg->window_type = 1;%}
+ OPTIONAL,
+
+ limit IntOffer [[p (PEPYPARM)&(arg->window)]]
+ %{arg->window_type = 2;%}
+ OPTIONAL
+ }
+ OPTIONAL
+}
+
+CompRepOffer
+%{
+ REP_LIST *arg = (REP_LIST *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->valid_cap = 0;
+ arg->num_reps = 0;
+ arg->repertoire[m].valid_font_cap = 0;
+ arg->repertoire[m].num_fonts = 0;
+/* arg->repertoire[m].rep_assign = 0; */
+%}
+
+{
+ repCapability [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+ %{arg->valid_cap = 1;%}
+ OPTIONAL,
+
+ [1] IMPLICIT SEQUENCE OF
+ %{m = arg->num_reps;%}
+ RepFontOffer [[p (PEPYPARM)&(arg->repertoire[m])]]
+ %{++arg->num_reps;
+ if(arg->num_reps >= MAXREPS) return(OK);
+ %}
+}
+
+RepFontOffer
+%{
+ REP_FONT *arg = (REP_FONT *)parm;
+%}
+ ::=
+CHOICE
+{
+ NULL
+ %{arg->rep_type = 1;%},
+
+ SEQUENCE
+ {
+ repertoire [0] IMPLICIT PrintableString
+ [[s arg->rep_assign]]
+ OPTIONAL,
+
+ fontCapability [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+ %{arg->valid_font_cap = 1;%}
+ OPTIONAL,
+
+ [2] IMPLICIT SEQUENCE OF
+ %{n = arg->num_fonts;%}
+ PrintableString
+ [[s arg->font_names[n] ]]
+ %{++arg->num_fonts;%}
+ OPTIONAL
+ }
+ %{arg->rep_type = 2;%}
+}
+
+--CompEmpOffer ::= SEQUENCE
+--%{ parm->asq_profile.cds_offer_list[l].emp_offer.valid_cap = 0;
+-- parm->asq_profile.cds_offer_list[l].emp_offer.num_emps = 0;
+--%}
+
+--{
+-- empCap [0] IMPLICIT IntOffer [[p parm]]
+-- %{parm->asq_profile.cds_offer_list[l].emp_offer.valid_cap = 1;%}
+-- OPTIONAL,
+
+-- SEQUENCE OF %{m = parm->asq_profile.cds_offer_list[l].emp_offer.num_emps;%}
+-- PrintableString
+-- [[s parm->asq_profile.cds_offer_list[l].emp_offer.emp_string[m] ]]
+-- %{++parm->asq_profile.cds_offer_list[l].emp_offer.num_emps;
+-- if(parm->asq_profile.cds_offer_list[l].emp_offer.num_emps >= MAXEMPS) return(OK);
+-- %}
+-- OPTIONAL
+--}
+
+--ColorOffer %{int i;%} ::= SEQUENCE
+--%{
+-- COLOR_LIST *arg = parm;
+--
+-- arg->valid_cap = 0;
+-- arg->num_colors = 0;
+--%}
+
+--{
+-- colorCap [0] IMPLICIT FCIntOffer [[p parm]]
+-- %{arg->valid_cap = 1;%}
+-- OPTIONAL,
+
+-- colorNames SEQUENCE OF %{m = parm->asq_profile.cds_offer_list[l].fore_color_list.num_colors;%}
+-- PrintableString
+-- [[s parm->asq_profile.cds_offer_list[l].fore_color_list.color_string[m] ]]
+-- %{++parm->asq_profile.cds_offer_list[l].fore_color_list.num_colors;
+-- if(parm->asq_profile.cds_offer_list[l].fore_color_list.num_colors >= MAXCOLORS) return(OK);
+-- %}
+-- OPTIONAL
+--}
+
+IntOffer
+%{
+ INT_OFFER *arg = (INT_OFFER *)parm;
+%}
+ ::= SEQUENCE OF
+
+ CHOICE
+ {
+ indivValue [0] IMPLICIT INTEGER
+ [[i arg->value]]
+ %{arg->type = 0;%},
+
+ range [1] IMPLICIT SEQUENCE
+ %{arg->type = 1;%}
+ {
+ INTEGER [[i arg->min_val]],
+ INTEGER [[i arg->max_val]]
+ }
+ }
+
+END
+
+%{
+
+%}
--- /dev/null
+-- VTPM: decode ASR PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_asr.py,v 7.1 91/02/22 09:48:04 mrose Interim $
+--
+--
+-- $Log: rcv_asr.py,v $
+-- Revision 7.1 91/02/22 09:48:04 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:36 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+ASRPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m,n,q;
+
+#ifdef PEPYTEST
+
+ASR_MSG udr;
+
+rcv_asr(pe)
+PE pe;
+{
+
+ int i;
+
+ if(unbuild_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,&udr) == NOTOK)
+ {
+ (void)printf("Can't unbuild ASR PDU\n");
+ return;
+ }
+
+ (void)printf("Result = %d\n",udr.result);
+ (void)printf("Version.bitcount = %d; Version = %x\n",
+ udr.version.bitcount,udr.version.bitstring);
+ (void)printf("F.U. bitcount = %d; F.U. = %x\n",
+ udr.func_units.bitcount,udr.func_units.bitstring);
+ if(udr.valid_coll)
+ (void)printf("valid_coll = %d; coll_winner = %d\n",
+ udr.valid_coll,udr.coll_winner);
+ (void)printf("Valid_reason = %d\n",udr.valid_reason);
+ (void)printf("Sp Obj = %d CDS Obj = %d CSS Obj = %d DEV Obj = %d\n",
+ udr.arg_list.num_sp_param,udr.arg_list.num_cds_objects,
+ udr.arg_list.num_css_objects,udr.arg_list.num_dev_objects);
+
+ for(l=0; l<udr.arg_list.num_sp_param; l++)
+ {
+ (void)printf("\n");
+ (void)printf("Special Num = %d Special Type = %d",
+ udr.arg_list.sp_val[l].param_num,
+ udr.arg_list.sp_val[l].param_type);
+ if(udr.arg_list.sp_val[l].param_type == 0)
+ {
+ (void)printf("Boolean Type = %d\n",
+ udr.arg_list.sp_val[l].args.bool_arg);
+ }
+ else if(udr.arg_list.sp_val[l].param_type == 1)
+ {
+ (void)printf("Integer Type = %d\n",
+ udr.arg_list.sp_val[l].args.int_arg);
+ }
+ else
+ (void)printf("Bad Special Param Type\n");
+ }
+
+ for(l=0;l<udr.arg_list.num_cds_objects; l++)
+ {
+ (void)printf("\n\nObject Name = %s\n",udr.arg_list.cds_val[l].obj_name);
+ (void)printf("Valid:\n");
+ (void)printf("\tdimen(%d) x_dim(%d) y_dim(%d) z_dim(%d)\n",
+ udr.arg_list.cds_val[l].dimensions,
+ udr.arg_list.cds_val[l].valid_x_dim,
+ udr.arg_list.cds_val[l].valid_y_dim,
+ udr.arg_list.cds_val[l].valid_z_dim);
+ (void)printf("\terase(%d) repertoire(%d) emph(%d) fore(%d)\n",
+ udr.arg_list.cds_val[l].valid_erasure,
+ udr.arg_list.cds_val[l].valid_rep_list,
+ udr.arg_list.cds_val[l].valid_emp_list,
+ udr.arg_list.cds_val[l].valid_fore_color);
+ (void)printf("\tback(%d) access right(%d)\n",
+ udr.arg_list.cds_val[l].valid_back_color,
+ udr.arg_list.cds_val[l].valid_access_right);
+ (void)printf("X Dimension:\n");
+ (void)printf("\tBound(%d) addressing(%d) absolute(%d) window(%d)\n",
+ udr.arg_list.cds_val[l].x_dim.bound_type,
+ udr.arg_list.cds_val[l].x_dim.valid_addr,
+ udr.arg_list.cds_val[l].x_dim.valid_abs,
+ udr.arg_list.cds_val[l].x_dim.window_type);
+ (void)printf("\twindow size = %d\n",udr.arg_list.cds_val[l].x_dim.window);
+ (void)printf("Repertoires: (Number = %d)\n",
+ udr.arg_list.cds_val[l].rep_value.num_reps);
+ for(i=0;i<udr.arg_list.cds_val[l].rep_value.num_reps;i++)
+ {
+ (void)printf("\ttype(%d) rep(%s) capability(%d) fonts(%d)\n",
+ udr.arg_list.cds_val[l].rep_value.repertoire[i].rep_type,
+ udr.arg_list.cds_val[l].rep_value.repertoire[i].rep_assign,
+ udr.arg_list.cds_val[l].rep_value.repertoire[i].valid_font_cap,
+ udr.arg_list.cds_val[l].rep_value.repertoire[i].num_fonts);
+ }
+ }
+
+}
+
+#endif
+
+
+#define bitstr2int(arg,val,cnt) \
+{ \
+ char *cp; \
+ \
+ cp = bitstr2strb (arg, &cnt); \
+ val = strb2int (cp, cnt); \
+ free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+ASRpdu ::= CHOICE
+
+{
+ asrpdu [1] IMPLICIT ASRcontent [[p (PEPYPARM)parm]]
+}
+
+ASRcontent
+%{
+ ASR_MSG *arg = (ASR_MSG *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->valid_reason = 0;
+ arg->valid_imp = 0;
+ arg->valid_coll = 0;
+ arg->version.bitcount = 0;
+ arg->func_units.bitcount = 0;
+ arg->arg_list.num_sp_param = 0;
+%}
+{
+
+ userReason [0] IMPLICIT PrintableString [[s arg->reason.usr_reason]]
+ %{arg->reason.type = 0;
+ arg->valid_reason = 1;%}
+ OPTIONAL,
+
+ provReason [1] IMPLICIT INTEGER [[i arg->reason.provider_reason]]
+ %{arg->reason.type = 1;
+ arg->valid_reason = 1;%}
+ OPTIONAL,
+
+ [2] IMPLICIT INTEGER [[i arg->result]],
+
+ [3] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+ %{arg->valid_imp = 1;%}
+ OPTIONAL,
+
+ [4] IMPLICIT BITSTRING
+ %{ bitstr2int ($$, arg->version.bitstring, arg->version.bitcount); %},
+
+ [5] IMPLICIT ArgumValueList [[p (PEPYPARM)&(arg->arg_list)]],
+
+ [6] IMPLICIT BITSTRING
+ %{ bitstr2int ($$, arg->func_units.bitstring, arg->func_units.bitcount) ;%},
+
+ [7] IMPLICIT INTEGER [[i arg->coll_winner]]
+ %{arg->valid_coll = 1;%}
+ OPTIONAL
+}
+
+ImplemIdent
+%{
+ IMPLEM_ID *arg = (IMPLEM_ID *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->oid_true = 0;
+ arg->name_true = 0;
+ arg->version_true = 0;
+%}
+{
+ impIdent [0] IMPLICIT OBJECT IDENTIFIER
+ [[O arg->imp_oid]]
+ %{arg->oid_true = 1;%},
+
+ impName [1] IMPLICIT PrintableString
+ [[s arg->name]]
+ %{arg->name_true = 1;%},
+
+ impVersion [2] IMPLICIT PrintableString
+ [[s arg->version]]
+ %{arg->version_true = 1;%}
+}
+
+ArgumValueList
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= SET OF %{q = arg->num_sp_param;%} Squat [[p parm]]
+
+
+Squat ::= CHOICE
+{
+ specArgs [0] IMPLICIT SpecialArgs [[p parm]],
+ vteParams [1] IMPLICIT ParamValueList [[p parm]]
+}
+
+SpecialArgs
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= SEQUENCE
+{
+ identifier INTEGER [[i arg->sp_val[q].param_num]],
+ value CHOICE
+ {
+ BOOLEAN [[b arg->sp_val[q].args.bool_arg]]
+ %{arg->sp_val[q].param_type = 0;%},
+ INTEGER [[i arg->sp_val[q].args.int_arg]]
+ %{arg->sp_val[q].param_type = 1;%},
+ PrintableString[[s arg->sp_val[q].args.string_arg]]
+ %{arg->sp_val[q].param_type = 2;%}
+ }
+
+ %{++arg->num_sp_param;
+ if(arg->num_sp_param >= MAXSPARGS) return(OK);
+ %}
+}
+
+ParamValueList
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= SEQUENCE
+%{
+/* arg->num_cds_objects = 0;*/
+%}
+{
+ displayObjects [0] IMPLICIT CDSValues [[p parm]]
+ OPTIONAL,
+
+-- controlObjects [1] IMPLICIT CSSValues [[p parm]]
+-- OPTIONAL,
+
+-- deviceObjects [2] IMPLICIT DEVValues [[p parm]]
+-- OPTIONAL,
+
+ deliveryControl [3] IMPLICIT INTEGER
+ [[i arg->del_ctrl]]
+ OPTIONAL
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below. PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous. At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSValues
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::=
+SET OF %{l = arg->num_cds_objects;%} SEQUENCE
+{
+ objectName PrintableString
+ [[s arg->cds_val[l].obj_name]],
+
+ ObjectOffer [[p (PEPYPARM)&(arg->cds_val[l])]]
+ %{ ++arg->num_cds_objects;
+ if(arg->num_cds_objects >= MAXCDSOBJ) return(OK);
+ %}
+}
+
+CSSValues ::= NULL --Unused for now--
+
+DEVValues ::= NULL --Unused for now--
+
+ObjectOffer
+%{
+ CDS_VALUE *arg = (CDS_VALUE *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->dimensions = 0;
+ arg->valid_x_dim = 0;
+ arg->valid_y_dim = 0;
+ arg->valid_z_dim = 0;
+ arg->valid_erasure = 0;
+ arg->valid_rep_list = 0;
+ arg->valid_emp_list = 0;
+ arg->valid_fore_color = 0;
+ arg->valid_back_color = 0;
+ arg->valid_access_right = 0;
+%}
+{
+ dimensionValue [0] IMPLICIT INTEGER
+ [[i arg->dimensions]]
+ OPTIONAL,
+
+ xParamValue [1] IMPLICIT DimValue [[p (PEPYPARM)&(arg->x_dim)]]
+ %{arg->valid_x_dim = 1;%}
+ OPTIONAL,
+
+ yParamValue [2] IMPLICIT DimValue [[p (PEPYPARM)&(arg->y_dim)]]
+ %{arg->valid_y_dim = 1;%}
+ OPTIONAL,
+
+ zParamValue [3] IMPLICIT DimValue [[p (PEPYPARM)&(arg->z_dim)]]
+ %{arg->valid_z_dim = 1;%}
+ OPTIONAL,
+
+-- erasurevalue [4] IMPLICIT BOOLEAN
+-- [[b arg->erasure]]
+-- %{arg->valid_erasure = 1;%}
+-- OPTIONAL,
+
+ repValueList [5] IMPLICIT CompRepValue [[p (PEPYPARM)&(arg->rep_value)]]
+ %{arg->valid_rep_list = 1;%}
+ OPTIONAL,
+
+-- empValueList [6] IMPLICIT CompEmpValue [[p (PEPYPARM)&(arg->emp_value)]]
+-- %{arg->valid_emp_list = 1;%}
+-- OPTIONAL,
+
+-- foreColorVal [7] IMPLICIT ColorValue [[p (PEPYPARM)&(arg->fore_color_list)]]
+-- %{arg->valid_fore_color = 1;%}
+-- OPTIONAL,
+
+-- backColorVal [8] IMPLICIT ColorValue [[p (PEPYPARM)&(arg->back_color_list)]]
+-- %{arg->valid_back_color = 1;%}
+-- OPTIONAL,
+
+ objectAccRight [9] IMPLICIT INTEGER
+ [[i arg->access_right]]
+ %{arg->valid_access_right = 1;%}
+ OPTIONAL
+}
+
+DimValue
+%{
+ DIMEN_VALUE *arg = (DIMEN_VALUE *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->bound_type = 0;
+ arg->valid_addr = 0;
+ arg->valid_abs = 0;
+ arg->window_type = 0;
+%}
+{
+ bound [0] CHOICE
+ {
+ unbounded NULL
+ %{arg->bound_type = 1;%},
+
+ limit INTEGER
+ [[i arg->bound]]
+ %{arg->bound_type = 2;%}
+ }
+ OPTIONAL,
+
+ addressing [1] IMPLICIT INTEGER
+ [[i arg->addressing]]
+ OPTIONAL,
+
+ absolute [2] IMPLICIT INTEGER
+ [[i arg->absolute]]
+ OPTIONAL,
+
+ window [3] CHOICE
+ {
+ unbounded NULL
+ %{arg->window_type = 1;%},
+
+ limit INTEGER
+ [[i arg->window]]
+ %{arg->window_type = 2;%}
+ }
+ OPTIONAL
+}
+
+CompRepValue
+%{
+ REP_VALUE *arg = (REP_VALUE *)parm;
+%}
+ ::= SEQUENCE
+%{
+ arg->valid_cap = 0;
+ arg->num_reps = 0;
+%}
+{
+ repCapability [0] IMPLICIT INTEGER
+ [[i arg->capability]]
+ %{arg->valid_cap = 1;%}
+ OPTIONAL,
+ [1] IMPLICIT SEQUENCE OF
+ %{m = arg->num_reps;%}
+ RepFontValue [[p (PEPYPARM)&(arg->repertoire[m])]]
+ %{++arg->num_reps;
+ if(arg->num_reps >= MAXREPS) return(OK);
+ %}
+ OPTIONAL
+}
+
+RepFontValue
+%{
+ FONT_VALUE *arg = (FONT_VALUE *)parm;
+%}
+ ::=
+CHOICE
+%{
+ arg->valid_font_cap = 0;
+ arg->num_fonts = 0;
+ arg->rep_assign = 0;
+%}
+{
+ NULL
+ %{arg->rep_type = 1;%},
+
+ SEQUENCE
+ {
+ repertoire [0] IMPLICIT PrintableString
+ [[s arg->rep_assign]]
+ OPTIONAL,
+
+ fontCapability [1] IMPLICIT INTEGER
+ [[i arg->capability]]
+ %{++arg->valid_font_cap;%}
+ OPTIONAL,
+
+ [2] IMPLICIT SEQUENCE OF
+ %{n = arg->num_fonts;%}
+ PrintableString
+ [[s arg->font_names[n] ]]
+ %{
+ ++arg->num_fonts;
+ if(arg->num_fonts >= MAXFONTS) return(OK);
+ %}
+ OPTIONAL
+ }
+}
+
+--CompEmpValue
+--%{
+-- EMP_VALUE *arg = (EMP_VALUE *)parm;
+--%}
+-- ::= SEQUENCE
+--%{arg->valid_cap = 0;
+-- arg->num_emps = 0;
+--%}
+--{
+-- empCap [0] IMPLICIT INTEGER
+-- [[i arg->capability]]
+-- %{arg->valid_cap = 1;%}
+-- OPTIONAL,
+
+-- SEQUENCE OF %{m = arg->num_emps;%}
+-- PrintableString
+-- [[s arg->emp_string[m] ]]
+-- %{++arg->num_emps;
+-- if(arg->num_emps >= MAXEMPS) return(OK);
+-- %}
+-- OPTIONAL
+--}
+
+--ColorValue
+--%{
+-- COLOR_VALUE *arg = (COLOR_VALUE *)parm;
+--%}
+-- ::= SEQUENCE
+--%{
+-- arg->valid_cap = 0;
+-- arg->num_colors = 0;
+--%}
+--{
+-- colorCap [0] IMPLICIT INTEGER
+-- [[i arg->capability]]
+-- %{arg->valid_cap = 1;%}
+-- OPTIONAL,
+
+-- colorNames SEQUENCE OF %{m = arg->num_colors;%}
+-- PrintableString
+-- [[s arg->color_string[m] ]]
+-- %{++arg->num_colors;
+-- if(arg->num_colors >= MAXCOLORS) return(OK);
+-- %}
+--}
+
+END
+
+%{
+
+
+%}
--- /dev/null
+-- VTPM: decode NDQ PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_text.py,v 7.1 91/02/22 09:48:06 mrose Interim $
+--
+--
+-- $Log: rcv_text.py,v $
+-- Revision 7.1 91/02/22 09:48:06 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:37 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+NDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+void adios ();
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int echo_sw;
+static char *do_name;
+extern TEXT_UPDATE *ndq_queue;
+
+#ifdef PEPYTEST
+
+TEXT_UPDATE ud;
+
+rcv_text(pe)
+PE pe;
+{
+
+ ud.echo_sw = ud.type_sw = -1;
+ ud.updates.do_list.do_name = "\0";
+ ud.updates.do_list.do_type = -1;
+ ud.updates.do_list.do_cmd.text_ud.text_count = 0;
+
+ if(unbuild_NDQPDU_NDQpdu(pe,1,NULLIP,NULLVP,&ud) == NOTOK)
+ return;
+
+ (void)printf("Echo = %d; Type = %d; D.O. Name = %s; D. O. Update Type = %d\n", ud.echo_sw,ud.type_sw,ud.updates.do_list.do_name, ud.updates.do_list.do_type);
+ if(ud.updates.do_list.do_cmd.text_ud.text_count)
+ (void)printf("Text = %s\n",ud.updates.do_list.do_cmd.text_ud.text_ptr);
+}
+
+#endif
+
+
+#define bitstr2int(arg,val,cnt) \
+{ \
+ char *cp; \
+ \
+ cp = bitstr2strb (arg, &cnt); \
+ val = strb2int (cp, cnt); \
+ free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+NDQpdu ::= CHOICE
+
+{
+ ndqpdu [6] IMPLICIT NDQcontent [[p (PEPYPARM)0]]
+}
+
+NDQcontent ::= SEQUENCE OF VTsdi [[p (PEPYPARM)0]]
+
+VTsdi ::= CHOICE
+{
+ echoNow [0] IMPLICIT SEQUENCE OF ObjectUpdate [[p (PEPYPARM)0]]
+ %{echo_sw = ECHO_ON;%},
+ notEchoNow [1] IMPLICIT SEQUENCE OF ObjectUpdate [[p (PEPYPARM)0]]
+ %{echo_sw = ECHO_OFF;%}
+}
+
+ObjectUpdate ::= CHOICE
+{
+ display [0] IMPLICIT SEQUENCE
+ {
+ dOname PrintableString
+ [[s do_name]],
+
+ SEQUENCE OF DOupdate [[p (PEPYPARM)0]]
+ },
+ control [1] IMPLICIT COupdate [[p (PEPYPARM)0]]
+}
+
+DOupdate
+%{
+ TEXT_UPDATE *arg = (TEXT_UPDATE *)parm;
+%}
+ ::= CHOICE
+%{
+ if( !(arg = (TEXT_UPDATE *)malloc(sizeof(TEXT_UPDATE)) ))
+ adios (NULLCP, "out of memory");
+ arg->echo_sw = echo_sw;
+ arg->type_sw = DISPLAY_OBJ;
+ arg->updates.do_list.do_name = do_name;
+%}
+{
+ nextXarray [0] IMPLICIT NULL
+ %{arg->updates.do_list.do_type = 0;
+ (void) enq(&ndq_queue,arg);%},
+ nextYarray [1] IMPLICIT NULL
+ %{arg->updates.do_list.do_type = 1;
+ (void) enq(&ndq_queue,arg);%},
+ ptr-relative [2] IMPLICIT ExplicitPointer
+ [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.ptr_rel)]]
+ %{arg->updates.do_list.do_type = 2;
+ (void) enq(&ndq_queue,arg);%},
+ ptr-absolute [3] IMPLICIT Pointer
+ [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.ptr_abs)]]
+ %{arg->updates.do_list.do_type = 3;
+ (void) enq(&ndq_queue,arg);%},
+ text [4] IMPLICIT OCTETSTRING
+ [[o arg->updates.do_list.do_cmd.text_ud.text_ptr $ arg->updates.do_list.do_cmd.text_ud.text_count]]
+ %{arg->updates.do_list.do_type = 4;
+ (void) enq(&ndq_queue,arg);%},
+
+ repeatText [5] IMPLICIT SEQUENCE {
+ finishAddress Pointer
+ [[p (PEPYPARM)parm]],
+
+ OCTETSTRING
+ [[o arg->updates.do_list.do_cmd.rpt_seq.text $ arg->updates.do_list.do_cmd.rpt_seq.text_count]]
+ }
+ %{arg->updates.do_list.do_type = 5;
+ (void) enq(&ndq_queue,arg);%},
+ writeAttr [6] IMPLICIT SEQUENCE {
+ AttrId [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.wrt_attrib)]],
+ AttrExtent [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.wrt_attrib)]]
+ }
+ %{arg->updates.do_list.do_type = 6;
+ (void) enq(&ndq_queue,arg);%},
+ erase [7] IMPLICIT SEQUENCE {
+ startErase Pointer [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.erase.start_erase)]],
+ endErase Pointer [[p (PEPYPARM)&(arg->updates.do_list.do_cmd.erase.end_erase)]],
+ eraseAttr BOOLEAN
+ [[b arg->updates.do_list.do_cmd.erase.erase_attr]]
+ }
+ %{arg->updates.do_list.do_type = 7;
+ (void) enq(&ndq_queue,arg);%},
+ previousXarray [8] IMPLICIT NULL
+ %{arg->updates.do_list.do_type = 8;
+ (void) enq(&ndq_queue,arg);%},
+ previousYarray [9] IMPLICIT NULL
+ %{arg->updates.do_list.do_type = 9;
+ (void) enq(&ndq_queue,arg);%}
+}
+
+COupdate
+%{
+ TEXT_UPDATE *arg = (TEXT_UPDATE *)parm;
+%}
+ ::= SEQUENCE
+%{
+ if( !(arg = (TEXT_UPDATE *)malloc(sizeof(TEXT_UPDATE)) ))
+ adios (NULLCP, "out of memory");
+ arg->echo_sw = echo_sw;
+ arg->type_sw = CTRL_OBJ;
+%}
+{
+ coName PrintableString
+ [[s arg->updates.co_list.co_name]],
+
+ objectUpdate CHOICE {
+ characterUpdate [0] IMPLICIT PrintableString
+ [[s arg->updates.co_list.co_cmd.char_update]]
+ %{arg->updates.co_list.co_type = 0;
+ (void) enq(&ndq_queue,arg);%},
+
+ booleanUpdate [1] IMPLICIT SEQUENCE {
+ values [0] IMPLICIT BITSTRING
+ [[x arg->updates.co_list.co_cmd.bool_update.value $ arg->updates.co_list.co_cmd.bool_update.val_count]],
+
+ mask [1] IMPLICIT BITSTRING
+ [[x arg->updates.co_list.co_cmd.bool_update.mask $ arg->updates.co_list.co_cmd.bool_update.mask_count]]
+ }
+ %{arg->updates.co_list.co_type = 1;
+ (void) enq(&ndq_queue,arg);%},
+
+ symbolicUpdate [2] IMPLICIT INTEGER
+ [[i arg->updates.co_list.co_cmd.sym_update]]
+ %{arg->updates.co_list.co_type = 2;
+ (void) enq(&ndq_queue,arg);%},
+
+ integerUpdate [3] IMPLICIT INTEGER
+ [[i arg->updates.co_list.co_cmd.int_update]]
+ %{arg->updates.co_list.co_type = 3;
+ (void) enq(&ndq_queue,arg);%},
+
+ bitStringUpdate [4] IMPLICIT BITSTRING
+ %{ bitstr2int ($$,
+ arg->updates.co_list.co_cmd.bit_update.bitstring,
+ arg->updates.co_list.co_cmd.bit_update.bitcount);
+ arg->updates.co_list.co_type = 4;
+ (void) enq(&ndq_queue,arg);%}
+ }
+}
+
+ExplicitPointer
+%{
+ EX_POINTER *arg = (EX_POINTER *)parm;
+%}
+ ::= SEQUENCE
+ %{ arg->x_true = 0;
+ arg->y_true = 0;
+ arg->z_true = 0;
+ %}
+ {
+ x [0] IMPLICIT INTEGER
+ [[i arg->x_value]]
+ %{arg->x_true = 1;%}
+ OPTIONAL,
+
+ y [1] IMPLICIT INTEGER
+ [[i arg->y_value]]
+ %{arg->y_true = 1;%}
+ OPTIONAL,
+
+ z [2] IMPLICIT INTEGER
+ [[i arg->z_value]]
+ %{arg->z_true = 1;%}
+ OPTIONAL
+}
+
+Pointer
+%{
+ POINTER *arg = (POINTER *)parm;
+%}
+ ::= CHOICE {
+ current [0] IMPLICIT NULL
+ %{arg->ptr_type = 0;%},
+ start [1] IMPLICIT NULL
+ %{arg->ptr_type = 1;%},
+ startY [2] IMPLICIT NULL
+ %{arg->ptr_type = 2;%},
+ startX [3] IMPLICIT NULL
+ %{arg->ptr_type = 3;%},
+ end [4] IMPLICIT NULL
+ %{arg->ptr_type = 4;%},
+ endY [5] IMPLICIT NULL
+ %{arg->ptr_type = 5;%},
+ endX [6] IMPLICIT NULL
+ %{arg->ptr_type = 6;%},
+ coords [7] IMPLICIT ExplicitPointer [[p (PEPYPARM)&(arg->e_ptr)]]
+ %{arg->ptr_type = 7;%}
+}
+
+AttrId
+%{
+ ATTRIB *arg = (ATTRIB *)parm;
+%}
+ ::= CHOICE {
+ graphCharRep [0] IMPLICIT INTEGER
+ [[i arg->attr_val]]
+ %{arg->attr_id = 0;%},
+
+ foreColor [1] IMPLICIT INTEGER
+ [[i arg->attr_val]]
+ %{arg->attr_id = 1;%},
+
+ backColor [2] IMPLICIT INTEGER
+ [[i arg->attr_val]]
+ %{arg->attr_id = 2;%},
+
+ emphasis [3] IMPLICIT INTEGER
+ [[i arg->attr_val]]
+ %{arg->attr_id = 3;%},
+
+ font [4] IMPLICIT INTEGER
+ [[i arg->attr_val]]
+ %{arg->attr_id = 4;%}
+}
+
+AttrExtent
+%{
+ ATTRIB *arg = (ATTRIB *)parm;
+%}
+ ::= CHOICE {
+ global [0] IMPLICIT NULL
+ %{arg->attr_ext = 0;%},
+ addrExtent [1] IMPLICIT SEQUENCE {
+ beginning Pointer [[p (PEPYPARM)&(arg->beg_p)]],
+ ending Pointer [[p (PEPYPARM)&(arg->end_p)]]
+ }
+ %{arg->attr_ext = 1;%},
+ modalExtent [2] IMPLICIT NULL
+ %{arg->attr_ext = 2;%}
+}
+
+END
+
+%{
+
+/*
+ * deq take something out of a fifo queue (a la knuth)
+ * elements are circularly linked
+ * q head points to last entry in queue
+ */
+
+TEXT_UPDATE *
+deq( qhp )
+register TEXT_UPDATE **qhp;
+{
+ register TEXT_UPDATE *elem;
+
+
+ if( (elem = (*qhp)) != 0 )
+ {
+ elem = elem->ndq_elem;
+ (*qhp)->ndq_elem = elem->ndq_elem;
+ if( elem == elem->ndq_elem )
+ (*qhp) = 0;
+ }
+
+ return( elem );
+}
+
+/*
+ * enq enter something in a queue
+ * queue format is same as deq above
+ */
+
+enq( qhp,elem )
+register TEXT_UPDATE **qhp;
+register TEXT_UPDATE *elem;
+{
+ register TEXT_UPDATE *liq;
+
+ if( (liq = (*qhp)) == 0 )
+ (*qhp) = elem;
+ elem->ndq_elem = (*qhp)->ndq_elem;
+ (*qhp)->ndq_elem = elem;
+ (*qhp) = elem;
+
+ return ( (int) liq ); /* last-in-queue zero, says queue was empty */
+}
+
+/*
+ * fiq get the first in queue - no delinking
+ * return zero if nothing in queue
+ */
+
+TEXT_UPDATE *
+fiq( qhp )
+register TEXT_UPDATE **qhp;
+{
+ register TEXT_UPDATE *e;
+
+ if( (e = *qhp) != 0 ) /* something in queue */
+ e = e->ndq_elem; /* \10get first in queue */
+
+ return( e ); /* return that value */
+}
+%}
--- /dev/null
+-- VTPM: decode UDQ PDU
+
+-- $Header: /f/osi/vt/RCS/rcv_udq.py,v 7.1 91/02/22 09:48:07 mrose Interim $
+--
+--
+-- $Log: rcv_udq.py,v $
+-- Revision 7.1 91/02/22 09:48:07 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:39 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+UDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+#undef PEPYPARM
+#define PEPYPARM int *
+
+void adios ();
+
+
+#define bitstr2int(arg,val,cnt) \
+{ \
+ char *cp; \
+ \
+ cp = bitstr2strb (arg, &cnt); \
+ val = strb2int (cp, cnt); \
+ free (cp); \
+}
+
+%}
+
+BEGIN
+
+SECTIONS none unbuild none
+
+UDQpdu ::= CHOICE
+
+{
+ udqpdu [7] IMPLICIT COupdate [[p (PEPYPARM)parm]]
+}
+
+COupdate
+%{
+ TEXT_UPDATE *arg = (TEXT_UPDATE *)parm;
+%}
+ ::= SEQUENCE
+{
+ coName PrintableString
+ [[s arg->updates.co_list.co_name]],
+
+ objectUpdate CHOICE {
+ characterUpdate [0] IMPLICIT PrintableString
+ [[s arg->updates.co_list.co_cmd.char_update]]
+ %{arg->updates.co_list.co_type = 0;%},
+
+ booleanUpdate [1] IMPLICIT SEQUENCE {
+ values [0] IMPLICIT BITSTRING
+ [[x arg->updates.co_list.co_cmd.bool_update.value $ arg->updates.co_list.co_cmd.bool_update.val_count]],
+
+ mask [1] IMPLICIT BITSTRING
+ [[x arg->updates.co_list.co_cmd.bool_update.mask $ arg->updates.co_list.co_cmd.bool_update.mask_count]]
+ }
+ %{arg->updates.co_list.co_type = 1;%},
+
+ symbolicUpdate [2] IMPLICIT INTEGER
+ [[i arg->updates.co_list.co_cmd.sym_update]]
+ %{arg->updates.co_list.co_type = 2;%},
+
+ integerUpdate [3] IMPLICIT INTEGER
+ [[i arg->updates.co_list.co_cmd.int_update]]
+ %{arg->updates.co_list.co_type = 3;%},
+
+ bitStringUpdate [4] IMPLICIT BITSTRING
+ %{ bitstr2int ($$,
+ arg->updates.co_list.co_cmd.bit_update.bitstring,
+ arg->updates.co_list.co_cmd.bit_update.bitcount);
+ arg->updates.co_list.co_type = 4;%}
+ }
+}
+END
--- /dev/null
+/* sector1.h - VTPM: sector 1 definitions */
+
+/*
+ * $Header: /f/osi/vt/RCS/sector1.h,v 7.1 91/02/22 09:48:08 mrose Interim $
+ *
+ *
+ * $Log: sector1.h,v $
+ * Revision 7.1 91/02/22 09:48:08 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:39 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#define MAXSPARGS 2 /*Max Special Profile Arguments (2 for TLENET)*/
+#define MAXCDSOBJ 2 /*Max Display Objects (2 for TRANSPARENT)*/
+#define MAXCSSOBJ 1 /*Max Control Objects to negotiate*/
+#define MAXDEVOBJ 1 /*Max Device Objects*/
+#define MAXFONTS 1
+#define MAXREPS 1 /*Maximum Repertoires*/
+#define MAXEMPS 1 /*Max Background Emphasis*/
+#define MAXCOLORS 1 /*Aw C'mon*/
+
+
+/* ASQ PDU Fields*/
+#define ASQ_basic 0
+#define ASQ_Imp_Ident 1
+#define ASQ_Func_Units 2
+#define ASQ_Profile 3
+#define ASQ_P_Version 4
+#define ASQ_Coll_Win 5
+
+/* ASR PDU Fields */
+#define ASR_Fail_String 0
+#define ASR_Fail_Reason 1
+#define ASR_Result 2
+#define ASR_Imp_Ident 3
+#define ASR_P_Version 4
+#define ASR_Arg_List 5
+#define ASR_Func_Units 6
+#define ASR_Coll_Win 7
+
+/* Functional Units Bit Map*/
+#define profileSwitch 0x01
+#define profileMIN 0x02
+#define negRelease 0x04
+#define urgData 0x08
+#define destBreak 0x10
+
+/* NDQ ASN.1 Types */
+#define ECHO_ON 0
+#define ECHO_OFF 1
+#define DISPLAY_OBJ 0
+#define CTRL_OBJ 1
+#define DO_NEXT_X 0
+#define DO_NEXT_Y 1
+#define DO_PTR_REL 2
+#define DO_PTR_ABS 3
+#define DO_TEXT 4
+#define DO_RPT_TEXT 5
+#define DO_ATTR 6
+#define DO_ERASE 7
+#define DO_PREV_X 8
+#define DO_PREV_Y 9
+
+/*DI/KB Control Objects*/
+#define KB_SIZE 5 /* network bit ordering */
+#define IP_OBJ 0x80
+#define AO_OBJ 0x40
+#define AYT_OBJ 0x20
+#define DM_OBJ 0x10
+#define BRK_OBJ 0x08
+
+/*NI/NA Control Objects*/
+#define NA_SIZE 4 /* network bit ordering */
+#define ECHO_OBJ 0x80 /*0 is Local; 1 is Remote*/
+#define SUP_GA 0x40 /*0 is Use Go Ahead; 1 is Suppress Go Ahead*/
+#define DISP_BIN 0x20 /*1 = WACA is Binary; 0 = WACA is ASCII*/
+#define KBD_BIN 0x10 /*1 = WACI is Binary; 0 = WACI is ASCII*/
+
+/*Go Ahead Control Object*/
+#define GA_SIZE 1 /* network bit ordering */
+#define GO_AHEAD 0x80
+
+/*Synch Control Object*/
+#define SYNC_SIZE 1 /* network bit ordering */
+#define SYNC 0x80
+
+/*Default Profile Control Object*/
+#define DEF_SIZE 1 /* network bit ordering */
+#define DEF_ECHO 0x80 /*True for local echo*/
+
+#define FULL_ASCII "ASCII" /*TEMP repertoire ID*/
+#define ASCII_GO "GO"
+#define TRANSPARENT "TRANS"
+
+typedef struct trans_args /*Arguments for transparent profile*/
+{
+ int num_reps;
+ char *rep_ptr[MAXREPS];
+ char *cur_rep; /*Currently active repertoire*/
+} TRANS_ARGS;
+
+typedef struct telnet_args /*Arguments for telnet profile*/
+{
+ int x_window;
+ char full_ascii; /*If 1, Full ASCII. If 0, graphics only*/
+} TELNET_ARGS;
+
+typedef struct vt_profile /*Structure for profile parameters*/
+{
+ char *profile_name;
+ union
+ {
+ TRANS_ARGS tr_arg_list;
+ TELNET_ARGS tel_arg_list;
+ } arg_val;
+} VT_PROFILE;
+
+/* Data Structures for PDU's */
+
+typedef struct ex_pointer /*Explicit Pointer*/
+{
+ int x_true;
+ int x_value;
+ int y_true;
+ int y_value;
+ int z_true;
+ int z_value;
+} EX_POINTER;
+
+typedef struct pointer /*General Pointer*/
+{
+ int ptr_type; /*Values 0 - 6 */
+ EX_POINTER e_ptr;
+} POINTER;
+
+typedef struct rpt_text /*Repeat text*/
+{
+ POINTER fin_addr;
+ int text_count;
+ char *text;
+} RPT_TEXT;
+
+typedef struct erase_text /*Erase*/
+{
+ POINTER start_erase;
+ POINTER end_erase;
+ int erase_attr; /*Boolean*/
+} ERASE_TEXT;
+
+typedef struct text
+{
+ int text_count;
+ char *text_ptr;
+} TEXT_CONTENT;
+
+typedef struct attrib
+{
+ int attr_id; /* 0 - 4*/
+ int attr_val;
+ int attr_ext;
+ POINTER beg_p;
+ POINTER end_p;
+} ATTRIB;
+
+typedef struct bool_u
+{
+ int val_count;
+ char *value;
+ int mask_count;
+ char *mask;
+} BOOL_U;
+
+typedef struct bit_str
+{
+ int bitcount;
+ int bitstring;
+} BIT_STR;
+
+typedef struct do_update /*Display Object Update*/
+{
+ char *do_name;
+ int do_type; /* 0 - 9 */
+ union
+ {
+ EX_POINTER ptr_rel;
+ POINTER ptr_abs;
+ TEXT_CONTENT text_ud;
+ RPT_TEXT rpt_seq;
+ ATTRIB wrt_attrib;
+ ERASE_TEXT erase;
+ } do_cmd;
+} DO_UPDATE;
+
+typedef struct co_update /*Control Object Update*/
+{
+ char *co_name;
+ int co_type; /* 0 - 4 */
+ union
+ {
+ char *char_update;
+ BOOL_U bool_update;
+ int sym_update;
+ int int_update;
+ BIT_STR bit_update;
+ } co_cmd;
+} CO_UPDATE;
+
+typedef struct text_update
+{
+ struct text_update *ndq_elem; /*Pointer to next one in queue*/
+ int echo_sw; /*0 = Echo Now; 1 = Not Echo Now*/
+ int type_sw; /*0 = display; 1 = control*/
+ union
+ {
+ DO_UPDATE do_list;
+ CO_UPDATE co_list;
+ } updates;
+} TEXT_UPDATE;
+
+typedef struct implem_id
+{
+ int oid_true;
+ OID imp_oid; /*Optional*/
+ int name_true;
+ char *name; /*Optional*/
+ int version_true;
+ char *version; /*Optional*/
+} IMPLEM_ID;
+
+typedef struct int_offer
+{
+ int type; /*0 for single value, 1 for range*/
+ int value;
+ int min_val;
+ int max_val;
+} INT_OFFER;
+
+typedef struct rep_font /*Repertoire Font Offer*/
+{
+ int rep_type; /*1 = NULL; 2 = SEQUENCE....*/
+ char *rep_assign; /*0 value for pointer means not used*/
+ int valid_font_cap;
+ INT_OFFER capability;
+ int num_fonts;
+ char *font_names[MAXFONTS];
+} REP_FONT;
+
+typedef struct dimen_param
+{
+ int bound_type; /*0 for no bound, 1 for unbounded, 2 for
+ INT_OFFER */
+ INT_OFFER bound;
+ BIT_STR addressing; /*NOT optional according to 9041*/
+ BIT_STR absolute; /*Optional*/
+ int window_type; /*0 for not used, 1 for unbounded, 2 for
+ INT_OFFER */
+ INT_OFFER window;
+} DIMEN_PARAM;
+
+typedef struct rep_list /*Repertoire list*/
+{
+ int valid_cap;
+ INT_OFFER capability; /*Listed as optional but seems you should
+ have it. */
+ int num_reps; /*Number of repertoires -- seems it should
+ usually equal capability. */
+ REP_FONT repertoire[MAXREPS];
+} REP_LIST;
+
+typedef struct emp_list
+{
+ int valid_cap;
+ INT_OFFER capability; /*Technically Optional*/
+ int num_emps;
+ char *emp_string[MAXEMPS];
+} EMP_LIST;
+
+typedef struct color_list
+{
+ int valid_cap;
+ INT_OFFER capability;
+ int num_colors;
+ char *color_string[MAXCOLORS];
+} COLOR_LIST;
+
+typedef struct cds_offer
+{
+ char *obj_name;
+ BIT_STR dimensions;
+ int valid_x_dim;
+ DIMEN_PARAM x_dim;
+ int valid_y_dim;
+ DIMEN_PARAM y_dim;
+ int valid_z_dim;
+ DIMEN_PARAM z_dim;
+ BIT_STR erasure;
+ int valid_rep_list;
+ REP_LIST rep_offer;
+ int valid_emp_list;
+ EMP_LIST emp_offer;
+ int valid_fore_color;
+ COLOR_LIST fore_color_list;
+ int valid_back_color;
+ COLOR_LIST back_color_list;
+ BIT_STR access_right;
+} CDS_OFFER;
+
+typedef struct css_offer /*Unused in TELNET (and hopefully Forms)*/
+{
+ int i; /*For compiler*/
+} CSS_OFFER;
+
+typedef struct dev_offer /*Also unused*/
+{
+ int i; /*For compiler*/
+} DEV_OFFER;
+
+typedef struct special_offer
+{
+ int param_num;
+ int param_type; /*0,1,or2*/
+ union
+ {
+ char *bool_arg; /*Turns into bitstring = 0 or 1*/
+ INT_OFFER int_arg;
+ char *string_arg;
+ } args;
+} SPECIAL_OFFER;
+
+typedef struct arg_offer_list
+{
+ int oid_true; /*Optional--Use Default Profile if not specified*/
+ OID prof_oid;
+ int num_sp_param; /*Number of special profile arguments*/
+ int num_cds_objects; /*Number of Conceptual Data Store objects*/
+ int num_css_objects; /*Number of Control Signal Status objects*/
+ int num_dev_objects; /*Number of Device Object identifiers*/
+ SPECIAL_OFFER sp_offer_list[MAXSPARGS];
+ CDS_OFFER cds_offer_list[MAXCDSOBJ];
+ CSS_OFFER css_offer_list[MAXCSSOBJ];
+ DEV_OFFER dev_offer_list[MAXDEVOBJ];
+ BIT_STR del_ctrl; /*Delivery Control*/
+} ARG_OFFER_LIST;
+
+typedef struct asq_msg
+{
+ int class; /*Basic only (=1)*/
+ int valid_imp;
+ IMPLEM_ID imp_id; /*Optional*/
+ BIT_STR func_units;
+ int valid_prof;
+ ARG_OFFER_LIST asq_profile; /*Profile is optional*/
+ BIT_STR version; /*Default = '1'B*/
+ int valid_coll;
+ int coll_winner; /*Optional*/
+} ASQ_MSG;
+
+typedef struct fail_reason
+{
+ int type; /*0 or 1*/
+ char *usr_reason;
+ int provider_reason; /* 1,2,3,or 4*/
+} FAIL_REASON;
+
+
+typedef struct font_value /*Repertoire Font Value*/
+{
+ int rep_type; /*1 = NULL; 2 = SEQUENCE....*/
+ char *rep_assign; /*0 value for pointer means not used*/
+ int valid_font_cap;
+ int capability;
+ int num_fonts;
+ char *font_names[MAXFONTS];
+} FONT_VALUE;
+
+typedef struct dimen_value
+{
+ int bound_type; /*0 for no bound, 1 for unbounded, 2 for
+ integer */
+ int bound;
+ int valid_addr;
+ int addressing; /*NOT optional according to 9041*/
+ int valid_abs;
+ int absolute; /*Optional*/
+ int window_type; /*0 for not used, 1 for unbounded, 2 for
+ integer */
+ int window;
+} DIMEN_VALUE;
+
+typedef struct rep_val_list /*Repertoire value list*/
+{
+ int valid_cap;
+ int capability;
+ int num_reps; /*Number of repertoires */
+ FONT_VALUE repertoire[MAXREPS];
+} REP_VALUE;
+
+typedef struct emp_value
+{
+ int valid_cap;
+ int capability;
+ int num_emps;
+ char *emp_string[MAXEMPS];
+} EMP_VALUE;
+
+typedef struct color_value
+{
+ int valid_cap;
+ int capability;
+ int num_colors;
+ char *color_string[MAXCOLORS];
+} COLOR_VALUE;
+
+typedef struct cds_value
+{
+ char *obj_name;
+ int dimensions; /*0 if not valid*/
+ int valid_x_dim;
+ DIMEN_VALUE x_dim;
+ int valid_y_dim;
+ DIMEN_VALUE y_dim;
+ int valid_z_dim;
+ DIMEN_VALUE z_dim;
+ int valid_erasure;
+ int erasure;
+ int valid_rep_list;
+ REP_VALUE rep_value;
+ int valid_emp_list;
+ EMP_VALUE emp_value;
+ int valid_fore_color;
+ COLOR_VALUE fore_color_list;
+ int valid_back_color;
+ COLOR_VALUE back_color_list;
+ int valid_access_right;
+ int access_right;
+} CDS_VALUE;
+
+typedef struct css_value /*Unused in TELNET */
+{
+ int i; /*For compiler*/
+} CSS_VALUE;
+
+typedef struct dev_value /*Also unused*/
+{
+ int i; /*For compiler*/
+} DEV_VALUE;
+
+typedef struct special_value
+{
+ int param_num;
+ int param_type; /*0,1,or2*/
+ union
+ {
+ int bool_arg; /*Turns into bitstring = 0 or 1*/
+ int int_arg;
+ char *string_arg;
+ } args;
+} SPECIAL_VALUE;
+
+typedef struct arg_val_list
+{
+ int num_sp_param; /*Number of special profile arguments*/
+ int num_cds_objects; /*Number of Conceptual Data Store objects*/
+ int num_css_objects; /*Number of Control Signal Status objects*/
+ int num_dev_objects; /*Number of Device Object identifiers*/
+ SPECIAL_VALUE sp_val[MAXSPARGS];
+ CDS_VALUE cds_val[MAXCDSOBJ];
+ CSS_VALUE css_val[MAXCSSOBJ];
+ DEV_VALUE dev_val[MAXDEVOBJ];
+ int del_ctrl; /*Delivery Control*/
+} ARG_VAL_LIST;
+
+typedef struct asr_msg
+{
+ int valid_reason; /*1 if reason is supplied*/
+ FAIL_REASON reason; /*Optional*/
+ int result; /*0,1, or 2*/
+ int valid_imp; /*1 if implementation i.d is supplied*/
+ IMPLEM_ID imp_id; /*Optional*/
+ BIT_STR version; /*Only '1'B now valid*/
+ int valid_arg_list;
+ ARG_VAL_LIST arg_list;
+ BIT_STR func_units;
+ int valid_coll; /*Is collision_winner valid?*/
+ int coll_winner; /*Optional (0,1,2)*/
+} ASR_MSG;
+
+
--- /dev/null
+/* sector5.h - VTPM: FSM sector 5 definitions */
+
+/*
+ * $Header: /f/osi/vt/RCS/sector5.h,v 7.1 91/02/22 09:48:10 mrose Interim $
+ *
+ *
+ * $Log: sector5.h,v $
+ * Revision 7.1 91/02/22 09:48:10 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:41 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+typedef struct expl_ptr {
+#define NULLCOORD -1
+ int xval; /* if they don't exist = NULLCOORD */
+ int yval;
+ int zval;
+} EXPL_PTR;
+
+#define NOBKTOK -1 /* for token in S mode */
+
+typedef struct bkq_content {
+ int token_val; /* 0 initiator, 1 acceptor, 2 accChoice or nobktok */
+ EXPL_PTR ExplPtr;
+} BKQ_content;
+
+
+typedef struct bkr_content {
+ int token_val; /* 0 initiator, 1 acceptor or nobktok */
+ EXPL_PTR ExplPtr;
+} BKR_content;
+
+typedef struct br_cnt {
+ BKQ_content BKQcont;
+ BKR_content BKRcont;
+ EXPL_PTR ExPtr;
+} BRcnt;
+
--- /dev/null
+-- VTPM: encode ASQ PDU
+
+-- $Header: /f/osi/vt/RCS/send_asq.py,v 7.1 91/02/22 09:48:13 mrose Interim $
+--
+--
+-- $Log: send_asq.py,v $
+-- Revision 7.1 91/02/22 09:48:13 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:42 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+ASQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m,n;
+
+#ifdef PEPYTEST
+
+char *myname;
+ASQ_MSG ud;
+static char my_version = 0x01;
+static char my_fu = 0x1c;
+static char a_char = 0x01;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+ PE pe;
+ int i,j;
+
+ myname = argv[0];
+
+ ud.class = 1;
+ ud.valid_prof = 1;
+ ud.valid_imp = 0;
+ ud.valid_coll = 0;
+ ud.version.bitstring = my_version;
+ ud.version.bitcount = 1;
+ ud.func_units.bitstring = my_fu;
+ ud.func_units.bitcount = 5;
+ ud.asq_profile.oid_true = 1;
+ ud.asq_profile.prof_oid = ode2oid("telnet");
+ ud.asq_profile.num_sp_param = 1;
+ ud.asq_profile.num_cds_objects = 2;
+ ud.asq_profile.num_css_objects = 0;
+ ud.asq_profile.num_dev_objects = 0;
+ ud.asq_profile.sp_offer_list[0].param_num = 1;
+ ud.asq_profile.sp_offer_list[0].param_type = 1;
+ ud.asq_profile.sp_offer_list[0].args.int_arg.type = 0;
+ ud.asq_profile.sp_offer_list[0].args.int_arg.value = 80;
+
+ ud.asq_profile.cds_offer_list[0].obj_name = "KB";
+ ud.asq_profile.cds_offer_list[1].obj_name = "DI";
+ for(i=0; i<ud.asq_profile.num_cds_objects; i++)
+ {
+ ud.asq_profile.cds_offer_list[i].valid_x_dim = 0;
+ ud.asq_profile.cds_offer_list[i].valid_y_dim = 0;
+ ud.asq_profile.cds_offer_list[i].valid_z_dim = 0;
+ ud.asq_profile.cds_offer_list[i].erasure.bitcount = 0;
+ ud.asq_profile.cds_offer_list[i].valid_rep_list = 1;
+ ud.asq_profile.cds_offer_list[i].valid_emp_list = 0;
+ ud.asq_profile.cds_offer_list[i].valid_fore_color = 0;
+ ud.asq_profile.cds_offer_list[i].valid_back_color = 0;
+ ud.asq_profile.cds_offer_list[i].access_right.bitcount = 0;
+ ud.asq_profile.cds_offer_list[i].rep_offer.valid_cap = 1;
+ ud.asq_profile.cds_offer_list[i].rep_offer.capability.type = 0;
+ ud.asq_profile.cds_offer_list[i].rep_offer.capability.value = 1;
+ ud.asq_profile.cds_offer_list[i].rep_offer.num_reps = 1;
+ ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[0].rep_type = 2;
+ ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[0].rep_assign = "ABC";
+ ud.asq_profile.cds_offer_list[i].rep_offer.repertoire[0].valid_font_cap = 0;
+ }
+
+ build_ASQPDU_ASQpdu(&pe,1,NULL,NULLCP,&ud);
+
+ print_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,&ud);
+
+ rcv_asq(pe);
+
+ exit(0);
+}
+
+#endif
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+ASQpdu ::= CHOICE <<1>>
+
+{
+ asqpdu [0] IMPLICIT ASQcontent [[p (PEPYPARM)parm]]
+}
+
+ASQcontent
+%{
+ ASQ_MSG *arg = (ASQ_MSG *)parm;
+%}
+ ::= SEQUENCE
+{
+ [0] IMPLICIT INTEGER [[i arg->class]],
+
+ [1] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+ OPTIONAL <<arg->valid_imp>>,
+
+ [2] IMPLICIT BITSTRING
+ [[x int2strb (arg->func_units.bitstring, arg->func_units.bitcount)
+ $ arg->func_units.bitcount]],
+
+ [3] IMPLICIT Profile [[p (PEPYPARM)&(arg->asq_profile)]]
+ OPTIONAL <<arg->valid_prof>>,
+
+ [4] IMPLICIT BITSTRING
+ [[x int2strb (arg->version.bitstring, arg->version.bitcount)
+ $ arg->version.bitcount]],
+
+ [5] IMPLICIT INTEGER [[i arg->coll_winner]]
+ OPTIONAL <<arg->valid_coll>>
+}
+
+ImplemIdent
+%{
+ IMPLEM_ID *arg = (IMPLEM_ID *)parm;
+%}
+ ::= SEQUENCE
+{
+ impIdent [0] IMPLICIT OBJECT IDENTIFIER
+ [[O arg->imp_oid]]
+ OPTIONAL <<arg->oid_true>>,
+
+ impName [1] IMPLICIT PrintableString
+ [[s arg->name]]
+ OPTIONAL <<arg->name_true>>,
+
+ impVersion [2] IMPLICIT PrintableString
+ [[s arg->version]]
+ OPTIONAL <<arg->version_true>>
+}
+
+Profile
+%{
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::= SEQUENCE
+{
+ name OBJECT IDENTIFIER [[O arg->prof_oid]]
+ OPTIONAL <<arg->oid_true>>,
+
+ ProfileArgList [[p parm]]
+ OPTIONAL <<arg->num_sp_param +
+ arg->num_cds_objects +
+ arg->num_css_objects +
+ arg->num_dev_objects>>
+
+}
+
+ProfileArgList
+%{
+ int j,k;
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::=
+
+SEQUENCE OF <<n=0; n<(arg->num_sp_param
+ + (arg->num_cds_objects?1:0)); n++>>
+
+ CHOICE <<(n<arg->num_sp_param) ? 1 : 2>>
+ {
+ specialArgs [0] IMPLICIT SEQUENCE
+ %{k=1;%}
+ {
+ identifier INTEGER
+ [[i arg->sp_offer_list[n].param_num]],
+
+ offeredValues CHOICE
+ <<arg->sp_offer_list[n].param_type + 1>>
+ {
+ boolean [0] IMPLICIT BITSTRING
+ [[x arg->sp_offer_list[n].args.bool_arg $ k]],
+
+ integer [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->sp_offer_list[n].args.int_arg)]],
+
+ string [2] IMPLICIT SET OF <<j=0; j<1; j++>>
+ PrintableString
+ [[s arg->sp_offer_list[n].args.string_arg]]
+ }
+ },
+
+ vteParams [1] IMPLICIT ParamOfferList [[p parm]]
+ }
+
+ParamOfferList
+%{
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::= SEQUENCE
+{
+ displayObjects [0] IMPLICIT CDSOffer [[p parm]]
+ OPTIONAL <<arg->num_cds_objects>>,
+
+-- controlObjects [1] IMPLICIT CSSOffer [[p parm]]
+-- OPTIONAL <<arg->num_css_objects>>,
+
+-- deviceObjects [2] IMPLICIT DEVOffer [[p parm]]
+-- OPTIONAL <<arg->num_dev_objects>>,
+
+ deliveryControl [3] IMPLICIT BITSTRING
+ [[x int2strb (arg->del_ctrl.bitstring, arg->del_ctrl.bitcount)
+ $ arg->del_ctrl.bitcount]]
+ OPTIONAL <<arg->del_ctrl.bitcount>>
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below. PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous. At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSOffer
+%{
+ ARG_OFFER_LIST *arg = (ARG_OFFER_LIST *)parm;
+%}
+ ::= SET OF <<l=0; l<arg->num_cds_objects; l++>> SEQUENCE
+{
+ objectName PrintableString
+ [[s arg->cds_offer_list[l].obj_name]],
+
+ ObjectOffer [[p (PEPYPARM)&(arg->cds_offer_list[l])]]
+}
+
+CSSOffer ::= NULL --Unused for now--
+
+DEVOffer ::= NULL --Unused for now--
+
+ObjectOffer
+%{
+ CDS_OFFER *arg = (CDS_OFFER *)parm;
+%}
+ ::= SEQUENCE
+{
+ dimensionOffer [0] IMPLICIT BITSTRING
+ [[x int2strb (arg->dimensions.bitstring,
+ arg->dimensions.bitcount) $ arg->dimensions.bitcount]]
+ OPTIONAL <<arg->dimensions.bitcount>>,
+
+ xParamOffer [1] IMPLICIT DimOffer [[p (PEPYPARM)&(arg->x_dim)]]
+ OPTIONAL <<arg->valid_x_dim>>,
+
+ yParamOffer [2] IMPLICIT DimOffer [[p (PEPYPARM)&(arg->y_dim)]]
+ OPTIONAL <<arg->valid_y_dim>>,
+
+ zParamOffer [3] IMPLICIT DimOffer [[p (PEPYPARM)&(arg->y_dim)]]
+ OPTIONAL <<arg->valid_z_dim>>,
+
+-- erasuroffer [4] IMPLICIT BITSTRING
+-- [[x int2strb (arg->erasure.bitstring,
+-- arg->erasure.bitcount)
+-- $ arg->erasure.bitcount]]
+-- OPTIONAL <<arg->erasure.bitcount>>,
+
+ repOfferList [5] IMPLICIT CompRepOffer [[p (PEPYPARM)&(arg->rep_offer)]]
+ OPTIONAL <<arg->valid_rep_list>>,
+
+-- empOfferList [6] IMPLICIT CompEmpOffer [[p (PEPYPARM)&(arg->emp_offer)]]
+-- OPTIONAL <<arg->valid_emp_list>>,
+
+-- foreColorList [7] IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->fore_color_list)]]
+-- OPTIONAL <<arg->valid_fore_color>>,
+
+-- backColorList [8] IMPLICIT ColorOffer [[p (PEPYPARM)&(arg->back_color_list)]]
+-- OPTIONAL <<arg->valid_back_color>>,
+
+ objectAccRight [9] IMPLICIT BITSTRING
+ [[x int2strb (arg->access_right.bitstring,
+ arg->access_right.bitcount)
+ $ arg->access_right.bitcount]]
+ OPTIONAL <<arg->access_right.bitcount>>
+}
+
+DimOffer
+%{
+ DIMEN_PARAM *arg = (DIMEN_PARAM *)parm;
+%}
+ ::= SEQUENCE
+{
+ bound [0] IMPLICIT SEQUENCE
+ {
+ unbounded NULL
+ OPTIONAL <<arg->bound_type == 1>>,
+
+ limit IntOffer [[p (PEPYPARM)&(arg->bound)]]
+ OPTIONAL <<arg->bound_type == 2>>
+ }
+ OPTIONAL <<arg->bound_type>>,
+
+ addressing [1] IMPLICIT BITSTRING
+ [[x int2strb (arg->addressing.bitstring,
+ arg->addressing.bitcount)
+ $ arg->addressing.bitcount]]
+ OPTIONAL <<arg->addressing.bitcount>>,
+
+ absolute [2] IMPLICIT BITSTRING
+ [[x int2strb (arg->absolute.bitstring,
+ arg->absolute.bitcount)
+ $ arg->absolute.bitcount]]
+ OPTIONAL <<arg->absolute.bitcount>>,
+
+ window [3] IMPLICIT SEQUENCE
+ {
+ unbounded NULL
+ OPTIONAL <<arg->window_type == 1>>,
+
+ limit IntOffer [[p (PEPYPARM)&(arg->window)]]
+ OPTIONAL <<arg->window_type == 2>>
+ }
+ OPTIONAL <<arg->window_type>>
+}
+
+CompRepOffer
+%{
+ REP_LIST *arg = (REP_LIST *)parm;
+%}
+ ::= SEQUENCE
+{
+ repCapability [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+ OPTIONAL <<arg->valid_cap>>,
+
+ [1] IMPLICIT SEQUENCE OF <<m=0; m<arg->num_reps; m++>>
+ RepFontOffer [[p (PEPYPARM)&(arg->repertoire[m])]]
+ OPTIONAL <<arg->num_reps>>
+}
+
+RepFontOffer
+%{
+ int i;
+ REP_FONT *arg = (REP_FONT *)parm;
+%} ::=
+CHOICE <<arg->rep_type>>
+{
+ NULL,
+
+ SEQUENCE
+ {
+ repertoire [0] IMPLICIT PrintableString
+ [[s arg->rep_assign]]
+ OPTIONAL <<arg->rep_assign>>,
+
+ fontCapability [1] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+ OPTIONAL <<arg->valid_font_cap>>,
+
+ [2] IMPLICIT SEQUENCE OF
+ <<i=0; i<arg->num_fonts; i++>>
+ PrintableString
+ [[s arg->font_names[i] ]]
+ OPTIONAL <<arg->num_fonts>>
+ }
+}
+
+--CompEmpOffer
+--%{
+-- int i;
+-- EMP_LIST *arg = (EMP_LIST *)parm;
+--%} ::= SEQUENCE
+--{
+-- empCap [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+-- OPTIONAL <<arg->valid_cap>>,
+
+-- SEQUENCE OF <<i=0; i<arg->num_emps; i++>>
+-- PrintableString
+-- [[s arg->emp_string[i] ]]
+-- OPTIONAL <<arg->num_emps>>
+--}
+
+--ColorOffer
+--%{
+-- int i;
+-- COLOR_LIST *arg = (COLOR_LIST *)parm;
+--%} ::= SEQUENCE
+--{
+-- colorCap [0] IMPLICIT IntOffer [[p (PEPYPARM)&(arg->capability)]]
+-- OPTIONAL <<arg->valid_cap>>,
+
+-- colorNames SEQUENCE OF <<i=0; i<arg->num_colors; i++>>
+-- PrintableString
+-- [[s arg->color_string[i] ]]
+-- OPTIONAL <<arg->num_colors>>
+--}
+
+IntOffer
+%{
+ int i;
+ INT_OFFER *arg = (INT_OFFER *)parm;
+%} ::= SEQUENCE OF <<i=0; i<1; i++>>
+
+ CHOICE <<arg->type + 1>>
+ {
+ indivValue [0] IMPLICIT INTEGER
+ [[i arg->value]],
+
+ range [1] IMPLICIT SEQUENCE
+ {
+ INTEGER [[i arg->min_val]],
+ INTEGER [[i arg->max_val]]
+ }
+ }
+
+END
+
+%{
+
+#ifdef PEPYTEST
+
+void advise(what,fmt,a,b,c,d,e,f,g,h,i,j)
+char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;
+{
+
+ (void) fflush(stdout);
+
+ fprintf(stderr,"%s: ",myname);
+ fprintf(stderr,fmt,a,b,c,d,e,f,g,h,i,j);
+ if(what)
+ (void) fputc(' ',stderr),perror(what);
+ else
+ (void) fputc('\n',stderr);
+ (void)fflush(stderr);
+}
+
+
+testdebug(pe,words)
+PE pe; /*Not Really, but pretend*/
+char *words;
+{
+
+ printf("%s \n",words);
+}
+
+#endif
+%}
--- /dev/null
+-- VTPM: encode ASR PDU
+
+-- $Header: /f/osi/vt/RCS/send_asr.py,v 7.1 91/02/22 09:48:15 mrose Interim $
+--
+--
+-- $Log: send_asr.py,v $
+-- Revision 7.1 91/02/22 09:48:15 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:43 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+ASRPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+static int l,m;
+
+#ifdef PEPYTEST
+
+char *myname;
+ASR_MSG ud;
+static char my_version = 0x01;
+static char my_fu = 0x1c;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+ PE pe;
+ int i;
+
+ myname = argv[0];
+
+ ud.valid_reason = 0;
+ ud.result = 1;
+ ud.valid_imp = 0;
+ ud.valid_arg_list = 1;
+ ud.version.bitstring = my_version;
+ ud.version.bitcount = 1;
+ ud.arg_list.num_sp_param = 1;
+ ud.arg_list.num_cds_objects = 2;
+ ud.arg_list.num_css_objects = 0;
+ ud.arg_list.num_dev_objects = 0;
+ ud.arg_list.sp_val[0].param_num = 1;
+ ud.arg_list.sp_val[0].param_type = 1;
+ ud.arg_list.sp_val[0].args.int_arg = 80;
+ ud.arg_list.cds_val[0].obj_name = "KB";
+ ud.arg_list.cds_val[1].obj_name = "DI";
+ for(i=0; i<ud.arg_list.num_cds_objects; i++)
+ {
+ ud.arg_list.cds_val[i].dimensions = 0;
+ ud.arg_list.cds_val[i].valid_x_dim = 0;
+ ud.arg_list.cds_val[i].valid_y_dim = 0;
+ ud.arg_list.cds_val[i].valid_z_dim = 0;
+ ud.arg_list.cds_val[i].valid_erasure = 0;
+ ud.arg_list.cds_val[i].valid_rep_list = 1;
+ ud.arg_list.cds_val[i].valid_emp_list = 0;
+ ud.arg_list.cds_val[i].valid_fore_color = 0;
+ ud.arg_list.cds_val[i].valid_back_color = 0;
+ ud.arg_list.cds_val[i].valid_access_right = 0;
+ ud.arg_list.cds_val[i].rep_value.valid_cap = 1;
+ ud.arg_list.cds_val[i].rep_value.capability = 1;
+ ud.arg_list.cds_val[i].rep_value.num_reps = 1;
+ ud.arg_list.cds_val[i].rep_value.repertoire[0].rep_type = 2;
+ ud.arg_list.cds_val[i].rep_value.repertoire[0].rep_assign =
+ "ABC";
+ ud.arg_list.cds_val[i].rep_value.repertoire[0].valid_font_cap =
+ 0;
+ }
+ ud.func_units.bitstring = my_fu;
+ ud.func_units.bitcount = 5;
+
+ build_ASRPDU_ASRpdu(&pe,1,NULL,NULLCP,&ud);
+
+ print_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,&ud);
+
+ rcv_asr(pe);
+
+ exit(0);
+}
+
+#endif
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+ASRpdu ::= CHOICE <<1>>
+
+{
+ asrpdu [1] IMPLICIT ASRcontent [[p (PEPYPARM)parm]]
+}
+
+ASRcontent
+%{
+ ASR_MSG *arg = (ASR_MSG *)parm;
+%}
+ ::= SEQUENCE
+{
+ userReason [0] IMPLICIT PrintableString [[s arg->reason.usr_reason]]
+ OPTIONAL <<(arg->valid_reason && (arg->reason.type == 0))>>,
+
+ provReason [1] IMPLICIT INTEGER [[i arg->reason.provider_reason]]
+ OPTIONAL <<(arg->valid_reason && (arg->reason.type == 1))>>,
+
+ [2] IMPLICIT INTEGER [[i arg->result]],
+
+ [3] IMPLICIT ImplemIdent [[p (PEPYPARM)&(arg->imp_id)]]
+ OPTIONAL <<arg->valid_imp>>,
+
+ [4] IMPLICIT BITSTRING
+ [[x int2strb (arg->version.bitstring, arg->version.bitcount)
+ $ arg->version.bitcount]],
+
+ [5] IMPLICIT ArgumValueList [[p (PEPYPARM)&(arg->arg_list)]]
+ OPTIONAL <<arg->valid_arg_list>>,
+
+ [6] IMPLICIT BITSTRING
+ [[x int2strb (arg->func_units.bitstring, arg->func_units.bitcount)
+ $ arg->func_units.bitcount]],
+
+ [7] IMPLICIT INTEGER [[i arg->coll_winner]]
+ OPTIONAL <<arg->valid_coll>>
+}
+
+ImplemIdent
+%{
+ IMPLEM_ID *arg = (IMPLEM_ID *)parm;
+%}
+ ::= SEQUENCE
+{
+ impIdent [0] IMPLICIT OBJECT IDENTIFIER
+ [[O arg->imp_oid]]
+ OPTIONAL <<arg->oid_true>>,
+
+ impName [1] IMPLICIT PrintableString
+ [[s arg->name]]
+ OPTIONAL <<arg->name_true>>,
+
+ impVersion [2] IMPLICIT PrintableString
+ [[s arg->version]]
+ OPTIONAL <<arg->version_true>>
+}
+
+ArgumValueList
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= SET OF <<l=0; l<(arg->num_sp_param
+ + (arg->num_cds_objects?1:0)); l++>> Goobers [[p parm]]
+
+Goobers
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= CHOICE <<(l < arg->num_sp_param) ? 1 : 2>>
+{
+ [0] IMPLICIT SpecialArgs [[p (PEPYPARM)&(arg->sp_val[l])]],
+ vteParams [1] IMPLICIT ParamValueList [[p parm]]
+}
+
+SpecialArgs
+%{
+ SPECIAL_VALUE *arg = (SPECIAL_VALUE *)parm;
+%}
+ ::= SEQUENCE
+{
+ identifier INTEGER [[i arg->param_num]],
+ value CHOICE <<arg->param_type + 1>>
+ {
+ BOOLEAN [[b arg->args.bool_arg]],
+ INTEGER [[i arg->args.int_arg]],
+ PrintableString[[s arg->args.string_arg]]
+ }
+}
+
+ParamValueList
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= SEQUENCE
+{
+ displayObjects [0] IMPLICIT CDSValues [[p parm]]
+ OPTIONAL <<arg->num_cds_objects>>,
+
+-- controlObjects [1] IMPLICIT CSSValues [[p parm]]
+-- OPTIONAL <<arg->num_css_objects>>,
+
+-- deviceObjects [2] IMPLICIT DEVValues [[p parm]]
+-- OPTIONAL <<arg->num_dev_objects>>,
+
+ deliveryControl [3] IMPLICIT INTEGER
+ [[i arg->del_ctrl]]
+ OPTIONAL <<arg->del_ctrl>>
+}
+
+--Note Problem with IMPLICIT SEQUENCE Definition below. PEPY does not accept
+--it as defined in 9041 and in fact that definition is ridiculous. At the
+--moment it is not clear if even hand coding available in ISODE 3.0 can
+--produce the requirement of 9041.
+
+CDSValues
+%{
+ ARG_VAL_LIST *arg = (ARG_VAL_LIST *)parm;
+%}
+ ::= SET OF <<l=0; l<arg->num_cds_objects; l++>> SEQUENCE
+{
+ objectName PrintableString
+ [[s arg->cds_val[l].obj_name]],
+
+ ObjectOffer [[p (PEPYPARM)&(arg->cds_val[l])]]
+}
+
+CSSValues ::= NULL --Unused for now--
+
+DEVValues ::= NULL --Unused for now--
+
+ObjectOffer
+%{
+ CDS_VALUE *arg = (CDS_VALUE *)parm;
+%}
+ ::= SEQUENCE
+{
+ dimensionValue [0] IMPLICIT INTEGER
+ [[i arg->dimensions]]
+ OPTIONAL <<arg->dimensions>>,
+
+ xParamValue [1] IMPLICIT DimValue [[p
+ (PEPYPARM)&(arg->x_dim)]]
+ OPTIONAL <<arg->valid_x_dim>>,
+
+ yParamValue [2] IMPLICIT DimValue [[p (PEPYPARM)&(arg->y_dim)]]
+ OPTIONAL <<arg->valid_y_dim>>,
+
+ zParamValue [3] IMPLICIT DimValue [[p (PEPYPARM)&(arg->z_dim)]]
+ OPTIONAL <<arg->valid_z_dim>>,
+
+-- erasurevalue [4] IMPLICIT BOOLEAN
+-- [[b arg->erasure]]
+-- OPTIONAL <<arg->valid_erasure>>,
+
+ repValueList [5] IMPLICIT CompRepValue [[p (PEPYPARM)&(arg->rep_value)]]
+ OPTIONAL <<arg->valid_rep_list>>,
+
+-- empValueList [6] IMPLICIT CompEmpValue [[p (PEPYPARM)&(arg->emp_value)]]
+-- OPTIONAL <<arg->valid_emp_list>>,
+
+-- foreColorVal [7] IMPLICIT ColorValue [[p (PEPYPARM)&(arg->fore_color_list)]]
+-- OPTIONAL <<arg->valid_fore_color>>,
+
+-- backColorVal [8] IMPLICIT ColorValue [[p (PEPYPARM)&(arg->back_color_list)]]
+-- OPTIONAL <<arg->valid_back_color>>,
+
+ objectAccRight [9] IMPLICIT INTEGER
+ [[i arg->access_right]]
+ OPTIONAL <<arg->valid_access_right>>
+}
+
+DimValue
+%{
+ DIMEN_VALUE *arg = (DIMEN_VALUE *)parm;
+%}
+ ::= SEQUENCE
+{
+ bound [0] CHOICE
+ <<arg->bound_type>>
+ {
+ unbounded NULL,
+
+ limit INTEGER
+ [[i arg->bound]]
+ }
+ OPTIONAL <<arg->bound_type>>,
+
+ addressing [1] IMPLICIT INTEGER
+ [[i arg->addressing]]
+ OPTIONAL <<arg->valid_addr>>,
+
+ absolute [2] IMPLICIT INTEGER
+ [[i arg->absolute]]
+ OPTIONAL <<arg->valid_abs>>,
+
+ window [3] CHOICE
+ <<arg->window_type>>
+ {
+ unbounded NULL,
+
+ limit INTEGER
+ [[i arg->window]]
+ }
+ OPTIONAL <<arg->window_type>>
+}
+
+CompRepValue
+%{
+ REP_VALUE *arg = (REP_VALUE *)parm;
+%}
+ ::= SEQUENCE
+{
+ repCapability [0] IMPLICIT INTEGER
+ [[i arg->capability]]
+ OPTIONAL <<arg->valid_cap>>,
+
+ [1] IMPLICIT SEQUENCE OF <<m=0; m<arg->num_reps; m++>>
+ RepFontValue [[p (PEPYPARM)&(arg->repertoire[m])]]
+ OPTIONAL <<arg->num_reps>>
+}
+
+RepFontValue
+%{
+ int i;
+ FONT_VALUE *arg = (FONT_VALUE *)parm;
+%} ::=
+CHOICE <<arg->rep_type>>
+{
+ NULL,
+
+ SEQUENCE
+ {
+ repertoire [0] IMPLICIT PrintableString
+ [[s arg->rep_assign]]
+ OPTIONAL <<arg->rep_assign>>,
+
+ fontCapability [1] IMPLICIT INTEGER
+ [[i arg->capability]]
+ OPTIONAL <<arg->valid_font_cap>>,
+
+ [2] IMPLICIT SEQUENCE OF
+ <<i=0; i<arg->num_fonts; i++>>
+ PrintableString
+ [[s arg->font_names[i] ]]
+ OPTIONAL <<arg->num_fonts>>
+ }
+}
+
+--CompEmpValue
+--%{
+-- int i;
+-- EMP_VALUE *arg = (EMP_VALUE *)parm;
+--%} ::= SEQUENCE
+--{
+-- empCap [0] IMPLICIT INTEGER
+-- [[i arg->capability]]
+-- OPTIONAL <<arg->valid_cap>>,
+
+-- SEQUENCE OF <<i=0; i<arg->num_emps; i++>>
+-- PrintableString
+-- [[s arg->emp_string[i] ]]
+-- OPTIONAL <<arg->num_emps>>
+--}
+
+--ColorValue
+--%{
+-- int i;
+-- COLOR_VALUE *arg = (COLOR_VALUE *)parm;
+--%} ::= SEQUENCE
+--{
+-- colorCap [0] IMPLICIT INTEGER
+-- [[i arg->capability]]
+-- OPTIONAL <<arg->valid_cap>>,
+
+-- colorNames SEQUENCE OF <<i=0; i<arg->num_colors; i++>>
+-- PrintableString
+-- [[s arg->color_string[i] ]]
+-- OPTIONAL <<arg->num_colors>>
+--}
+
+END
+
+%{
+
+#ifdef PEPYTEST
+
+void advise(what,fmt,a,b,c,d,e,f,g,h,i,j)
+char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;
+{
+
+ (void) fflush(stdout);
+
+ fprintf(stderr,"%s: ",myname);
+ fprintf(stderr,fmt,a,b,c,d,e,f,g,h,i,j);
+ if(what)
+ (void) fputc(' ',stderr),perror(what);
+ else
+ (void) fputc('\n',stderr);
+ (void)fflush(stderr);
+}
+
+testdebug(pe,words)
+PE pe; /*Not Really, but pretend*/
+char *words;
+{
+
+ printf("%s \n",words);
+}
+
+#endif
+
+%}
--- /dev/null
+-- VTPM: encode NDQ PDU
+
+-- $Header: /f/osi/vt/RCS/send_text.py,v 7.1 91/02/22 09:48:16 mrose Interim $
+--
+--
+-- $Log: send_text.py,v $
+-- Revision 7.1 91/02/22 09:48:16 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:44 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+NDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+#undef PEPYTEST
+
+#ifdef PEPYTEST
+
+char *myname;
+int l;
+TEXT_UPDATE ud;
+
+TEXT_UPDATE *ndq_queue;
+
+main(argc,argv)
+int argc;
+char **argv;
+{
+
+ PE pe;
+
+ myname = argv[0];
+
+ ud.echo_sw = 1;
+ ud.type_sw = 0;
+ ud.updates.do_list.do_name = "display";
+ ud.updates.do_list.do_type = 5;
+ ud.updates.do_list.do_cmd.text_ud.text_ptr = "pissant";
+ ud.updates.do_list.do_cmd.text_ud.text_count = 7;
+
+ build_NDQPDU_NDQpdu(&pe,1,NULL,NULLCP,&ud);
+
+ print_NDQPDU_NDQpdu(pe,1,NULLIP,NULLVP,&ud);
+
+ if(unbuild_NDQPDU_NDQpdu(pe,1,NULLIP,NULLVP,NULLCP)==NOTOK)
+ (void)printf("Can't Unbuild\n");;
+
+ exit(0);
+}
+
+#endif
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+NDQpdu ::= CHOICE <<1>>
+
+{
+ ndqpdu [6] IMPLICIT NDQcontent [[p (PEPYPARM)parm]]
+}
+
+NDQcontent
+%{ int j; %} ::=
+ SEQUENCE OF <<j=0; j<1; j++>> VTsdi [[p (PEPYPARM)parm]]
+
+VTsdi
+%{
+ int j,k;
+ TEXT_UPDATE *arg = (TEXT_UPDATE *)parm;
+%}
+ ::= CHOICE <<arg->echo_sw + 1>> {
+ echoNow [0] IMPLICIT SEQUENCE OF <<k=0; k<1; k++>> ObjectUpdate
+ [[p (PEPYPARM)parm]],
+
+ notEchoNow [1] IMPLICIT SEQUENCE OF <<j=0; j<1; j++>> ObjectUpdate
+ [[p (PEPYPARM)parm]]
+}
+
+ObjectUpdate
+%{
+ int j;
+ TEXT_UPDATE *arg = (TEXT_UPDATE *)parm;
+%} ::=
+ CHOICE <<arg->type_sw + 1>> {
+ display [0] IMPLICIT SEQUENCE {
+ doName PrintableString
+ [[s arg->updates.do_list.do_name]],
+ SEQUENCE OF <<j=0; j<1; j++>>
+ DOupdate [[p (PEPYPARM)&(arg->updates.do_list)]]
+ },
+ control [1] IMPLICIT COupdate [[p (PEPYPARM)&(arg->updates.co_list)]]
+}
+
+
+DOupdate
+%{
+ DO_UPDATE *arg = (DO_UPDATE *)parm;
+%}
+ ::= CHOICE <<arg->do_type + 1>> {
+ nextXarray [0] IMPLICIT NULL,
+ nextYarray [1] IMPLICIT NULL,
+ ptr-relative [2] IMPLICIT ExplicitPointer [[p (PEPYPARM)&(arg->do_cmd.ptr_rel)]],
+ ptr-absolute [3] IMPLICIT Pointer [[p (PEPYPARM)&(arg->do_cmd.ptr_abs)]],
+ text [4] IMPLICIT OCTETSTRING
+ [[o arg->do_cmd.text_ud.text_ptr $ arg->do_cmd.text_ud.text_count]],
+
+ repeatText [5] IMPLICIT SEQUENCE {
+ finishAddress Pointer
+ [[p (PEPYPARM)&(arg->do_cmd.rpt_seq.fin_addr)]],
+
+ OCTETSTRING
+ [[o arg->do_cmd.rpt_seq.text $ arg->do_cmd.rpt_seq.text_count]]
+ },
+
+ writeAttr [6] IMPLICIT SEQUENCE {
+ AttrId [[p (PEPYPARM)&(arg->do_cmd.wrt_attrib)]],
+ AttrExtent [[p (PEPYPARM)&(arg->do_cmd.wrt_attrib)]]
+ },
+
+ erase [7] IMPLICIT SEQUENCE {
+ startErase Pointer[[p (PEPYPARM)&(arg->do_cmd.erase.start_erase)]],
+ endErase Pointer [[p (PEPYPARM)&(arg->do_cmd.erase.end_erase)]],
+ eraseAttr BOOLEAN
+ [[b arg->do_cmd.erase.erase_attr]]
+ },
+
+ previousXarray [8] IMPLICIT NULL,
+ previousYarray [9] IMPLICIT NULL
+ }
+
+COupdate
+%{
+ CO_UPDATE *arg = (CO_UPDATE *)parm;
+%}
+ ::= SEQUENCE {
+ coName PrintableString
+ [[s arg->co_name]],
+
+ objectUpdate CHOICE <<arg->co_type + 1>> {
+ characterUpdate [0] IMPLICIT PrintableString
+ [[s arg->co_cmd.char_update]],
+
+ booleanUpdate [1] IMPLICIT SEQUENCE {
+ values [0] IMPLICIT BITSTRING
+ [[x arg->co_cmd.bool_update.value $ arg->co_cmd.bool_update.val_count]],
+
+ mask [1] IMPLICIT BITSTRING
+ [[x arg->co_cmd.bool_update.mask $ arg->co_cmd.bool_update.mask_count]]
+ },
+
+ symbolicUpdate [2] IMPLICIT INTEGER
+ [[i arg->co_cmd.sym_update]],
+
+ integerUpdate [3] IMPLICIT INTEGER
+ [[i arg->co_cmd.int_update]],
+
+ bitStringUpdate [4] IMPLICIT BITSTRING
+ [[x int2strb (arg->co_cmd.bit_update.bitstring,
+ arg->co_cmd.bit_update.bitcount)
+ $ arg->co_cmd.bit_update.bitcount]]
+ }
+}
+
+ExplicitPointer
+%{
+ EX_POINTER *arg = (EX_POINTER *)parm;
+%}
+ ::= SEQUENCE {
+ x [0] IMPLICIT INTEGER
+ [[i arg->x_value]]
+ OPTIONAL
+ <<arg->x_true>>,
+
+ y [1] IMPLICIT INTEGER
+ [[i arg->y_value]]
+ OPTIONAL
+ <<arg->y_true>>,
+
+ z [2] IMPLICIT INTEGER
+ [[i arg->z_value]]
+ OPTIONAL
+ <<arg->z_true>>
+}
+
+Pointer
+%{
+ POINTER *arg = (POINTER *)parm;
+%}
+ ::= CHOICE <<arg->ptr_type + 1>> {
+ current [0] IMPLICIT NULL,
+ start [1] IMPLICIT NULL,
+ startY [2] IMPLICIT NULL,
+ startX [3] IMPLICIT NULL,
+ end [4] IMPLICIT NULL,
+ endY [5] IMPLICIT NULL,
+ endX [6] IMPLICIT NULL,
+ coords [7] IMPLICIT ExplicitPointer [[p (PEPYPARM)&(arg->e_ptr)]]
+}
+
+AttrId
+%{
+ ATTRIB *arg = (ATTRIB *)parm;
+%}
+ ::= CHOICE <<arg->attr_id + 1>> {
+ graphCharRep [0] IMPLICIT INTEGER
+ [[i arg->attr_val]],
+
+ foreColor [1] IMPLICIT INTEGER
+ [[i arg->attr_val]],
+
+ backColor [2] IMPLICIT INTEGER
+ [[i arg->attr_val]],
+
+ emphasis [3] IMPLICIT INTEGER
+ [[i arg->attr_val]],
+
+ font [4] IMPLICIT INTEGER
+ [[i arg->attr_val]]
+}
+
+AttrExtent
+%{
+ ATTRIB *arg = (ATTRIB *)parm;
+%}
+ ::= CHOICE <<arg->attr_ext + 1>> {
+ global [0] IMPLICIT NULL,
+ addrExtent [1] IMPLICIT SEQUENCE {
+ beginning Pointer [[p (PEPYPARM)&(arg->beg_p)]],
+ ending Pointer [[p (PEPYPARM)&(arg->end_p)]]
+ },
+ modalExtent [2] IMPLICIT NULL
+}
+
+END
+
+%{
+
+#ifdef PEPYTEST
+
+void advise(what,fmt,a,b,c,d,e,f,g,h,i,j)
+char *what, *fmt, *a, *b, *c, *d, *e, *f, *g, *h, *i, *j;
+{
+
+ (void) fflush(stdout);
+
+ fprintf(stderr,"%s: ",myname);
+ fprintf(stderr,fmt,a,b,c,d,e,f,g,h,i,j);
+ if(what)
+ (void) fputc(' ',stderr),perror(what);
+ else
+ (void) fputc('\n',stderr);
+ (void)fflush(stderr);
+}
+
+testdebug(pe,words)
+PE pe;
+char *words;
+{
+
+ printf("%s\n",words);
+}
+
+#endif
+
+%}
--- /dev/null
+-- VTPM: encode UDQ PDU
+
+-- $Header: /f/osi/vt/RCS/send_udq.py,v 7.1 91/02/22 09:48:18 mrose Interim $
+--
+--
+-- $Log: send_udq.py,v $
+-- Revision 7.1 91/02/22 09:48:18 mrose
+-- Interim 6.8
+--
+-- Revision 7.0 89/11/23 22:31:45 mrose
+-- Release 6.0
+--
+
+--
+-- NOTICE
+--
+-- Acquisition, use, and distribution of this module and related
+-- materials are subject to the restrictions of a license agreement.
+-- Consult the Preface in the User's Manual for the full terms of
+-- this agreement.
+--
+--
+
+
+UDQPDU DEFINITIONS ::=
+
+%{
+#include <stdio.h>
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+
+%}
+
+BEGIN
+
+SECTIONS build none none
+
+UDQpdu ::= CHOICE <<1>>
+
+{
+ udqpdu [7] IMPLICIT COupdate [[p (PEPYPARM)parm]]
+}
+
+
+COupdate
+%{
+ TEXT_UPDATE *ud = (TEXT_UPDATE *) parm;
+ CO_UPDATE *arg = (CO_UPDATE *) &(ud->updates.co_list);
+%}
+ ::= SEQUENCE {
+ coName PrintableString
+ [[s arg->co_name]],
+
+ objectUpdate CHOICE <<arg->co_type + 1>> {
+ characterUpdate [0] IMPLICIT PrintableString
+ [[s arg->co_cmd.char_update]],
+
+ booleanUpdate [1] IMPLICIT SEQUENCE {
+ values [0] IMPLICIT BITSTRING
+ [[x arg->co_cmd.bool_update.value $ arg->co_cmd.bool_update.val_count]],
+
+ mask [1] IMPLICIT BITSTRING
+ [[x arg->co_cmd.bool_update.mask $ arg->co_cmd.bool_update.mask_count]]
+ },
+
+ symbolicUpdate [2] IMPLICIT INTEGER
+ [[i arg->co_cmd.sym_update]],
+
+ integerUpdate [3] IMPLICIT INTEGER
+ [[i arg->co_cmd.int_update]],
+
+ bitStringUpdate [4] IMPLICIT BITSTRING
+ [[x int2strb (arg->co_cmd.bit_update.bitstring,
+ arg->co_cmd.bit_update.bitcount)
+ $ arg->co_cmd.bit_update.bitcount]]
+ }
+ }
+END
--- /dev/null
+/* states1.c - VTPM: FSM sector 1 states */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/states1.c,v 7.1 91/02/22 09:48:19 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/states1.c,v 7.1 91/02/22 09:48:19 mrose Interim $
+ *
+ *
+ * $Log: states1.c,v $
+ * Revision 7.1 91/02/22 09:48:19 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:46 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+
+#define undefined(s1,e1) \
+ adios (NULLCP, \
+ "undefined state/event: sector is 1, state is %s, event is %d", \
+ s1, e1)
+
+int
+s1_01(event, pe) /* sector 1, state 01 */
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case ASQ:
+ return(a1_17(pe));
+ case VASSreq:
+ return(a1_2(pe));
+ case APQ:
+ return(a1_107(pe));
+ case AUQ:
+ return(a1_107(pe));
+ case PAB:
+ return(a1_107(pe));
+ case VTAB:
+ return(a1_107(pe));
+ case VUABreq:
+ return(a1_107(pe));
+ default:
+ undefined ("01", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_02B(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case ASR:
+ return(a1_15(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("02B", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_02S(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case ASR:
+ return(a1_16(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("02S", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_03B(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case VASSrsp:
+ return(a1_3(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("03B", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_03S(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case VASSrsp:
+ return(a1_4(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("03S", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_10B(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case GTQ:
+ return(a1_107(pe));
+ case RLQ:
+ return(a1_25(pe));
+ case RTQ:
+ return(a1_5(pe));
+ case VRELreq:
+ return(a1_7(pe));
+ case SNQ:
+ return(a1_29(pe));
+ case SPQ:
+ return(a1_30(pe));
+ case VSNEGreq:
+ return(a1_11(pe));
+ case VSWPreq:
+ return(a1_13(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("10B", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_10N(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case GTQ:
+ return(a1_19(pe));
+ case RLQ:
+ return(a1_26(pe));
+ case SNQ:
+ return(a1_28(pe));
+ case SPQ:
+ return(a1_30(pe));
+ case VRQTreq:
+ return(a1_10(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("10N", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_10T(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case RTQ:
+ return(a1_27(pe));
+ case VGVTreq:
+ return(a1_6(pe));
+ case VRELreq:
+ return(a1_8(pe));
+ case VRQTreq:
+ return(a1_19(pe));
+ case VSNEGreq:
+ return(a1_12(pe));
+ case VSWPreq:
+ return(a1_14(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("10T", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_50B(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case DLQ:
+ return(a1_21(pe));
+ case GTQ:
+ return(a1_7(pe));
+ case NDQ_ntr:
+ return(a1_0(pe));
+ case NDQ_tr:
+ return(a1_1(pe));
+ case RLQ:
+ return(a1_22(pe));
+ case SNQ:
+ return(a1_23(pe));
+ case SPQ:
+ return(a1_24(pe));
+ case UDQ:
+ return(a1_18(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("50B", event); /* NOTREACHED */
+ }
+}
+
+
+int
+s1_51Q(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case DLQ:
+ return(a1_21(pe));
+ case NDQ_ntr:
+ return(a1_0(pe));
+ case NDQ_tr:
+ return(a1_1(pe));
+ case RLR:
+ return(a1_20(pe));
+ case RTQ:
+ return(a1_107(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("51Q", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_51R(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case VRELrsp:
+ return(a1_9(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("51R", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_51N(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case VRELrsp:
+ return(a1_9(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("51N", event); /* NOTREACHED */
+ }
+}
+
+int
+s1_51T(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case RLR:
+ return(a1_20(pe));
+ case RTQ:
+ return(a1_0(pe));
+ case UDQ:
+ return(a1_18(pe));
+ case APQ:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case AUQ:
+ a1_101(pe);
+ return(OK); /* NOTREACHED */
+ case PAB:
+ a1_100(pe);
+ return(OK); /* NOTREACHED */
+ case VTAB:
+ a1_103(pe);
+ return(OK); /* NOTREACHED */
+ case VUABreq:
+ a1_102(pe);
+ return(OK); /* NOTREACHED */
+ default:
+ undefined ("51T", event); /* NOTREACHED */
+ }
+}
--- /dev/null
+/* states5.c - VTPM: FSM sector 5 states */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/states5.c,v 7.1 91/02/22 09:48:20 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/states5.c,v 7.1 91/02/22 09:48:20 mrose Interim $
+ *
+ *
+ * $Log: states5.c,v $
+ * Revision 7.1 91/02/22 09:48:20 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:47 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+
+#define undefined(s1, e1) \
+ adios (NULLCP, \
+ "undefined state/event: sector is 5, state is %s, event is %d", \
+ s1, e1)
+
+int
+s5_400B(event, pe) /* sector 5, state 400B */
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case DLQ:
+ return(a5_35(pe));
+ case NDQ_ntr:
+ return(a5_3(pe));
+ case NDQ_tr:
+ return(a5_2(pe));
+ case UDQ:
+ return(a5_34(pe));
+ case HDQ:
+ return(a5_106(pe));
+ case VDATreq_h:
+ return(a5_11(pe));
+ case VDATreq_u:
+ return(a5_28(pe));
+ case RLQ:
+ return(a5_38(pe));
+ case BKQ:
+ return(a5_32(pe));
+ case VDATreq_n:
+ return(a5_1(pe));
+ case VDELreq:
+ return(a5_9(pe));
+ case VRELreq:
+ return(a5_17(pe));
+ case VBRKreq:
+ return(a5_5(pe));
+ default:
+ undefined ("400B", event); /* NOTREACHED */
+ }
+}
+
+/* ARGSUSED */
+int
+s5_402B(event, pe)
+ int event;
+ PE pe;
+{
+ undefined ("402B", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_420B(event, pe)
+ int event;
+ PE pe;
+{
+ undefined ("420B", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_422B(event, pe) /* sector 5, state 422B */
+ int event;
+ PE pe;
+{
+ undefined ("422B", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_40N(event, pe)
+ int event;
+ PE pe;
+{
+ undefined ("40N", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_40T(event, pe)
+ int event;
+ PE pe;
+{
+ undefined ("40T", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_42T(event, pe)
+ int event;
+ PE pe;
+{
+ undefined ("42T", event); /* NOTREACHED */
+}
+
+/* ARGSUSED */
+int
+s5_42N(event, pe)
+ int event;
+ PE pe;
+{
+ undefined ("42N", event); /* NOTREACHED */
+}
+
+
+s5_61(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case BKR:
+ return(a5_31(pe));
+ default:
+ undefined ("61", event); /* NOTREACHED */
+ }
+}
+int
+s5_62(event, pe)
+ int event;
+ PE pe;
+{
+ switch (event) {
+ case VBRKrsp:
+ return(a5_6(pe));
+ default:
+ undefined ("62", event); /* NOTREACHED */
+ }
+}
--- /dev/null
+.TH VT 1C "21 Nov 1988"
+.\" $Header: /f/osi/vt/RCS/vt.1c,v 7.1 91/02/22 09:48:21 mrose Interim $
+.\"
+.\"
+.\" $Log: vt.1c,v $
+.\" Revision 7.1 91/02/22 09:48:21 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:31:48 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+vt \- VT interactive remote login initiator
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B vt
+\%[-g]
+\%[-D]
+\%[-f]
+\%[-F logfile]
+\%[-B]
+\%[host]
+.in -.5i
+.SH DESCRIPTION
+The \fIvt\fR program implements the initiator side of
+a remote login service based on the Virtual Terminal (VT)
+standard and the VT TELNET profile from the NIST OSI Workshop
+Implementor's Agreements.
+.PP
+The user interface to the service is based on BSD 4.2 TELNET.
+Command mode is entered by typing an escape character (``^]'' by default)
+as in TELNET.
+.SH OPTIONS
+.TP
+.B -g
+Use only the G0 character set for the \fIascii\fR repertoire (graphics only).
+.TP
+.B -D
+Use the VT asynchronous default profile (see ISO 9040) rather than
+the TELNET profile.
+.TP
+.B -B
+Do not use the VT-BREAK functional unit (see ISO 9040) in negotiating
+the VT association.
+.TP
+.B -F logfile
+Sets the VT logfile.
+Note that the pathname of this file is interpreted relatively to the
+ISODE logging area.
+To have tracing information written to a file in the current
+directory,
+start the filename with \*(lq./\*(rq.
+.TP
+.B -f
+Do not read and execute the commands in the file \fI$HOME/.vtrc\fR on startup.
+.SH COMMANDS
+.TP
+.B open\0host
+Open an association with the remote login service on the named host.
+.TP
+.B close\fR
+Close the existing association.
+.TP
+.B quit\fR
+Close the association and exit the remote login initiator process.
+.TP
+.B escape
+Set the ``escape character'' used to enter command mode. Control characters
+may be specified as ``^'' followed by a single letter;
+e.g. ``control-X'' is ``^X''.
+.TP
+.B ayt
+Send an ``are you there'' message to the remote login server.
+.TP
+.B break
+Send a ``break'' message to flush data queued in both directions
+and interrupt the remote process.
+.TP
+.B help
+Print a description of the available commands.
+.TP
+.B set
+Configure the VT variables listed below.
+.TP
+.B status
+Prints the current status of VT.
+.TP
+.B suspend
+Suspend
+.IR vt .
+This command only works when the user is using the
+.IR csh .
+.PP
+VT commands in $HOME/.vtrc are executed when \fIvt\fR starts
+up unless the \fI-f\fR flag is used.
+.SH Variables
+.PP
+Variables that can be manipulated with the \fIset\fR
+command include:
+.TP
+.B crmod
+Toggle carriage return mode. When this mode is enabled
+any carriage return characters received from the remote
+host will be mapped into a carriage return and a line
+feed. This mode does not affect those characters
+typed by the user, only those received.
+.TP
+.B echo
+Sets the echo mode to remote (ie. responder echoes) with ``set
+echo remote'' or local (ie. initiator echoes) with ``set
+echo local''.
+.TP
+.B repertoire
+Sets the character set to \fIascii \fRor \fItransparent\fR
+(binary).
+.SH FILES
+.nf
+.ta \w'\*(EDisoentities 'u
+\*(EDisoentities ISODE application entity title database
+$HOME/\&.vtrc runcom file
+.fi
+.SH "SEE ALSO"
+vtd(8c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO DIS 9040, 9041:
+\fIInformation Processing Systems \-\-
+Virtual Terminal Service and Protocol\fR
+.br
+Implementation Agreements for Open Systems Interconnection Protocols
+.SH AUTHORS
+Rick Wilder and Don Chirieleison,
+The MITRE Corporation.
+.br
+Parts of this program are based on the \fItelnet\fR(1c) program supplied with
+Berkeley UNIX.
+.SH BUGS
+.PP
+\fIvt\fR and \fIvtd\fR need to be brought up to date with BSD 4.3(4?)
+TELNET.
+.PP
+The encodings of the VT PDUs may need to be updated when
+the International Standard version of ISO 9041 is available.
--- /dev/null
+/* vt.c - VT initiator */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vt.c,v 7.4 91/02/22 09:48:23 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/vt.c,v 7.4 91/02/22 09:48:23 mrose Interim $
+ *
+ *
+ * $Log: vt.c,v $
+ * Revision 7.4 91/02/22 09:48:23 mrose
+ * Interim 6.8
+ *
+ * Revision 7.3 90/12/23 18:43:29 mrose
+ * update
+ *
+ * Revision 7.2 90/01/11 18:38:13 mrose
+ * real-sync
+ *
+ * Revision 7.1 89/11/30 23:51:38 mrose
+ * pa2str
+ *
+ * Revision 7.0 89/11/23 22:31:49 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <signal.h>
+#include "vtpm.h"
+#include "sector1.h"
+#include "tailor.h"
+
+#include <sys/ioctl.h>
+#ifdef BSD44
+#include <sys/termios.h>
+#endif
+#include <ctype.h>
+#include <setjmp.h>
+#include <varargs.h>
+
+#define strip(x) ((x)&0177)
+#define TBUFSIZ 1024
+
+char ttyobuf[TBUFSIZ], *tfrontp = ttyobuf, *tbackp = ttyobuf;
+char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
+
+int connected;
+int net;
+int showoptions = 0;
+int options;
+int debug = 0;
+int crmod = 0;
+char escape = ']' & 037;
+static char *escapestr = "^]";
+
+VT_PROFILE vtp_profile;
+int rflag = 0;
+char erase_char; /*Unix Erase*/
+char erase_line; /*Unix Kill*/
+char intr_char; /*Unix Interrupt*/
+char *my_displayobj = "K"; /*Initiator's Display Object Name*/
+char *my_echo_obj = "NI"; /*Initiator's Negotiation Control Object*/
+char *my_signal_obj = "KB"; /*Initiator's Signal Control Object*/
+char *his_echo_obj = "NA"; /*Acceptor's Negotiation Control Object*/
+char *his_signal_obj = "DI"; /*Acceptor's Signal Control Object*/
+int my_right = INITIATOR;
+char kb_image; /*KB Control Object Image*/
+char di_image; /*DI Control Image*/
+char ni_image; /*NI Control Object Image*/
+char na_image; /*NA Control Object Image*/
+char nego_state; /*Current state of NI affected options*/
+char sync_image; /*SY Control Object*/
+char ga_image;
+int transparent = 0; /*Transparent Repertoire switch*/
+int telnet_profile = 1;
+int do_break = 1; /*If VT-BREAK Functional Unit agreed to*/
+char *myhostname;
+char peerhost[BUFSIZ];
+struct PSAPaddr ts_bound;
+int pty; /*Kludge for single map.c (sorry)*/
+
+char line[BUFSIZ];
+
+jmp_buf toplevel;
+jmp_buf peerdied;
+
+extern int errno;
+
+
+struct dispatch {
+ char *ds_name;
+ IFP ds_fnx;
+
+ int ds_flags;
+#define DS_NULL 0x00
+#define DS_OPEN 0x01 /* association required */
+#define DS_CLOSE 0x02 /* association avoided */
+
+ char *ds_help;
+};
+
+struct dispatch *getds ();
+
+
+int vt_open (), vt_close (), vt_quit (), vt_status (), vt_suspend ();
+int vt_ayt (), vt_break (), vt_escape ();
+int vt_set (), vt_help ();
+
+
+static struct dispatch dispatches[] = {
+ "ayt", vt_ayt, DS_OPEN,
+ "send \"are you there?\"",
+
+ "break", vt_break, DS_OPEN,
+ "send break",
+
+ "close", vt_close, DS_OPEN,
+ "release association with terminal service",
+
+ "escape", vt_escape, DS_NULL,
+ "set escape character (depreciated)",
+
+ "help", vt_help, DS_NULL,
+ "print help information",
+
+ "open", vt_open, DS_CLOSE,
+ "associate with terminal service",
+
+ "quit", vt_quit, DS_NULL,
+ "release association with terminal service and exit",
+
+ "set", vt_set, DS_NULL,
+ "display or change variables",
+
+ "status", vt_status, DS_OPEN,
+ "show current status",
+
+ "suspend", vt_suspend, DS_OPEN,
+ "suspend vtp",
+
+ NULL
+};
+
+
+SFD intr(), deadpeer();
+char *control(), *strdup ();
+
+#ifdef BSD44
+struct termios oterm;
+#else
+struct tchars otc;
+struct ltchars oltc;
+struct sgttyb ottyb;
+#endif
+
+static int runcom = 0;
+char *myname;
+static char *myhome;
+int tmode();
+
+LLog _vt_log = {
+ "./vt.log", NULLCP, NULLCP,
+ LLOG_NONE, LLOG_NONE, -1, LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+};
+LLog *vt_log = &_vt_log;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int i,
+ fflag;
+ char *logname,
+ buffer[BUFSIZ],
+ *vec[NVEC + 1];
+ FILE *fp;
+
+ if (myname = rindex (*argv, '/'))
+ myname++;
+ if (myname == NULL || *myname == NULL)
+ myname = *argv;
+
+ isodetailor (myname, 1);
+
+ ll_hdinit (vt_log, myname);
+
+ fflag = 0;
+ logname = 0;
+ myhostname = PLocalHostName ();
+ peerhost[0] = NULL;
+ acc = &accs;
+ acr = &acrs;
+ aci = &acis;
+
+#ifdef BSD44
+ if (tcgetattr(0, &oterm) == -1)
+ perror("tcgetattr");
+ erase_char = oterm.c_cc[VERASE];
+ erase_line = oterm.c_cc[VKILL];
+ intr_char = oterm.c_cc[VINTR];
+#else
+ if (ioctl(0, TIOCGETP, (char *)&ottyb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(0, TIOCGETC, (char *)&otc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(0, TIOCGLTC, (char *)&oltc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ erase_char = ottyb.sg_erase;
+ erase_line = ottyb.sg_kill;
+ intr_char = otc.t_intrc;
+#endif
+
+
+ setbuf(stdin, NULLCP);
+ setbuf(stdout, NULLCP);
+
+ bzero ((char *) &vtp_profile, sizeof vtp_profile);
+ vtp_profile.profile_name = "telnet";
+ vtp_profile.arg_val.tel_arg_list.x_window = ncols (stdin);
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+
+ for(i=1; i<argc; i++)
+ {
+ if (peerhost[0] == NULL && (*argv[i] != '-'))
+ {
+ (void) strcpy(peerhost,argv[i]);
+ }
+ else if(!strcmp(argv[i], "-g"))
+ {
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 0;
+ advise(LLOG_DEBUG,NULLCP,"using ASCII GO repertoire");
+ }
+ else if(!strcmp(argv[i], "-D"))
+ {
+ vtp_profile.profile_name = "default";
+ telnet_profile = 0;
+ my_displayobj = "DISPLAY-OBJECT-2";
+ advise(LLOG_DEBUG,NULLCP,"using default profile");
+ }
+ else if(!strcmp(argv[i],"-B"))
+ {
+ advise(LLOG_DEBUG,NULLCP,"VT-BREAK not chosen");
+ do_break = 0;
+ }
+ else if(!strcmp(argv[i], "-f"))
+ fflag++;
+ else if(!strcmp(argv[i], "-F"))
+ {
+ if ((logname = argv[++i]) == NULL || *logname == '-')
+ adios (NULLCP, "usage: %s -F logfile", myname);
+ vt_log -> ll_file = logname;
+ (void) ll_close (vt_log);
+ advise(LLOG_DEBUG,NULLCP, "logging to %s",logname);
+ }
+ else
+ adios("usage: %s [-g] [-D] [-B] [-f] [-F logfile] [hostname]",
+ myname);
+ }
+
+
+ runcom = 1;
+
+ rcinit ();
+ (void) sprintf (buffer, "%s/.vtrc", myhome);
+ if (!fflag && (fp = fopen (buffer, "r"))) {
+ register char *bp;
+
+ while (fgets (buffer, sizeof buffer, fp)) {
+ if (bp = index (buffer, '\n'))
+ *bp = NULL;
+
+ bzero ((char *) vec, sizeof vec);
+ if (str2vec (buffer, vec) < 1)
+ continue;
+
+ if (vtploop (vec, NOTOK) == NOTOK && peerhost[0])
+ exit (1);
+ }
+
+ (void) fclose (fp);
+ }
+
+ runcom = 0;
+
+ if (peerhost[0] != NULL) {
+ if (setjmp(toplevel) != 0)
+ exit(0);
+ do_vt();
+ }
+ (void) setjmp(toplevel);
+ for (;;)
+ command(1);
+}
+
+/* \f DISPATCH */
+
+command(top)
+ int top;
+{
+ int eof,oldmode;
+ char *vec[NVEC + 1];
+
+ oldmode = tmode(0);
+ if (!top)
+ (void) putchar('\n');
+ else
+ (void) signal (SIGINT, SIG_DFL);
+ eof = 0;
+ for (;;) {
+ if (getline ("%s> ", line) == NOTOK) {
+ if (eof) {
+ if (!connected)
+ exit (0);
+ (void) vt_status (NULLVP);
+ break;
+ }
+
+ eof = 1;
+ continue;
+ }
+ eof = 0;
+
+ bzero ((char *) vec, sizeof vec);
+ if (str2vec (line, vec) < 1)
+ break;
+
+ if (vtploop (vec, NOTOK) != DONE)
+ break;
+ }
+ if (!top) {
+ if (!connected)
+ longjmp(toplevel, 1);
+ (void) fflush (stdout);
+ (void) fflush (stderr);
+ (void) tmode(oldmode);
+ }
+}
+
+/* \f */
+
+static int vtploop (vec, error)
+char **vec;
+int error;
+{
+ register struct dispatch *ds;
+
+ if ((ds = getds (strcmp (*vec, "?") ? *vec : "help")) == NULL)
+ return error;
+
+ if (!connected) {
+ if (ds -> ds_flags & DS_OPEN) {
+ advise (LLOG_NOTICE,NULLCP, "not associated with terminal service");
+ return error;
+ }
+ }
+ else
+ if (ds -> ds_flags & DS_CLOSE) {
+ advise (LLOG_NOTICE,NULLCP,
+ "already associated with terminal service");
+ return error;
+ }
+
+ switch ((*ds -> ds_fnx) (vec)) {
+ case NOTOK:
+ return error;
+
+ case OK:
+ default:
+ return OK;
+
+ case DONE:
+ return DONE;
+ }
+}
+
+/* \f */
+
+int getline (prompt, buffer)
+char *prompt,
+ *buffer;
+{
+ register int i;
+ register char *cp,
+ *ep;
+ static int sticky = 0;
+
+ if (sticky) {
+ sticky = 0;
+ return NOTOK;
+ }
+
+ (void)printf (prompt, connected ? peerhost : myname);
+ (void) fflush (stdout);
+
+ for (ep = (cp = buffer) + BUFSIZ - 1; (i = getchar ()) != '\n';) {
+ if (i == EOF) {
+ (void)printf ("\n");
+ clearerr (stdin);
+ if (cp == buffer)
+ return NOTOK;
+
+ sticky++;
+ break;
+ }
+
+ if (cp < ep)
+ *cp++ = i;
+ }
+ *cp = NULL;
+
+ return OK;
+}
+
+/* \f */
+
+struct dispatch *getds (name)
+register char *name;
+{
+ register int longest,
+ nmatches;
+ register char *p,
+ *q;
+ char buffer[BUFSIZ];
+ register struct dispatch *ds,
+ *fs;
+
+ longest = nmatches = 0;
+ for (ds = dispatches; p = ds -> ds_name; ds++) {
+ for (q = name; *q == *p++; q++)
+ if (*q == NULL)
+ return ds;
+ if (*q == NULL)
+ if (q - name > longest) {
+ longest = q - name;
+ nmatches = 1;
+ fs = ds;
+ }
+ else
+ if (q - name == longest)
+ nmatches++;
+ }
+
+ switch (nmatches) {
+ case 0:
+ advise (LLOG_NOTICE,NULLCP, "unknown operation \"%s\"", name);
+ return NULL;
+
+ case 1:
+ return fs;
+
+ default:
+ for (ds = dispatches, p = buffer; q = ds -> ds_name; ds++)
+ if (strncmp (q, name, longest) == 0) {
+ (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
+ p += strlen (p);
+ }
+ advise (LLOG_NOTICE,NULLCP,
+ "ambiguous operation, it could be one of:%s",
+ buffer);
+ return NULL;
+ }
+}
+
+/* \f OPERATIONS */
+
+static int vt_open (vec)
+char **vec;
+{
+ if (*++vec == NULL) {
+ if (getline ("host: ", line) == NOTOK
+ || str2vecX (line, vec, 0, NULLIP, NULL, 0) < 1)
+ return NOTOK;
+ }
+
+ (void) strcpy (peerhost, *vec);
+ do_vt ();
+
+ return OK;
+}
+
+
+do_vt()
+{
+ (void) signal(SIGINT, intr);
+ (void) signal(SIGPIPE, deadpeer);
+ (void)printf("Trying...\n");
+ (void)fflush(stdout);
+
+ if ((fd = con_req()) < 0)
+ return;
+
+ connected++;
+ (void) vt_status (NULLVP);
+ (void)printf ("escape character is '%s'\n", escapestr);
+ if (setjmp(peerdied) == 0)
+ vt(fd);
+ adios (NULLCP, "association terminated by peer");
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int vt_close (vec)
+char **vec;
+{
+ (void) tmode(0);
+ vrelreq();
+ if (getch () >= -1) {
+ advise (LLOG_DEBUG,NULLCP, "flushing input queue...");
+ while (getch () >= -1)
+ continue;
+ }
+
+ /* read network events until the release sequence reached
+ the point where the other side shuts down
+ */
+
+ (void)printf ("association released\n");
+ (void)fflush (stdout);
+ connected = 0;
+ /* reset his options */
+
+ return OK;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int vt_quit (vec)
+char *vec;
+{
+ if (connected)
+ (void) vt_close (NULLVP);
+
+ exit(0); /* NOTREACHED */
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int vt_status (vec)
+char **vec;
+{
+ (void) printf ("associated with terminal service on \"%s\"\n at %s\n",
+ peerhost, pa2str (&ts_bound));
+ (void) printf (" using %s profile\n", vtp_profile.profile_name);
+
+ return OK;
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int vt_suspend (vec)
+char **vec;
+{
+ register int save;
+
+ save = tmode(0);
+ (void)kill(0, SIGTSTP);
+
+ /* reget parameters in case they were changed */
+#ifdef BSD44
+ if (tcgetattr(0, &oterm) == -1)
+ perror("tcgetattr");
+#else
+ if (ioctl(0, TIOCGETP, (char *)&ottyb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(0, TIOCGETC, (char *)&otc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (ioctl(0, TIOCGLTC, (char *)&oltc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+#endif
+ (void) tmode(save);
+
+ return OK;
+}
+
+/* \f */
+
+static int vt_escape (vec)
+char **vec;
+{
+ char c;
+
+ if (*++vec == NULL) {
+ if (getline ("new escape character: ", line) == NOTOK
+ || str2vec (line, vec) < 1)
+ return NOTOK;
+ }
+
+ if ((c = *vec[0]) != NULL) {
+ char *cp = control (escape = c);
+
+ free (escapestr);
+ escapestr = strdup (cp);
+ }
+ (void)printf ("escape character is '%s'\n", escapestr);
+
+ return OK;
+}
+
+/* \f VARIABLES */
+
+static char *debug_val[] = {
+ "0", "1", "2", "3", "4", "5", "6", "7", NULL
+};
+
+static char *bool[] = {
+ "off", "on", NULL
+};
+
+static char *emodes[] = {
+ "local", "remote", NULL
+};
+
+static char *rmodes[] = {
+ "ascii", "transparent", NULL
+};
+
+static char *xsaplevels[] = {
+ "none", "fatal", "exceptions", "notice", "pdus", "trace", "debug", NULL
+};
+
+
+struct var {
+ char *v_name;
+ IP v_value;
+
+ char *v_dname;
+ char **v_dvalue;
+ char *v_mask;
+
+ IFP v_hook;
+};
+
+struct var *getvar ();
+
+
+static int echo = 0;
+static int repertoire = 0;
+static int verbose = 0;
+
+int set_debug (), set_echo (), set_escape (), set_repertoire ();
+
+
+static struct var vars[] = {
+ "acsaplevel", &_acsap_log.ll_events, "ACSAP logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "acsapfile", NULLIP, "ACSAP trace file", &_acsap_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "addrlevel", &_addr_log.ll_events, "address logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "addrfile", NULLIP, "address trace file", &_addr_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "compatlevel", &_compat_log.ll_events, "COMPAT logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "compatfile", NULLIP, "COMPAT trace file", &_compat_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "crmod", &crmod, "map CR on output", bool, NULLCP, NULLIFP,
+
+ "debug", &debug, "debug VT", debug_val, NULLCP, set_debug,
+
+ "echo", &echo, "local or remote echoing", emodes, NULLCP, set_echo,
+
+ "escape", NULLIP, "escape character", &escapestr, NULLCP, set_escape,
+
+ "options", &showoptions, "show option processing", bool, NULLCP, NULLIFP,
+
+ "psaplevel", &_psap_log.ll_events, "PSAP logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "psapfile", NULLIP, "PSAP trace file", &_psap_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "psap2level", &_psap2_log.ll_events, "PSAP2 logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "psap2file", NULLIP, "PSAP2 trace file", &_psap2_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "repertoire", &repertoire, "terminal repertoire", rmodes, NULLCP,
+ set_repertoire,
+
+ "ssaplevel", &_ssap_log.ll_events, "SSAP logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "ssapfile", NULLIP, "SSAP trace file", &_ssap_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "tracelevel", &_vt_log.ll_events, "VT logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "tracefile", NULLIP, "VT trace file", &_vt_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "tsaplevel", &_tsap_log.ll_events, "TSAP logging", xsaplevels,
+ LLOG_MASK, NULLIFP,
+ "tsapfile", NULLIP, "TSAP trace file", &_tsap_log.ll_file, NULLCP,
+ NULLIFP,
+
+ "verbose", &verbose, "verbose interaction", bool, NULLCP, NULLIFP,
+
+ NULL
+};
+
+
+static int varwidth1;
+static int varwidth2;
+
+char **getval ();
+
+/* \f */
+
+static int vt_set (vec)
+char **vec;
+{
+ register int i,
+ j;
+ int value,
+ vflag;
+ register char **cp,
+ *dp;
+ register struct var *v;
+
+ if (*++vec == NULL) {
+ register int w;
+ int columns,
+ width,
+ lines;
+ register struct var *u;
+
+ for (u = vars; u -> v_name; u++)
+ continue;
+ width = varwidth1;
+
+ if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)
+ columns = 1;
+ lines = ((u - vars) + columns - 1) / columns;
+
+ (void)printf ("Variables:\n");
+ for (i = 0; i < lines; i++)
+ for (j = 0; j < columns; j++) {
+ v = vars + j * lines + i;
+ (void)printf ("%s", v -> v_name);
+ if (v + lines >= u) {
+ (void)printf ("\n");
+ break;
+ }
+ for (w = strlen (v -> v_name); w < width; w = (w + 8) & ~7)
+ (void) putchar ('\t');
+ }
+
+ return DONE;
+ }
+
+ echo = (nego_state & ECHO_OBJ) ? 1 : 0;
+ repertoire = transparent ? 1 : 0;
+
+ if (strcmp (*vec, "?") == 0) {
+ for (v = vars; v -> v_name; v++)
+ printvar (v);
+
+ return DONE;
+ }
+
+ if ((v = getvar (*vec)) == NULL)
+ return DONE;
+
+ if (*++vec == NULL) {
+ printvar (v);
+
+ return DONE;
+ }
+
+ if (strcmp (*vec, "?") == 0) {
+ if (v -> v_value && (cp = v -> v_dvalue)) {
+ printf ("use %s of:", v -> v_mask ? "any" : "one");
+ for (i = 0; *cp; cp++)
+ printf ("%s \"%s\"", i++ ? "," : "", *cp);
+ if (v -> v_mask)
+ printf (";\n\tor \"all\";\n\tor a hexadecimal number from 0 to 0x%x\n",
+ (1 << (i - 1)) - 1);
+ else
+ printf (";\n\tor a number from 0 to %d\n",
+ cp - v -> v_dvalue - 1);
+ }
+ else
+ (void)printf ("use any %s value\n",
+ v -> v_value ? "integer" : "string");
+
+ return DONE;
+ }
+
+ if (v -> v_value == NULLIP) {
+ register int w;
+
+ if (*v -> v_dvalue)
+ free (*v -> v_dvalue);
+ *v -> v_dvalue = strdup (*vec);
+ if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)
+ varwidth2 = w;
+ if (v -> v_hook)
+ (*v -> v_hook) (v);
+ if (verbose)
+ printvar (v);
+ return DONE;
+ }
+
+ if (v -> v_mask) {
+ if (strcmp (dp = *vec, "all") == 0 && (cp = v -> v_dvalue)) {
+ i = 1;
+ while (*++cp)
+ i <<= 1;
+ value = i - 1;
+ j = 1;
+ }
+ else {
+ if (strncmp (dp = *vec, "0x", 2) == 0)
+ dp += 2;
+ for (j = sscanf (dp, "%x", &value); *dp; dp++)
+ if (!isxdigit (*dp)) {
+ j = 0;
+ break;
+ }
+ }
+ }
+ else
+ j = sscanf (*vec, "%d", &value);
+
+ if (j == 1) {
+ if (cp = v -> v_dvalue) {
+ if (v -> v_mask) {
+ i = 1;
+ while (*++cp)
+ i <<= 1;
+ if (value >= i)
+ goto out_of_range;
+ }
+ else {
+ for (; *cp; cp++)
+ continue;
+ if (value >= cp - v -> v_dvalue) {
+out_of_range: ;
+ advise (LLOG_NOTICE,NULLCP,
+ "value out of range \"%s\"", *vec);
+
+ return DONE;
+ }
+ }
+ }
+
+ vflag = verbose;
+ *v -> v_value = value;
+ if (v -> v_hook)
+ (*v -> v_hook) (v);
+ if (vflag)
+ printvar (v);
+
+ return DONE;
+ }
+
+ if (v -> v_mask) {
+ i = 0;
+ for (; *vec; vec++) {
+ if (!(cp = getval (*vec, v -> v_dvalue))) {
+ advise (LLOG_NOTICE,NULLCP, "bad value \"%s\"", *vec);
+
+ return DONE;
+ }
+ if ((j = cp - v -> v_dvalue) <= 0)
+ continue;
+
+ i |= 1 << (j - 1);
+ }
+
+ vflag = verbose;
+ *v -> v_value = i;
+ if (v -> v_hook)
+ (*v -> v_hook) (v);
+ if (vflag)
+ printvar (v);
+
+ return DONE;
+ }
+
+ if (v -> v_dvalue && (cp = getval (*vec, v -> v_dvalue))) {
+ vflag = verbose;
+ *v -> v_value = cp - v -> v_dvalue;
+ if (v -> v_hook)
+ (*v -> v_hook) (v);
+ if (vflag)
+ printvar (v);
+ }
+ else
+ if (!v -> v_dvalue)
+ advise (LLOG_NOTICE,NULLCP, "bad value \"%s\"", *vec);
+
+ return DONE;
+}
+
+/* \f */
+
+static printvar (v)
+register struct var *v;
+{
+ int i;
+ char buffer[BUFSIZ];
+
+ if (runcom)
+ return;
+
+ (void)printf ("%-*s = ", varwidth1, v -> v_name);
+ if (v -> v_value) {
+ i = *v -> v_value;
+
+ if (v -> v_mask) {
+ if (v -> v_dvalue) {
+ if (i == 0)
+ (void)printf ("%-*s", varwidth2, v -> v_dvalue[i]);
+ else {
+ (void) strcpy (buffer, sprintb (i, v -> v_mask));
+ if (strlen (buffer) <= varwidth2)
+ (void)printf ("%-*s", varwidth2, buffer);
+ else
+ (void)printf ("%s\n%*s", buffer, varwidth1 + varwidth2 + 3,
+ "");
+ }
+ }
+ else
+ (void)printf ("0x%-*x", varwidth2 - 2, i);
+ }
+ else {
+ if (v -> v_dvalue)
+ (void)printf ("%-*s", varwidth2, v -> v_dvalue[i]);
+ else
+ (void)printf ("%-*d", varwidth2, i);
+ }
+ }
+ else
+ if (*v -> v_dvalue) {
+ (void) sprintf (buffer, "\"%s\"", *v -> v_dvalue);
+ (void)printf ("%-*s", varwidth2, buffer);
+ }
+ (void)printf (" - %s\n", v -> v_dname);
+}
+
+/* \f */
+
+/* ARGSUSED */
+
+static int set_debug (v)
+struct var *v;
+{
+ if (debug)
+ ll_dbinit (vt_log, myname);
+ else
+ vt_log -> ll_stat &= ~LLOGTTY;
+}
+
+
+/* ARGSUSED */
+
+static int set_echo (v)
+struct var *v;
+{
+ if (!connected) {
+ advise (LLOG_NOTICE,NULLCP, "not associated with terminal service");
+ return;
+ }
+
+ vt_echo (echo);
+}
+
+
+/* ARGSUSED */
+
+static int set_escape (v)
+struct var *v;
+{
+ if (*escapestr) {
+ char *cp = control (escape = *escapestr);
+
+ free (escapestr);
+ escapestr = strdup (cp);
+ }
+}
+
+
+/* ARGSUSED */
+
+static int set_repertoire (v)
+struct var *v;
+{
+ if (!connected) {
+ advise (LLOG_NOTICE,NULLCP, "not associated with terminal service");
+ return;
+ }
+
+ vt_repertoire (repertoire);
+}
+
+/* \f */
+
+static char **getval (name, choices)
+register char *name;
+char **choices;
+{
+ register int longest,
+ nmatches;
+ register char *p,
+ *q,
+ **cp,
+ **fp;
+ char buffer[BUFSIZ];
+
+ longest = nmatches = 0;
+ for (cp = choices; p = *cp; cp++) {
+ for (q = name; *q == *p++; q++)
+ if (*q == NULL)
+ return cp;
+ if (*q == NULL)
+ if (q - name > longest) {
+ longest = q - name;
+ nmatches = 1;
+ fp = cp;
+ }
+ else
+ if (q - name == longest)
+ nmatches++;
+ }
+
+ switch (nmatches) {
+ case 0:
+ advise (LLOG_NOTICE,NULLCP, "unknown value \"%s\"", name);
+ return NULL;
+
+ case 1:
+ return fp;
+
+ default:
+ for (cp = choices, p = buffer; q = *cp; cp++)
+ if (strncmp (q, name, longest) == 0) {
+ (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
+ p += strlen (p);
+ }
+ advise (LLOG_NOTICE,NULLCP, "ambiguous value, it could be one of:%s",
+ buffer);
+ return NULL;
+ }
+}
+
+/* \f */
+
+static struct var *getvar (name)
+register char *name;
+{
+ register int longest,
+ nmatches;
+ register char *p,
+ *q;
+ char buffer[BUFSIZ];
+ register struct var *v,
+ *f;
+
+ longest = nmatches = 0;
+ for (v = vars; p = v -> v_name; v++) {
+ for (q = name; *q == *p++; q++)
+ if (*q == NULL)
+ return v;
+ if (*q == NULL)
+ if (q - name > longest) {
+ longest = q - name;
+ nmatches = 1;
+ f = v;
+ }
+ else
+ if (q - name == longest)
+ nmatches++;
+ }
+
+ switch (nmatches) {
+ case 0:
+ advise (LLOG_NOTICE,NULLCP, "unknown variable \"%s\"", name);
+ return NULL;
+
+ case 1:
+ return f;
+
+ default:
+ for (v = vars, p = buffer; q = v -> v_name; v++)
+ if (strncmp (q, name, longest) == 0) {
+ (void) sprintf (p, "%s \"%s\"", p != buffer ? "," : "", q);
+ p += strlen (p);
+ }
+ advise (LLOG_NOTICE,NULLCP,
+ "ambiguous variable, it could be one of:%s", buffer);
+ return NULL;
+ }
+}
+
+/* \f HELP */
+
+static int helpwidth = 0;
+
+
+static int vt_help (vec)
+char **vec;
+{
+ register int i,
+ j,
+ w;
+ int columns,
+ width,
+ lines;
+ register struct dispatch *ds,
+ *es;
+
+ for (es = dispatches; es -> ds_name; es++)
+ continue;
+ width = helpwidth;
+
+ if (*++vec == NULL) {
+ if ((columns = ncols (stdout) / (width = (width + 8) & ~7)) == 0)
+ columns = 1;
+ lines = ((es - dispatches) + columns - 1) / columns;
+
+ (void)printf ("Operations:\n");
+ for (i = 0; i < lines; i++)
+ for (j = 0; j < columns; j++) {
+ ds = dispatches + j * lines + i;
+ (void)printf ("%s", ds -> ds_name);
+ if (ds + lines >= es) {
+ (void)printf ("\n");
+ break;
+ }
+ for (w = strlen (ds -> ds_name); w < width; w = (w + 8) & ~7)
+ (void) putchar ('\t');
+ }
+
+ (void)printf ("\n");
+
+ return DONE;
+ }
+
+ for (; *vec; vec++)
+ if (strcmp (*vec, "?") == 0) {
+ for (ds = dispatches; ds -> ds_name; ds++)
+ (void)printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help);
+
+ break;
+ }
+ else
+ if (ds = getds (*vec))
+ (void)printf ("%-*s\t- %s\n", width, ds -> ds_name, ds -> ds_help);
+
+ return DONE;
+}
+
+
+#ifndef TIOCGWINSZ
+/* ARGSUSED */
+#endif
+
+static int ncols (fp)
+FILE *fp;
+{
+#ifdef TIOCGWINSZ
+ int i;
+ struct winsize win;
+
+ if (ioctl (fileno (fp), TIOCGWINSZ, (char *) &win) != NOTOK
+ && (i = win.ws_col) > 0)
+ return i;
+#endif
+
+ return 80;
+}
+
+/* \f */
+
+char *strdup (s)
+char *s;
+{
+ char *p;
+
+ if ((p = malloc((unsigned) (strlen (s) + 1))) == NULL)
+ adios (NULLCP, "out of memory");
+
+ (void) strcpy (p, s);
+
+ return p;
+}
+
+/* \f */
+
+static rcinit ()
+{
+ register int w;
+ register char **cp;
+ register struct dispatch *ds;
+ register struct var *v;
+
+ if ((myhome = getenv ("HOME")) == NULL)
+ myhome = "."; /* could do passwd search... */
+
+ escapestr = strdup (control (escape));
+ for (ds = dispatches, helpwidth = 0; ds -> ds_name; ds++)
+ if ((w = strlen (ds -> ds_name)) > helpwidth)
+ helpwidth = w;
+
+ for (v = vars, varwidth1 = 0; v -> v_name; v++) {
+ if ((w = strlen (v -> v_name)) > varwidth1)
+ varwidth1 = w;
+
+ if (v -> v_value) {
+ if (cp = v -> v_dvalue) {
+ if (v -> v_mask) {
+#ifdef notdef
+ w = 1;
+ while (*++cp)
+ w <<= 1;
+ w--;
+ if ((w = strlen (sprintb (w, v -> v_mask))) > varwidth2)
+ varwidth2 = w;
+#endif
+ }
+ else
+ for (; *cp; cp++)
+ if ((w = strlen (*cp)) > varwidth2)
+ varwidth2 = w;
+ }
+ }
+ else
+ if (*v -> v_dvalue) {
+ *v -> v_dvalue = strdup (*v -> v_dvalue);
+ if ((w = strlen (*v -> v_dvalue) + 2) > varwidth2)
+ varwidth2 = w;
+ }
+ }
+}
+
+char sibuf[BUFSIZ << 3], *sbp;
+char tibuf[BUFSIZ], *tbp;
+int tcc;
+
+/*
+ * Select from tty and network...
+ */
+vt(s)
+ int s;
+{
+ register int c;
+ int tin = fileno(stdin), tout = fileno(stdout);
+ int nfds, result;
+
+ if ((nfds = (tin > tout ? tin : tout)) < s)
+ nfds = s;
+ nfds++;
+
+ nego_state = 0;
+ if(telnet_profile)
+ {
+ (void) tmode(2);
+ vt_rem_echo(&ni_image); /*Request Remote Echo*/
+ vt_sup_ga(&ni_image); /*Request Suppress Go Ahead*/
+ repertoire = 1;
+ vt_repertoire(repertoire);
+ }
+ else (void) tmode(1);
+
+ for (;;) {
+ fd_set ibits, obits;
+
+ FD_ZERO (&ibits);
+
+ FD_ZERO (&obits);
+ FD_SET (tout, &obits);
+ FD_SET (s, &obits);
+
+ if (nfrontp - nbackp)
+ FD_SET (s, &obits);
+ else
+ FD_SET (tin, &ibits);
+
+ if (tfrontp - tbackp)
+ FD_SET (tout, &obits);
+ else
+ FD_SET (s, &ibits);
+ if (FD_ISSET (s, &ibits) && data_pending()) {
+ FD_CLR (s, &ibits);
+ result = xselect(nfds, &ibits, &obits,
+ (fd_set *)NULL, OK);
+ if (result == -1)
+ adios ("failed", "xselect");
+ FD_SET (s, &ibits);
+ }
+ else {
+ result = xselect(nfds, &ibits, &obits,
+ (fd_set *)NULL, NOTOK);
+ if (result == -1)
+ adios ("failed", "xselect");
+ }
+ if (!FD_ISSET (s, &ibits)
+ && !FD_ISSET (tin, &ibits)
+ && !FD_ISSET (s, &obits)
+ && !FD_ISSET (tout, &obits)) {
+ sleep(5);
+ continue;
+ }
+
+ /*
+ * Something to read from the network...
+ */
+ if (FD_ISSET (s, &ibits)) {
+
+ while ( (c = getch()) > 0){
+ *tfrontp++ = c;
+ if(tfrontp >= &ttyobuf[TBUFSIZ-1]) break;
+ }
+
+ if (c == E_EOF) {
+ break;
+ }
+ }
+
+ /*
+ * Something to read from the tty...
+ */
+ if (FD_ISSET (tin, &ibits)) {
+ tcc = read(tin, tibuf, sizeof (tibuf));
+ if (tcc < 0 && errno == EWOULDBLOCK)
+ tcc = 0;
+ else {
+ if (tcc <= 0) {
+ advise(LLOG_NOTICE,NULLCP, "error: read from terminal returned %d", tcc);
+ break;
+ }
+ tbp = tibuf;
+ }
+ }
+
+ while (tcc > 0) {
+ register int ch;
+
+ if ((&netobuf[BUFSIZ] - nfrontp) < 2)
+ break;
+ ch = *tbp++ & 0377, tcc--;
+ if (strip(ch) == escape) {
+ command(0);
+ tcc = 0;
+ break;
+ }
+ *nfrontp++ = ch;
+ }
+ if (FD_ISSET (s, &obits) && (nfrontp - nbackp) > 0)
+ netflush(s);
+ if (FD_ISSET (tout, &obits) && (tfrontp - tbackp) > 0)
+ ttyflush(tout);
+ }
+ (void) tmode(0);
+}
+
+/*
+ * Construct a control character sequence
+ * for a special character.
+ */
+char *
+control(c)
+ register int c;
+{
+ static char buf[3];
+
+ if (c == 0177)
+ return ("^?");
+ if (c >= 040) {
+ buf[0] = c;
+ buf[1] = 0;
+ } else {
+ buf[0] = '^';
+ buf[1] = '@'+c;
+ buf[2] = 0;
+ }
+ return (buf);
+}
+
+SFD deadpeer()
+{
+ (void) tmode(0);
+ longjmp(peerdied, -1);
+}
+
+SFD intr()
+{
+ (void) tmode(0);
+ longjmp(toplevel, -1);
+}
+
+ttyflush(dd)
+int dd;
+{
+ int n;
+
+ if ((n = tfrontp - tbackp) > 0) {
+
+ n = write(dd, tbackp, n);
+
+ }
+ if (n < 0)
+ {
+ advise(LLOG_NOTICE,NULLCP, "ttyflush(): Negative returned from write");
+ return;
+ }
+ tbackp += n;
+ if (tbackp == tfrontp)
+ tbackp = tfrontp = ttyobuf;
+}
+
+netflush(dd)
+int dd;
+{
+ register char *cp;
+ int n, i, j;
+ int nl_flag; /*If current PDU includes newline, follow it
+ with a Deliver Request*/
+
+ nl_flag = 0;
+ if ((n = nfrontp - nbackp) > 0) {
+ if(transparent)
+ {
+ if (vt_text(nbackp,n) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ vtsend();
+ cp = nbackp;
+ for(i=0; i<n; i++)
+ {
+ if( (*cp == '\r') ||
+ (*cp == '\n') )
+ {
+ vdelreq(FALSE);
+ break;
+ }
+ ++cp;
+ }
+ nbackp += n;
+ }
+ else
+ {
+ cp = nbackp;
+ for(i=0,j=0; i<n; i++)
+ {
+ if(*cp == '\r')
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ rflag = 1;
+ vt_newline();
+ ++nl_flag;
+ }
+ else if(*cp == '\n')
+ {
+ if(!rflag) /*If preceeding char was not CR*/
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ vt_newline();
+ ++nl_flag;
+ }
+ else /*Preceeding char was CR so already sent
+ the Update. Remove this LF from buffer*/
+ {
+ ++nbackp;
+ ++cp;
+ rflag = 0;
+ }
+ }
+ else if(telnet_profile)
+ {
+ rflag = 0;
+ if(*cp == erase_char)
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ vt_char_erase();
+ }
+ else if(*cp == erase_line)
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ vt_line_erase();
+ }
+ else if(*cp == intr_char)
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ vt_interrupt();
+ }
+ else if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
+ /*If ASCII GO, dump ctrl chars*/
+ {
+ if((*cp < 0x20) || (*cp > 0x7e))
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ }
+ else
+ {
+ ++j;
+ ++cp;
+ }
+ }
+ else
+ {
+ ++j;
+ ++cp;
+ }
+ }
+ else /*Else Default Profile*/
+ {
+ if((*cp < 0x20) || (*cp > 0x7e))
+ {
+ if(j)
+ if (vt_text(nbackp,j) != OK)
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ }
+ else
+ {
+ ++j; ++cp;
+ }
+ }
+ } /*End for loop*/
+ if(j)
+ if (vt_text(nbackp,j) != OK) /*Load anything left if CR or LF
+ wasn't last char in buffer*/
+ advise(LLOG_NOTICE,NULLCP, "vt_text failed");
+ nbackp += j;
+ vtsend(); /*Send the whole NDQ*/
+ if(nl_flag && telnet_profile) vdelreq(FALSE);
+ rflag = 0;
+ }
+
+ }
+ if (n < 0) {
+ if (errno != ENOBUFS && errno != EWOULDBLOCK) {
+ (void) tmode(0);
+ perror(peerhost);
+ (void)close(dd);
+ longjmp(peerdied, -1);
+ /*NOTREACHED*/
+ }
+ n = 0;
+ }
+ if (nbackp == nfrontp)
+ nbackp = nfrontp = netobuf;
+}
+\f
+flushbufs()
+{
+ tcc = 0;
+ tbp = tibuf;
+ nfrontp = nbackp = netobuf;
+ while (getch() > 0)
+ continue;
+ tfrontp = tbackp = ttyobuf;
+}
+
+/* \f ERRORS */
+
+void finalbye ()
+{
+ (void) tmode (0);
+}
+
+
+#ifndef lint
+void adios (va_alist)
+va_dcl
+{
+ int code;
+ va_list ap;
+ static int latched = 0;
+
+ va_start (ap);
+
+ code = va_arg (ap, int);
+
+ (void) _ll_log (vt_log, code, ap);
+
+ va_end (ap);
+
+ if (connected && latched++ == 0)
+ (void) vt_close (NULLVP);
+
+ _exit (1);
+}
+#else
+/* VARARGS2 */
+
+void adios (what, fmt)
+char *what,
+ *fmt;
+{
+ adios (what, fmt);
+}
+#endif
+
+
+#ifndef lint
+void advise (va_alist)
+va_dcl
+{
+ int code,
+ flags;
+ char buffer[BUFSIZ];
+ va_list ap;
+
+ va_start (ap);
+
+ code = va_arg (ap, int);
+
+ asprintf (buffer, ap);
+
+ flags = vt_log -> ll_stat;
+
+ if (code & (LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE)) {
+ (void) fflush (stdout);
+
+ fprintf (stderr, "%s: ", myname);
+ (void) fputs (buffer, stderr);
+ (void) fputc ('\n', stderr);
+
+ (void) fflush (stderr);
+
+ vt_log -> ll_stat &= ~LLOGTTY;
+ }
+
+ (void) ll_log (vt_log, code, NULLCP, "%s", buffer);
+
+ vt_log -> ll_stat = flags;
+
+ va_end (ap);
+}
+#else
+/* VARARGS3 */
+
+void advise (code, what, fmt)
+int code;
+char *what,
+ *fmt;
+{
+ advise (code, what, fmt);
+}
+#endif
+
+/* XXX -- why is this stubbed ? */
+#ifdef BSD44
+ptyecho(on)
+{
+}
+#else
+/*ARGSUSED*/
+setmode(on, off)
+{
+}
+#endif
--- /dev/null
+/* vt_telnet.c - VT telnet profile */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vt_telnet.c,v 7.1 91/02/22 09:48:26 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/vt_telnet.c,v 7.1 91/02/22 09:48:26 mrose Interim $
+ *
+ *
+ * $Log: vt_telnet.c,v $
+ * Revision 7.1 91/02/22 09:48:26 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:53 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+#include "sector1.h"
+#include <sys/ioctl.h>
+
+#define VT_BREAK
+#undef PEPYPARM
+#define PEPYPARM int *
+
+extern struct sgttyb ottyb;
+extern int cur_emode;
+extern char *my_displayobj;
+extern char *my_signal_obj;
+extern char *my_echo_obj;
+extern char kb_image;
+extern char di_image;
+extern char ni_image;
+extern char na_image;
+extern char sync_image;
+extern char ga_image;
+extern char nego_state;
+extern int my_right;
+extern transparent;
+extern do_break;
+extern telnet_profile;
+extern int connected;
+
+vt_newline() /*Produce Newline update*/
+{
+
+ TEXT_UPDATE ud;
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = DISPLAY_OBJ;
+ ud.updates.do_list.do_name = my_displayobj;
+ ud.updates.do_list.do_type = DO_NEXT_X; /*Next X-Array*/
+ send_queue(ud);
+}
+\f
+vt_char_erase() /*Pointer Relative (x=x-1) & erase current*/
+{
+
+ TEXT_UPDATE ud;
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = DISPLAY_OBJ;
+ ud.updates.do_list.do_name = my_displayobj;
+ ud.updates.do_list.do_type = DO_PTR_REL;
+ ud.updates.do_list.do_cmd.ptr_rel.x_true = 1;
+ ud.updates.do_list.do_cmd.ptr_rel.y_true = 0;
+ ud.updates.do_list.do_cmd.ptr_rel.z_true = 0;
+ ud.updates.do_list.do_cmd.ptr_rel.x_value = -1;
+
+ send_queue(ud);
+
+ ud.updates.do_list.do_type = DO_ERASE;
+ ud.updates.do_list.do_cmd.erase.start_erase.ptr_type = 0; /*Current*/
+ ud.updates.do_list.do_cmd.erase.end_erase.ptr_type = 0; /*Current*/
+ ud.updates.do_list.do_cmd.erase.erase_attr = 0;
+
+ send_queue(ud);
+}
+\f
+vt_line_erase() /*Erase full x-array & pointer to x = 1*/
+{
+
+ TEXT_UPDATE ud;
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = DISPLAY_OBJ;
+ ud.updates.do_list.do_name = my_displayobj;
+ ud.updates.do_list.do_type = DO_ERASE;
+ ud.updates.do_list.do_cmd.erase.start_erase.ptr_type = 3; /*Start X*/
+ ud.updates.do_list.do_cmd.erase.end_erase.ptr_type = 6; /*End X*/
+ ud.updates.do_list.do_cmd.erase.erase_attr = 0;
+
+ send_queue(ud);
+
+ ud.updates.do_list.do_type = DO_PTR_ABS;
+ ud.updates.do_list.do_cmd.ptr_abs.ptr_type = 3; /*Start X*/
+
+ send_queue(ud);
+}
+\f
+vt_interrupt() /*Toggle Bit 1 of DI/KB control object*/
+{
+
+ TEXT_UPDATE ud;
+ char int_mask;
+ char image;
+
+ int_mask = IP_OBJ;
+ if(my_right == INITIATOR)
+ {
+ kb_image ^= IP_OBJ;
+ image = kb_image;
+ }
+ else
+ {
+ di_image ^= IP_OBJ; /*Toggle the Interrupt Process bit*/
+ image = di_image;
+ }
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = CTRL_OBJ;
+ ud.updates.co_list.co_name = my_signal_obj;
+ ud.updates.co_list.co_type = 1; /*Boolean Update*/
+ ud.updates.co_list.co_cmd.bool_update.value = ℑ
+ ud.updates.co_list.co_cmd.bool_update.val_count = KB_SIZE;
+ ud.updates.co_list.co_cmd.bool_update.mask = &int_mask;
+ ud.updates.co_list.co_cmd.bool_update.mask_count = KB_SIZE;
+ send_queue(ud);
+}
+\f
+vt_set_nego(image,mask) /*Update NA/NI control object as in image*/
+char image;
+char mask;
+{
+
+ TEXT_UPDATE ud;
+ char e_image;
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = CTRL_OBJ;
+ ud.updates.co_list.co_name = my_echo_obj;
+ ud.updates.co_list.co_type = 1; /*Boolean*/
+ e_image = image;
+ ud.updates.co_list.co_cmd.bool_update.value = &e_image;
+ ud.updates.co_list.co_cmd.bool_update.val_count = NA_SIZE;
+ ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+ ud.updates.co_list.co_cmd.bool_update.mask_count = NA_SIZE;
+ send_queue(ud);
+ vtsend(); /*Since we're bypassing normal keyboard entry*/
+}
+\f
+vt_echo(echo)
+int echo;
+{
+
+ if (!telnet_profile) {
+ advise (LLOG_NOTICE,NULLCP, "not using TELNET profile");
+ return;
+ }
+ if ((ni_image & ECHO_OBJ) != (nego_state & ECHO_OBJ)) {
+ advise (LLOG_NOTICE,NULLCP,
+ "negotiation in progress, try again later...");
+ return;
+ }
+
+ if (echo != ((nego_state & ECHO_OBJ) ? 1 : 0)) {
+ if (echo)
+ ni_image |= ECHO_OBJ;
+ else
+ ni_image &= ~ECHO_OBJ;
+
+ vt_set_nego(ni_image,ECHO_OBJ);/*Set proper UNIX echo state when reponse
+ is received. */
+ }
+ else
+ advise (LLOG_NOTICE,NULLCP, "already using %s echoing",
+ echo ? "remote" : "local");
+}
+\f
+vt_rem_echo(img_addr) /*Request Remote Echo Mode. Parameter is pointer
+ to image byte. */
+char *img_addr;
+{
+ *img_addr |= ECHO_OBJ;
+ vt_set_nego(*img_addr,ECHO_OBJ);
+}
+
+
+vt_sup_ga(img_addr) /*Request Suppress Go Ahead*/
+char *img_addr;
+{
+ *img_addr |= SUP_GA;
+ vt_set_nego(*img_addr,SUP_GA);
+}
+\f
+/* ARGSUSED */
+vt_break(vec)
+char **vec;
+{
+#ifdef VT_BREAK
+ if(!do_break)
+ {
+ advise(LLOG_NOTICE,NULLCP,"VT-BREAK Functional Unit Not Chosen");
+ return OK;
+ }
+ (void)tmode(2);
+ vt_clr_obj(); /*Initialize all control objects*/
+ vbrkreq();
+#else
+ TEXT_UPDATE ud;
+
+ mask = BRK_OBJ;
+ kb_image ^= BRK_OBJ; /*Can Only be called by User side*/
+ image = kb_image;
+
+ bzero ((char *) ud, sizeof *ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = CTRL_OBJ;
+ ud.updates.co_list.co_name = my_signal_obj;
+ ud.updates.co_list.co_type = 1; /*Boolean Update*/
+ ud.updates.co_list.co_cmd.bool_update.value = ℑ
+ ud.updates.co_list.co_cmd.bool_update.val_count = KB_SIZE;
+ ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+ ud.updates.co_list.co_cmd.bool_update.mask_count = KB_SIZE;
+ send_queue(ud);
+ vtsend();
+#endif
+
+ return OK;
+}
+\f
+/* ARGSUSED */
+vt_ayt(vec) /*Send Are You There*/
+char **vec;
+{
+
+ TEXT_UPDATE ud;
+ char mask;
+ char image;
+
+ if(!telnet_profile)
+ {
+ advise(LLOG_NOTICE,NULLCP, "not using TELNET profile");
+ return NOTOK;
+ }
+ mask = AYT_OBJ;
+ kb_image ^= AYT_OBJ; /*Can only be called by User side*/
+ image = kb_image;
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = CTRL_OBJ;
+ ud.updates.co_list.co_name = my_signal_obj;
+ ud.updates.co_list.co_type = 1; /*Boolean Update*/
+ ud.updates.co_list.co_cmd.bool_update.value = ℑ
+ ud.updates.co_list.co_cmd.bool_update.val_count = KB_SIZE;
+ ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+ ud.updates.co_list.co_cmd.bool_update.mask_count = KB_SIZE;
+ send_queue(ud);
+ vtsend();
+
+ return OK;
+}
+\f
+switch_rep(rep_num)/*Change to specified repertoire.
+ Switching is done by sending
+ a Write Attribute NDQ.
+ */
+int rep_num;
+{
+
+ TEXT_UPDATE ud;
+
+ if(rep_num == 1) transparent = 0;
+ else transparent = 1;
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = DISPLAY_OBJ;
+ ud.updates.do_list.do_name = my_displayobj;
+ ud.updates.do_list.do_type = DO_ATTR;
+ ud.updates.do_list.do_cmd.wrt_attrib.attr_id = 0;
+ ud.updates.do_list.do_cmd.wrt_attrib.attr_val = rep_num; /*Rep Number*/
+ ud.updates.do_list.do_cmd.wrt_attrib.attr_ext = 2; /*Modal Extent*/
+ send_queue(ud);
+ vtsend();
+}
+\f
+vt_repertoire (repertoire)
+int repertoire;
+{
+ if (!telnet_profile) {
+ advise (LLOG_NOTICE,NULLCP, "not using TELNET profile");
+ return;
+ }
+
+ if (repertoire != transparent) {
+ if (repertoire)
+ ni_image |= (DISP_BIN|KBD_BIN);
+ else
+ ni_image &= ~(DISP_BIN|KBD_BIN);
+ vt_set_nego(ni_image,DISP_BIN|KBD_BIN);
+ }
+ else
+ advise (LLOG_NOTICE,NULLCP, "already using %s repertoire",
+ transparent ? "BINARY" : "ASCII");
+}
+\f
+vt_clr_obj() /*Set TELNET Profile Control Objects to 0*/
+{
+ kb_image = di_image = 0;
+ nego_state = ni_image = na_image = 0;
+ sync_image = ga_image = 0;
+}
+\f
+/*ARGSUSED*/
+vt_sync(vec) /*Send TELNET SYNC signal (test for UDQ & typed data)*/
+char **vec;
+{
+
+ PE udqp;
+ TEXT_UPDATE ud;
+ char mask, image;
+
+ mask = SYNC;
+ sync_image ^= SYNC;
+ image = sync_image;
+ bzero( (char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = CTRL_OBJ;
+ ud.updates.co_list.co_name = "SY";
+ ud.updates.co_list.co_type = 1;
+ ud.updates.co_list.co_cmd.bool_update.value = ℑ
+ ud.updates.co_list.co_cmd.bool_update.val_count = SYNC_SIZE;
+ ud.updates.co_list.co_cmd.bool_update.mask = &mask;
+ ud.updates.co_list.co_cmd.bool_update.mask_count = SYNC_SIZE;
+ if(build_UDQPDU_UDQpdu(&udqp,1,NULL,NULLCP,(PEPYPARM) &ud) == NOTOK)
+ adios(NULLCP,"UDQ build failure");
+ udqp->pe_context = 1;
+ (void) do_event(VDATreq_u,udqp);
+ pe_free(udqp);
+ return OK;
+}
--- /dev/null
+.TH VTD 8C "21 Nov 1988"
+.\" $Header: /f/osi/vt/RCS/vtd.8c,v 7.1 91/02/22 09:48:27 mrose Interim $
+.\"
+.\"
+.\" $Log: vtd.8c,v $
+.\" Revision 7.1 91/02/22 09:48:27 mrose
+.\" Interim 6.8
+.\"
+.\" Revision 7.0 89/11/23 22:31:54 mrose
+.\" Release 6.0
+.\"
+.SH NAME
+iso.vt \- VT remote login responder
+.SH SYNOPSIS
+.in +.5i
+.ti -.5i
+.B \*(SDiso.vt
+\%[-d 0-7]
+\%[-F logfile]
+\fImagic\0arguments\fR
+.in -.5i
+(under \fI\*(SDtsapd\fR\0)
+.SH DESCRIPTION
+The \fIvtd\fR server implements the responder side of
+a remote login service based on the ISO Virtual Terminal (VT)
+standard and the VT TELNET profile from the NIST OSI Workshop
+Implementor's Agreements.
+.SH OPTIONS
+.TP
+.B -d 0-7
+Set the level of debug output from 0, meaning none, to 7, which is
+the most verbose.
+.TP
+.B -F logfile
+Sets the VT logfile.
+Note that the pathname of this file is interpreted relatively to the
+ISODE logging area.
+To have tracing information written to a file in the current
+directory,
+start the filename with \*(lq./\*(rq.
+.SH FILES
+.nf
+.ta \w'\*(LDvt.log 'u
+\*(EDisoentities ISODE application entity title database
+\*(LDvt.log logfile
+.fi
+.SH "SEE ALSO"
+vt(1c),
+.br
+\fIThe ISO Development Environment: User's Manual\fR,
+.br
+ISO DIS 9040, 9041:
+\fIInformation Processing Systems \-\-
+Virtual Terminal Service and Protocol\fR
+.br
+Implementation Agreements for Open Systems Interconnection Protocols
+.SH AUTHORS
+Rick Wilder and Don Chirieleison,
+The MITRE Corporation.
+.br
+Parts of this program are based on the \fItelnet\fR(1c) program supplied with
+Berkeley UNIX.
+.SH BUGS
+\fIvt\fR and \fIvtd\fR need to be brought up to date with BSD 4.3(4?)
+TELNET.
+.PP
+The encodings of the VT PDUs may need to be updated when
+the International Standard version of ISO 9041 is available.
+.PP
+When an association is established,
+a possible bug in the PTY driver on systems derived from Berkeley UNIX
+may cause the \*(lqlogin:\*(rq prompt to be lost.
+The \fIlogin\fR program is still running,
+the user need only type-in the username or hit RETURN for another prompt.
+.PP
+Due to a possible bug in the PTY driver on systems derived from Berkeley UNIX,
+it is important that the responder always run detached from a
+controlling terminal.
+Since the repsonder is invoked from \fItsapd\fR\0(8c),
+this requirement is passed on to the \fItsapd\fR program.
+Thus,
+when running the VT responder,
+it is \fBcritical\fR that \fItsapd\fR be started under
+\fI/etc/rc.local\fR or in \*(lqbackground\*(rq mode, e.g.,
+.sp
+.in +.5i
+.nf
+# \*(SDtsapd >& /dev/null
+.fi
+.in -.5i
+.sp
+which will cause the daemon to automatically detach.
--- /dev/null
+/* vtd.c - VT responder */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vtd.c,v 7.3 91/02/22 09:48:28 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/vtd.c,v 7.3 91/02/22 09:48:28 mrose Interim $
+ *
+ *
+ * $Log: vtd.c,v $
+ * Revision 7.3 91/02/22 09:48:28 mrose
+ * Interim 6.8
+ *
+ * Revision 7.2 90/07/09 14:52:06 mrose
+ * sync
+ *
+ * Revision 7.1 89/11/30 23:51:42 mrose
+ * pa2str
+ *
+ * Revision 7.0 89/11/23 22:31:55 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#undef MAP_BACKSPACE /*Map backspace character to VT ERASE CHAR*/
+
+#include <signal.h>
+#include "vtpm.h"
+#include "sector1.h"
+#include "tailor.h"
+#include <sys/ioctl.h>
+#ifdef BSD44
+#include <sys/termios.h>
+#include <sys/ttydefaults.h>
+#endif
+
+#ifndef _PATH_LOGIN
+#ifndef BSD44
+#define _PATH_LOGIN "/bin/login"
+#else
+#define _PATH_LOGIN "/usr/bin/login"
+#endif
+#endif
+
+#include <arpa/telnet.h>
+
+#include <ctype.h>
+#include <setjmp.h>
+#include <pwd.h>
+#include <varargs.h>
+
+#define BELL '\07'
+#ifndef SUNOS4
+#define BANNER "\r\n\r\n4.2 BSD UNIX (%s)\r\n\r\n\r%s"
+#else
+#define BANNER "\r\n\r\nSunOS UNIX (%s)\r\n\r\n\r%s"
+#endif
+
+int connected = FALSE;
+char command[256];
+
+
+/*
+ * I/O data buffers, pointers, and counters.
+ */
+char ptyobuf[BUFSIZ], *pfrontp = ptyobuf, *pbackp = ptyobuf;
+char netobuf[BUFSIZ], *nfrontp = netobuf, *nbackp = netobuf;
+int pcc;
+
+VT_PROFILE vtp_profile;
+int rflag = 0;
+char erase_char;
+char erase_line;
+char intr_char;
+char *crp = "\r";
+char *my_displayobj = "D"; /*Acceptor's Display Object Name*/
+char *my_echo_obj = "NA"; /*Acceptor's Negotiation Control Object Name*/
+char *my_signal_obj = "DI"; /*Acceptor's Signal Control Object*/
+char *his_echo_obj = "NI"; /*Initiator's Negotiation Control Object*/
+char *his_signal_obj = "KB"; /*Initiator/s Signal control Object*/
+int my_right = ACCEPTOR;
+char kb_image; /*KB Control Object image*/
+char di_image; /*DI Control Object Image*/
+char ni_image; /*NI Control Object image*/
+char na_image; /*NA Control Object image*/
+char nego_state; /*Current state of NA affected options*/
+char sync_image; /*SY Control Object image*/
+char ga_image;
+int transparent = 0; /*Flag for Transparent repertoire*/
+int telnet_profile =1;
+int do_break = 1; /*If VT-BREAK agreed to*/
+int showoptions = 0;
+int debug = 0;
+
+#ifdef BSD44
+struct termios oterm;
+#else
+struct tchars otc;
+struct ltchars oltc;
+struct sgttyb ottyb;
+#endif
+char *myhostname;
+char peerhost[BUFSIZ];
+struct PSAPaddr ts_bound;
+struct passwd *pwd;
+
+int pty, net;
+int inter;
+extern char **environ;
+extern int errno;
+char line[] = "/dev/ptyp0";
+char *envinit[] = { "TERM=network", 0 };
+SFD cleanup();
+static int do_cleaning = 0;
+
+char *myname;
+LLog _vt_log = {
+ "vt.log", NULLCP, NULLCP,
+ LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1,
+ LLOGCLS | LLOGCRT | LLOGZER, NOTOK
+
+};
+LLog *vt_log = &_vt_log;
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int f = 0;
+ char *cp = line;
+ char *logname = NULLCP;
+ int i, p, t;
+ char j;
+#ifndef BSD44
+ struct sgttyb b;
+#endif
+
+ if (myname = rindex (*argv, '/'))
+ myname++;
+ if (myname == NULL || *myname == NULL)
+ myname = *argv;
+
+ isodetailor (myname, 0);
+ if (debug = isatty (fileno (stderr)))
+ ll_dbinit (vt_log, myname);
+ else
+ ll_hdinit (vt_log, myname);
+
+ for(i=1; i<(argc - 2); i++)
+ {
+ if (!strcmp(argv[i], "-d"))
+ {
+ if (!isdigit(argv[++i][0])
+ || sscanf(argv[i], "%d", &debug) != 1)
+ adios (NULLCP, "usage: %s -d 0-7", myname);
+ advise(LLOG_DEBUG,NULLCP, "setting debug level to %d", debug);
+ if (debug)
+ ll_dbinit (vt_log, myname);
+ }
+ else if(!strcmp(argv[i], "-F"))
+ {
+ if ((logname = argv[++i]) == NULL || *logname == '-')
+ adios (NULLCP, "usage: %s -F logfile", myname);
+ vt_log -> ll_file = logname;
+ (void) ll_close (vt_log);
+ advise(LLOG_DEBUG,NULLCP, "logging to %s",logname);
+ }
+ else
+ adios(NULLCP, "usage: %s [-F logfile] [-d N]",
+ myname);
+ }
+
+ advise (LLOG_NOTICE,NULLCP, "starting");
+
+ acc = &accs;
+ acr = &acrs;
+ aci = &acis;
+ acs = &acss;
+
+ if (ass_ind(argc,argv) == OK) {
+ connected = TRUE;
+ if( !strcmp(vtp_profile.profile_name,"default") )
+ telnet_profile = 0;
+ }
+ else
+ exit(1);
+#ifdef BSD44
+ na_image = 0;
+ nego_state = 0; /*Start off in Local echo*/
+ i = forkpty(&p, line, NULL, NULL);
+ if (i == -1) {
+ perror("vtd -- forkpty");
+ vrelreq();
+ /*NOTREACHED*/
+ }
+ if (i) {
+ vtd(sd, p);
+ /*NOTREACHED*/
+ }
+#else
+/*
+ * Get a pty, scan input lines.
+ */
+ for (j = 'p' ; j <= 't'; j++) {
+ cp[strlen ("/dev/pty")] = j;
+ for (i = 0; i < 16; i++) {
+ cp[strlen("/dev/ptyp")] = "0123456789abcdef"[i];
+ p = open(cp, 2);
+ if (p >= 0)
+ goto gotpty;
+ }
+ }
+ perror("All network ports in use");
+ vrelreq();
+ /*NOTREACHED*/
+gotpty:
+
+ cp[strlen("/dev/")] = 't';
+ t = open("/dev/tty", 2);
+ if (t >= 0) {
+ if (ioctl(t, TIOCNOTTY, 0) == -1) {
+ perror("ioctl (TIOCNOTTY)");
+ }
+ (void)close(t);
+ }
+ t = open(cp, 2);
+ if (t < 0)
+ fatalperror(f, cp, errno);
+ if (ioctl(t, TIOCGETP, (char*)&b) == -1) {
+ perror("ioctl (TIOCGETP)");
+ adios(NULLCP, "ioctl failed (TIOCGETP)");
+ }
+ b.sg_flags = CRMOD|XTABS|ANYP;
+ if (ioctl(t, TIOCSETP, (char*)&b) == -1) {
+ perror("ioctl (TIOCSETP)");
+ adios(NULLCP, "ioctl failed (TIOCSETP)");
+ }
+ if (ioctl(p, TIOCGETP, (char*)&b) == -1) { /* XXX why is this done on the controller */
+ perror("ioctl (TIOCGETP)");
+ adios(NULLCP, "ioctl failed (TIOCGETP)");
+ }
+ if (telnet_profile)
+ b.sg_flags &= ~ECHO;
+ else
+ b.sg_flags |= ECHO; /*Remote echo for Default*/
+ if (ioctl(p, TIOCSETP, (char*)&b) == -1) {
+ perror("ioctl (TIOCSETP)");
+ adios(NULLCP, "ioctl failed (TIOCSETP)");
+ }
+ na_image = 0;
+ nego_state = 0; /*Start off in Local echo*/
+
+ if ((i = fork()) < 0)
+ fatalperror(f, "fork", errno);
+ if (i)
+ vtd(sd, p);
+ (void)close(sd);
+ (void)close(p);
+ if (dup2(t, 0) == -1) {
+ perror("dup2");
+ adios(NULLCP, "dup2 failed");
+ }
+ if (dup2(t, 1) == -1) {
+ perror("dup2");
+ adios(NULLCP, "dup2 failed");
+ }
+ if (dup2(t, 2) == -1) {
+ perror("dup2");
+ adios(NULLCP, "dup2 failed");
+ }
+ (void)close(t);
+#endif
+ environ = envinit;
+
+ execl(_PATH_LOGIN,"login","-h",peerhost,NULLCP);
+ fatalperror(f, _PATH_LOGIN, errno);
+ /*NOTREACHED*/
+}
+
+fatal(f, msg)
+ int f;
+ char *msg;
+{
+ char buf[BUFSIZ];
+
+ (void) sprintf(buf, "%s: %s.\n", myname, msg);
+ (void) write(f, buf, strlen(buf));
+ adios (NULLCP, msg);
+}
+
+fatalperror(f, msg, errnum)
+ int f;
+ char *msg;
+ int errnum;
+{
+ char buf[BUFSIZ];
+ extern char *sys_errlist[];
+
+ (void) sprintf(buf, "%s: %s", msg, sys_errlist[errnum]);
+ fatal(f, buf);
+}
+
+/*
+ * Main loop. Select from pty and network.
+ */
+
+vtd(f, p)
+{
+ int on = 1;
+ int nfds, result;
+
+ do_cleaning = 1;
+ net = f, pty = p;
+ nfds = (f > p ? f : p) + 1;
+
+ if (ioctl(p, FIONBIO, (char*)&on) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed (FIONBIO)");
+ }
+#ifdef SIGTSTP
+ (void) signal(SIGTSTP, SIG_IGN);
+#endif
+#ifdef SIGCHLD
+ (void) signal(SIGCHLD, cleanup);
+#endif
+ /*
+ * Show banner that getty never gave.
+ */
+ myhostname = PLocalHostName ();
+ (void) sprintf(nfrontp, BANNER, myhostname, "");
+ nfrontp += strlen(nfrontp);
+
+#ifdef BSD44
+ if (tcgetattr(pty, &oterm) == -1) {
+ perror("tcgetattr");
+ adios(NULLCP, "tcgetattr failed");
+ }
+ if (telnet_profile) {
+ oterm.c_lflag &= ~ECHO;
+ if (tcsetattr(pty, TCSADRAIN, &oterm) == -1) {
+ perror("tcgetattr");
+ adios(NULLCP, "tcgetattr failed");
+ }
+ }
+ erase_char = oterm.c_cc[VERASE];
+ erase_line = oterm.c_cc[VKILL];
+ intr_char = oterm.c_cc[VINTR];
+#else
+ if (ioctl(pty,TIOCGETP,(char*)&ottyb) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed (TIOCGETP)");
+ }
+ if (ioctl(pty,TIOCGETC,(char*)&otc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed (TIOCGETC)");
+ }
+ if (ioctl(pty,TIOCGLTC,(char*)&oltc) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed (TIOCGLTC)");
+ }
+ erase_char = ottyb.sg_erase;
+ erase_line = ottyb.sg_kill;
+ intr_char = otc.t_intrc;
+#endif
+
+
+ for (;;) {
+ fd_set ibits, obits;
+ register int c;
+
+ FD_ZERO (&ibits);
+ FD_ZERO (&obits);
+ /*
+ * Never look for input if there's still
+ * stuff in the corresponding output buffer
+ */
+ if (nfrontp - nbackp) {
+ FD_SET (f, &obits);
+ }
+ else {
+ FD_SET (p, &ibits);
+ }
+ if (pfrontp - pbackp) {
+ FD_SET (p, &obits);
+ }
+ else {
+ FD_SET (f, &ibits);
+ }
+ if (FD_ISSET (f, &ibits) && data_pending()) {
+ FD_CLR (f, &ibits);
+
+ result = xselect(nfds, &ibits, &obits,
+ (fd_set *)NULL, OK);
+
+ if (result < 0)
+ adios("failed", "xselect");
+ FD_SET (f, &ibits);
+ }
+ else {
+ if (xselect(nfds, &ibits, &obits, (fd_set *)NULL,
+ NOTOK) == -1)
+ adios("failed", "xselect");
+ }
+ if (!FD_ISSET (f, &ibits)
+ && !FD_ISSET (p, &ibits)
+ && !FD_ISSET (f, &obits)
+ && !FD_ISSET (p, &obits)) {
+ sleep(5);
+ continue;
+ }
+
+ /*
+ * Something to read from the network...
+ */
+ if (FD_ISSET (f, &ibits)) {
+ while ((c = getch()) > 0)
+ *pfrontp++ = c;
+ }
+ if (c == E_EOF) {
+ break;
+ }
+
+ /*
+ * Something to read from the pty...
+ */
+ if (FD_ISSET (p, &ibits)) {
+ pcc = read(p, nfrontp, (&netobuf[BUFSIZ] - nfrontp));
+
+ if (pcc < 0 && errno == EWOULDBLOCK)
+ pcc = 0;
+ else {
+ if (pcc <= 0) {
+ if (debug)
+ advise(LLOG_EXCEPTIONS,NULLCP,
+ "problem reading from pty");
+ break;
+ }
+ }
+ nfrontp += pcc;
+ }
+
+ if (FD_ISSET (f, &obits) && (nfrontp - nbackp) > 0)
+ netflush();
+
+ if (FD_ISSET (p, &obits) && (pfrontp - pbackp) > 0)
+ ptyflush();
+ }
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "finished loop in vtp");
+ cleanup();
+}
+
+/*
+ * Send interrupt to process on other side of pty.
+ * If it is in raw mode, just write NULL;
+ * otherwise, write intr char.
+ */
+interrupt()
+{
+#ifdef BSD44
+ struct termios term;
+
+ ptyflush();
+ if (tcgetattr(pty, &term) == -1) {
+ perror("tcgetattr");
+ return;
+ }
+ if ((term.c_lflag&ISIG) && term.c_cc[VINTR] != _POSIX_VDISABLE)
+ *pfrontp++ = term.c_cc[VINTR];
+ else
+ *pfrontp++ = '\0';
+#else
+ struct sgttyb b;
+ struct tchars tchars;
+
+ ptyflush(); /* half-hearted */
+ if (ioctl(pty, TIOCGETP, (char*)&b) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ if (b.sg_flags & RAW) {
+ *pfrontp++ = '\0';
+ return;
+ }
+ *pfrontp++ = ioctl(pty, TIOCGETC, (char*)&tchars) < 0 ?
+ '\177' : tchars.t_intrc;
+#endif
+}
+
+netflush()
+{
+ register char *cp;
+ int n;
+ int i, j;
+ int nl_flag; /*Records if Newline is included in current PDU to
+ decide if Deliver Request should follow it. Should
+ not be required but some implementations may wait
+ for it before delivering NDQ to application*/
+
+ nl_flag = 0;
+ if ((n = nfrontp - nbackp) > 0) {
+
+ if (debug) {
+ (void) ll_log (vt_log, LLOG_DEBUG, NULLCP,
+ ("writing to the net"));
+ (void) ll_printf (vt_log, "<<");
+ for(i=0; i<(nfrontp-nbackp); i++)
+ (void)ll_printf (vt_log, "%02x ",*(nbackp+i));
+ (void)ll_printf (vt_log, ">>\n");
+ (void)ll_sync (vt_log);
+ }
+ if(transparent)
+ {
+ (void)vt_text(nbackp,n);
+ vtsend();
+ cp = nbackp;
+ for(i=0; i<n; i++)
+ {
+ if((*cp == '\r') ||
+ (*cp == '\n'))
+ {
+ vdelreq(FALSE);
+ break;
+ }
+ ++cp;
+ }
+ nbackp += n;
+ }
+ else
+ {
+ cp = nbackp;
+ for(i=0,j=0; i<n; i++)
+ {
+ if(*cp == '\r')
+ {
+ if(rflag) (void)vt_text(crp,1);
+ /*Previous char was CR so put one in NDQ*/
+ if(j)
+ (void)vt_text(nbackp,j);
+ nbackp += (j+1); /*Skip over current CR*/
+ cp = nbackp;
+ j = 0;
+ if(i == (n-1) ) (void)vt_text(crp,1);
+ /*If CR is last char in buffer, send it*/
+ else rflag = 1;
+ /*If not last char in buffer, read next one*/
+ continue;
+ }
+ else if(rflag) /*If previous character was CR*/
+ {
+ if(*cp == '\n') /*Got CR-LF -- map to Next X-Array*/
+ {
+ nbackp += (j+1);
+ cp = nbackp;
+ rflag = 0;
+ vt_newline();
+ ++nl_flag;
+ continue;
+ }
+ else /*Preceeding char was CR but not followed by
+ LF. Put CR in buffer*/
+ (void) vt_text(crp,1);
+ rflag = 0;
+ }
+ if(telnet_profile)
+ {
+ rflag = 0;
+#ifdef MAP_BACKSPACE
+ if(*cp == 0x08) /*If believed to be erase*/
+ {
+ if(j)
+ (void)vt_text(nbackp,j);
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ vt_char_erase();
+ continue;
+ }
+#endif
+ if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
+ /*If ASCII GO, dump ctrl chars*/
+ {
+ if((*cp < 0x20) || (*cp > 0x7e))
+ {
+ if(j)
+ (void)vt_text(nbackp,j);
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ }
+ else
+ {
+ ++j; ++cp;
+ }
+ }
+ else
+ {
+ ++j;
+ ++cp;
+ }
+ }
+ else /*Else Default Profile*/
+ {
+ if((*cp < 0x20) || (*cp > 0x7e))
+ {
+ if(j)
+ (void)vt_text(nbackp,j);
+ nbackp += (j+1);
+ cp = nbackp;
+ j = 0;
+ }
+ else
+ {
+ ++j;
+ ++cp;
+ }
+ }
+ } /*End for loop*/
+ if(j)
+ (void)vt_text(nbackp,j); /*Load anything left if CR or LF
+ wasn't last char in buffer*/
+ nbackp += j;
+ vtsend(); /*Send the whole NDQ*/
+ if(nl_flag && telnet_profile) vdelreq(FALSE);
+ }
+ }
+ if (n < 0) {
+ if (errno != ENOBUFS && errno != EWOULDBLOCK) {
+ adios("closed", "association");
+ /*NOTREACHED*/
+ }
+ n = 0;
+ }
+ if (nbackp == nfrontp)
+ nbackp = nfrontp = netobuf;
+}
+
+SFD cleanup()
+{
+ sleep(1);
+ while(getch() > 0); /*Clean out unread VT-DATA PDU's still held
+ in network. Kludge to overcome deficiency
+ in Session Release. */
+ rmut();
+#ifndef BSD44
+ vhangup();
+#endif
+ vrelreq();
+ (void)kill(0, SIGKILL);
+ exit(1);
+}
+
+#include <utmp.h>
+
+struct utmp wtmp;
+char wtmpf[] = "/usr/adm/wtmp";
+char utmp[] = "/etc/utmp";
+#define SCPYN(a, b) strncpy(a, b, sizeof (a))
+#define SCMPN(a, b) strncmp(a, b, sizeof (a))
+
+long lseek (), time ();
+
+rmut()
+{
+ register f;
+ int found = 0;
+
+ f = open(utmp, 2);
+ if (f >= 0) {
+ while(read(f, (char *)&wtmp, sizeof (wtmp)) == sizeof (wtmp)) {
+ if (SCMPN(wtmp.ut_line, line+5) || wtmp.ut_name[0]==0)
+ continue;
+ (void)lseek(f, -(long)sizeof (wtmp), 1);
+ (void)SCPYN(wtmp.ut_name, "");
+#if !defined(SYS5) && !defined(bsd43_ut_host)
+ (void)SCPYN(wtmp.ut_host, "");
+#endif
+ (void)time(&wtmp.ut_time);
+ (void) write(f, (char *)&wtmp, sizeof (wtmp));
+ found++;
+ }
+ (void)close(f);
+ }
+ if (found) {
+ f = open(wtmpf, 1);
+ if (f >= 0) {
+ (void)SCPYN(wtmp.ut_line, line+5);
+ (void)SCPYN(wtmp.ut_name, "");
+#if !defined(SYS5) && !defined(bsd43_ut_host)
+ (void)SCPYN(wtmp.ut_host, "");
+#endif
+ (void)time(&wtmp.ut_time);
+ (void)lseek(f, (long)0, 2);
+ (void) write(f, (char *)&wtmp, sizeof (wtmp));
+ (void)close(f);
+ }
+ }
+ (void)chmod(line, 0666);
+ (void)chown(line, 0, 0);
+ line[strlen("/dev/")] = 'p';
+ (void)chmod(line, 0666);
+ (void)chown(line, 0, 0);
+}
+
+bye()
+{
+ if(do_cleaning) {
+ rmut();
+ (void)kill(0, SIGKILL);
+ }
+ exit(0);
+}
+
+flushbufs()
+{
+ pcc = 0;
+ pfrontp = pbackp = ptyobuf;
+ nfrontp = nbackp = netobuf;
+ while (getch() > 0)
+ continue;
+}
+
+/* \f ERRORS */
+
+void finalbye ()
+{
+ bye ();
+}
+
+
+#ifndef lint
+void adios (va_alist)
+va_dcl
+{
+ va_list ap;
+
+ va_start (ap);
+
+ (void) _ll_log (vt_log, LLOG_FATAL, ap);
+
+ va_end (ap);
+
+ bye ();
+
+ _exit (1);
+}
+#else
+/* VARARGS2 */
+
+void adios (what, fmt)
+char *what,
+ *fmt;
+{
+ adios (what, fmt);
+}
+#endif
+
+
+#ifndef lint
+void advise (va_alist)
+va_dcl
+{
+ int code;
+ va_list ap;
+
+ va_start (ap);
+
+ code = va_arg (ap, int);
+
+ (void) _ll_log (vt_log, code, ap);
+
+ va_end (ap);
+}
+#else
+/* VARARGS3 */
+
+void advise (code, what, fmt)
+int code;
+char *what,
+ *fmt;
+{
+ advise (code, what, fmt);
+}
+#endif
+
+ptyflush()
+{
+ int n;
+
+ if ((n = pfrontp - pbackp) > 0)
+ {
+ n = write(pty, pbackp, n);
+ }
+ if (n < 0)
+ return;
+ pbackp += n;
+ if (pbackp == pfrontp)
+ pbackp = pfrontp = ptyobuf;
+}
+
+#ifdef BSD44
+ptyecho(on)
+{
+ struct termios term;
+
+ ptyflush();
+ if (tcgetattr(pty, &term) == -1) {
+ perror("tcgetattr");
+ return;
+ }
+ if (on)
+ term.c_lflag |= ECHO;
+ else
+ term.c_lflag &= ECHO;
+ if (tcsetattr(pty, TCSAFLUSH, &term) == -1) {
+ perror("tcsetattr");
+ return;
+ }
+}
+#else
+setmode(on, off)
+ int on, off;
+{
+ struct sgttyb b;
+
+ ptyflush();
+ if(ioctl(pty, TIOCGETP, (char*)&b) < 0) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+ b.sg_flags |= on;
+ b.sg_flags &= ~off;
+ if (ioctl(pty, TIOCSETP, (char*)&b) == -1) {
+ perror("ioctl");
+ adios(NULLCP, "ioctl failed");
+ }
+}
+#endif
--- /dev/null
+/* vtpm.c - VTPM: FSM */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vtpm.c,v 7.1 91/02/22 09:48:30 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/vtpm.c,v 7.1 91/02/22 09:48:30 mrose Interim $
+ *
+ *
+ * $Log: vtpm.c,v $
+ * Revision 7.1 91/02/22 09:48:30 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:57 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+#include "eventmsg.h"
+#include "sector1.h"
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+int cmode;
+extern int sd; /*Session descriptor for this association*/
+extern int debug;
+
+struct SSAPref sfs;
+struct SSAPref *sf;
+struct PSAPaddr *pa;
+struct AcSAPconnect accs;
+struct AcSAPconnect *acc;
+struct AcSAPrelease acrs;
+struct AcSAPrelease *acr;
+struct AcSAPindication acis;
+struct AcSAPindication *aci;
+struct AcSAPabort *aca;
+AEI aei;
+OID ctx,
+ pci;
+
+struct AcSAPstart acss;
+struct AcSAPstart *acs;
+struct PSAPstart *ps;
+struct PSAPindication pi;
+struct PSAPdata px;
+struct PSAPfinish *pf;
+
+/****************************************************************************/
+/* GET EVENT - attempt to read a PDU from the presentation connection */
+/* designated by "sd", determine */
+/* which imcoming event has ocurred, */
+/* and process the event with "do_event" */
+/* */
+/* A non-blocking read is done and OK is returned if there */
+/* is nothing to read. */
+/* */
+/* PARAMETERS - */
+/* FD - the presentation ID for the connection to read from */
+/* */
+/* PE - a pointer to the presentation element that is read */
+/* (note that what is passed is a pointer to a pointer to */
+/* data structure so that the address of the PE */
+/* that is read can be returned in this parameter) */
+/* */
+/* RETURNS - the number of the incoming event associated with reading */
+/* this PE from the network */
+/****************************************************************************/
+
+int
+get_event(dd, pe)
+ int dd;
+ PE *pe;
+{
+ int result, event;
+ PE nullpe;
+
+ result = PReadRequest(dd, &px, OK, &pi);
+ switch (result) {
+ case NOTOK:
+ if (debug)
+ advise(LLOG_EXCEPTIONS,NULLCP, "P-READ REQUEST returned NOTOK");
+ return(NOTOK);
+ case DONE:
+ if (pi.pi_type == PI_FINISH) {
+ pf = &pi.pi_finish;
+ event = RLQ;
+ nullpe = NULLPE;
+ pe = &nullpe;
+ }
+ else if(pi.pi_type == PI_SYNC)
+ {
+ return( pn_ind(dd, &pi.pi_sync)) ;
+ }
+ else
+ adios(NULLCP, "PReadRequest returned DONE, but event unknown (%d)",pi.pi_type);
+ break;
+ case OK:
+ if (px.px_ninfo > 1)
+ adios(NULLCP, "read more than one PE from network!\n");
+ pe = &(px.px_info[0]);
+
+ /* we are assuming here that you can only get one PDU per P-DATA.
+ */
+ PLOG (vt_log, print_VT_PDUs, *pe, NULLCP, 1);
+ if ((*pe)->pe_class != PE_CLASS_CONT)
+ adios(NULLCP,"read pe of class %d", (*pe)->pe_class);
+ switch((*pe)->pe_id) {
+ case (ASQ_PDU):
+ {
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "got ASQ_PDU");
+
+ event = ASQ;
+ }
+ case ASR_PDU:
+ {
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "got ASR_PDU");
+
+ event = ASR;
+ }
+ case AUQ_PDU:
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "got AUQ_PDU");
+ event = AUQ;
+ break;
+ case DAQ_PDU:
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "got DAQ_PDU");
+ event = DAQ;
+ break;
+ case DLQ_PDU:
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "got DLQ_PDU");
+
+ event = DLQ;
+ break;
+
+ case NDQ_PDU:
+ {
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "got NDQ_PDU");
+
+ event = NDQ_tr; /*See comment below*/
+
+ /* We're supposed to find out if the NDQ contains an
+ update to a triggered control object or not to determine
+ what kind of event we have. Right now we'll assume that
+ we do have such an update in all cases. Note that this may
+ be a problem if we use quarantine delivery control in the
+ future.
+
+ for each update, find out if the update is for a display object
+ or for a control object. if it's a control object get the name
+ of it and find out if it has a trigger
+
+ */
+ break;
+ }
+
+ case UDQ_PDU:
+ {
+ event = UDQ;
+ break;
+ }
+
+ case HDQ_PDU:
+ {
+ if(debug) advise(LLOG_NOTICE,NULLCP,"Got HDQ");
+ event = HDQ;
+ break;
+ }
+
+ case RLR_PDU:
+ event = RLR;
+ break;
+
+ default:
+ adios(NULLCP,"unknown PDU type %d", (*pe)->pe_id);
+ }
+ }
+ return(do_event(event,*pe));
+}
+\f
+
+
+#define SECTORS 6
+
+/* number of states in each sector */
+
+unsigned max_state[SECTORS] = { 0, 13, 0, 0, 0, 10};
+
+int (*s0[])() = {
+ NULL
+};
+
+int (*s1[])() = {
+ s1_01, /* states in the first sector */
+ s1_02B,
+ s1_02S,
+ s1_03B,
+ s1_03S,
+ s1_10B,
+ s1_10N,
+ s1_10T,
+ s1_50B,
+ s1_51Q,
+ s1_51R,
+ s1_51N,
+ s1_51T
+};
+
+int (*s2[])() = {
+ NULL
+};
+
+int (*s3[])() = {
+ NULL
+};
+
+int (*s4[])() = {
+ NULL
+};
+
+int (*s5[])() = {
+ s5_400B,
+ s5_402B,
+ s5_420B,
+ s5_422B,
+ s5_40N,
+ s5_40T,
+ s5_42N,
+ s5_42T,
+ s5_61,
+ s5_62
+};
+
+int ((**sectors[])()) = {s0, s1, s2, s3, s4, s5};
+
+\f
+unsigned state = 0,
+ sector = 1;
+
+do_event(event, pe)
+ int event;
+ PE pe;
+{
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP,
+ "in do_event, sector is %d, state is %d, event is %d (%s)",
+ sector, state, event,
+ event >= 0
+ && event < sizeof eventname/sizeof eventname[0]
+ ? eventname[event] : "INVALID");
+ if (sector >= SECTORS || state >= max_state[sector])
+ return(NOTOK);
+ return(sectors[sector][state](event, pe));
+}
+\f
+/* ARGSUSED */
+pn_ind(dd, psync) /* sync indications */
+ int dd;
+ struct PSAPsync *psync;
+{
+ switch(psync->pn_type)
+ {
+ case SN_MAJORIND:
+ advise(LLOG_DEBUG,NULLCP, "vt: got SN_MAJORIND");
+ break;
+ case SN_MAJORCNF:
+ advise(LLOG_DEBUG,NULLCP, "vt: got SN_MAJORCNF");
+ break;
+ case SN_MINORIND:
+ advise(LLOG_DEBUG,NULLCP, "vt: got SN_MINORIND");
+ break;
+ case SN_MINORCNF:
+ advise(LLOG_DEBUG,NULLCP, "vt: got SN_MINORCNF");
+ break;
+ case SN_RESETIND:
+/* advise(LLOG_DEBUG,NULLCP, "vt: resetind: SN_RESETIND"); */
+ if(psync->pn_options != SYNC_RESTART)
+ adios(NULLCP,"resetind: bad options params");
+ if(psync->pn_ninfo > 0)
+ return( do_event(BKQ,psync->pn_info[0]));
+ else return( do_event(BKQ,NULLPE));
+ case SN_RESETCNF:
+/* advise(LLOG_DEBUG,NULLCP, "vt: got SN_RESETCNF\n"); */
+ if(psync->pn_options != SYNC_RESTART)
+ adios(NULLCP,"resetind: bad options params");
+ if(psync->pn_ninfo > 0)
+ return( do_event(BKR,psync->pn_info[0]));
+ else return( do_event(BKR,NULLPE));
+ default:
+ adios(NULLCP,"received bad sync type");
+ }
+ PNFREE(psync);
+ return(NOTOK);
+}
+
+\f
+
+\f
+/*****************************************************************************/
+/* P_DATA - send a PDU via PDataRequest */
+/* */
+/* RETURNS - OK or exits on error */
+/* */
+/* PARAMETERS - */
+/* PDU - a PE containing the PDU to be sent */
+/* */
+/* CLASSIFICATION - utility function for VTPM (used only in processing */
+/* outgoing events that are mapped to P_DATA) */
+/* */
+/*****************************************************************************/
+
+p_data(pdu)
+ PE pdu;
+{
+
+ PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+ if (PDataRequest(sd, &pdu, 1, &pi) != OK)
+ ps_adios (&pi.pi_abort, "P-DATA.REQUEST");
+ pe_free(pdu);
+ return(OK);
+}
+
+\f
+/****************************************************************************/
+/* P_MAJOR_SYNC.REQUEST - send a PDU via PMajSyncRequest */
+/* */
+/* RETURNS - OK or exits on error */
+/* */
+/* PARAMETERS - */
+/* PDU - a PE containing the PDU to be sent */
+/* */
+/* CLASSIFICATION - utility function for VTPM (used only in processing */
+/* outgoing events that are mapped to P_MAJOR_SYNC.REQUEST) */
+/* */
+/****************************************************************************/
+
+p_maj_sync_req(pdu)
+ PE pdu;
+{
+ long ssn;
+
+ PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+ if (PMajSyncRequest(sd, &ssn, &pdu, 1, &pi) != OK)
+ ps_adios (&pi.pi_abort, "P-MAJOR-SYNC.REQUEST");
+ return(OK);
+}
+
+\f
+/****************************************************************************/
+/* P_MAJOR_SYNC.RESPONSE - send a PDU via PMajSyncResponse */
+/* */
+/* RETURNS - OK or exits on error */
+/* */
+/* PARAMETERS - */
+/* PDU - a PE containing the PDU to be sent */
+/* */
+/* CLASSIFICATION - utility function for VTPM (used only in processing */
+/* outgoing events that are mapped to P_MAJOR_SYNC.RESPONSE)*/
+/* */
+/****************************************************************************/
+
+p_maj_sync_resp(pdu)
+ PE pdu;
+{
+ PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+ if (PMajSyncResponse(sd, &pdu, 1, &pi) != OK)
+ ps_adios (&pi.pi_abort, "P-MAJOR-SYNC.RESPONSE");
+ return(OK);
+}
+
+\f
+/***************************************************************************/
+/* P_TYPED_DATA - send a PDU via PTypedRequest */
+/* */
+/* RETURNS - OK or exits on error */
+/* */
+/* PARAMETERS - */
+/* PDU - a PE containing the PDU to be sent */
+/* */
+/* CLASSIFICATION - utility function for VTPM (used only in processing */
+/* outgoing events that are mapped to P_TYPED_DATA) */
+/* */
+/***************************************************************************/
+
+p_typed_data(pdu)
+ PE pdu;
+{
+
+ PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+ if (PTypedRequest(sd, &pdu, 1, &pi) != OK)
+ ps_adios (&pi.pi_abort, "P-TYPED-DATA.REQUEST");
+ return(OK);
+}
+\f
+/*****************************************************************************/
+/* P_RESYNCHRONIZE.REQUEST - send a PDU via PReSyncRequest */
+/* */
+/* RETURNS - OK or exits on error */
+/* */
+/* PARAMETERS - */
+/* PDU - a PE containing the (break) PDU to be sent */
+/* */
+/* CLASSIFICATION - utility function for VTPM (used only in processing */
+/* outgoing events that are mapped to P_RESYNC.REQUEST) */
+/*****************************************************************************/
+
+p_resync_req(pdu,type)
+ PE pdu;
+ int type;
+{
+
+long ssn = 0; /* should be made a global at some time */
+int settings = ST_INIT_VALUE;
+
+#define VTKP_REQ 0x00 /* setting values, see ssap.h */
+#define VTKP_ACC 0x15
+#define VTKP_CHO 0x2a
+
+ PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+ if (PReSyncRequest(sd, type, ssn, settings, &pdu, 1, &pi) != OK)
+/* if (PReSyncRequest(sd, type, 0, 0, (PE *)NULL, 0, &pi) != OK) */
+ ps_adios (&pi.pi_abort, "P-RESYNCHRONIZE.REQUEST");
+ return(OK);
+}
+
+\f
+/****************************************************************************/
+/* P_RESYNC.RESPONSE - send a PDU via PReSyncResponse */
+/* */
+/* RETURNS - OK or exits on error */
+/* */
+/* PARAMETERS - */
+/* PDU - a PE containing the PDU to be sent */
+/* */
+/* CLASSIFICATION - utility function for VTPM (used only in processing */
+/* outgoing events that are mapped to P_RESYNC.RESPONSE) */
+/* */
+/****************************************************************************/
+
+p_resync_resp(pdu)
+ PE pdu;
+{
+
+long ssn = 0; /* should be made a global at some time */
+int settings = ST_INIT_VALUE;
+ PLOG (vt_log, print_VT_PDUs, pdu, NULLCP, 0);
+
+ if (PReSyncResponse(sd, ssn, settings, &pdu, 1, &pi) != OK)
+ ps_adios (&pi.pi_abort, "P-RESYNCHRONIZE.RESPONSE");
+ return(OK);
+}
+
+
+\f
+/****************************************************************************/
+/* ASR - generate an ASR event. (that is send an ASR PDU which is */
+/* passed in as a parameter as user data on the AcAssocResponse.)*/
+/* */
+/* PARAMETERS: PE - a vt ASR PDU */
+/* status (SUCCESS or FAILURE) */
+/* */
+/* RETURNS: OK */
+/****************************************************************************/
+
+asr(pe,status)
+ PE pe;
+ int status;
+{
+
+/* include "pe" as user data on the AcAssocResponse
+*/
+ struct PSAPctxlist *pl = &ps->ps_ctxlist;
+ int s_requirements;
+ long isn;
+ int reason, i;
+
+ if (debug > 2) {
+ for(i=0; i<pl->pc_nctx; i++)
+ advise(LLOG_DEBUG,NULLCP," ctx %d: %d %s %d",
+ i,pl->pc_ctx[i].pc_id,sprintoid(pl->pc_ctx[i].pc_asn),
+ pl->pc_ctx[i].pc_result);
+
+ }
+ if (debug) {
+ advise(LLOG_DEBUG,NULLCP, "in asr.\n");
+ advise(LLOG_DEBUG,NULLCP, "about to call AcAssocResp, sd is %d, pe->pe_id is %d\n", sd, pe->pe_id);
+ }
+
+ if(status == SUCCESS)
+ {
+ status = ACS_ACCEPT;
+ reason = ACS_USER_NULL;
+ }
+ else
+ {
+ status = ACS_PERMANENT;
+ reason = ACS_USER_NOREASON;
+ }
+ s_requirements = SR_DUPLEX | SR_RESYNC | SR_TYPEDATA;
+ isn = 0;
+ pe -> pe_context = 1;
+ if (AcAssocResponse (sd, status, reason, NULLOID, NULLAEI,
+ NULLPA,
+ &ps->ps_ctxlist,
+ ps->ps_defctxresult, ps->ps_prequirements, s_requirements,isn,
+ ps->ps_settings, &ps->ps_connect, &pe, 1, aci) == NOTOK)
+ acs_adios (aca, "A-ASSOCIATE.RESPONSE");
+
+ if (debug)
+ advise(LLOG_DEBUG,NULLCP, "sent AcAssociate Response\n");
+ return(OK);
+}
+
+\f
+
+send_bad_asr(reason) /*Compose and send ASR with result = failure. Encode
+ ASR-FailureReason using the reason parameter
+ (0 means no reason).
+ */
+
+int reason;
+{
+
+ PE asr_pe;
+ ASR_MSG ud;
+
+ bzero ((char *) &ud, sizeof ud);
+ if(reason)
+ {
+ ud.valid_reason = 1;
+ ud.reason.type = 1;
+ ud.reason.provider_reason = reason;
+ }
+ else ud.valid_reason = 0;
+ ud.result = 0; /*Failure code*/
+ ud.valid_imp = 0;
+ ud.valid_coll = 0;
+ ud.valid_arg_list = 0;
+ ud.version.bitstring = 0x00;
+ ud.version.bitcount = 5;
+ if(build_ASRPDU_ASRpdu(&asr_pe,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+ adios (NULLCP, "ASR build failure (%s)", PY_pepy);
+
+ return(asr(asr_pe,FAILURE)); /*Send the PDU thru Association control*/
+}
+\f
+
+send_rlr(pe) /*Send RLR (Release Response) PDU to peer. The RLR is
+ built by vrelrsp(). It is sent by a call to Association
+ Control.
+ */
+PE pe;
+{
+ pe -> pe_context = 1;
+ if(AcRelResponse(sd,ACS_ACCEPT,ACR_NORMAL,&pe,1,aci) == NOTOK)
+ acs_adios (&aci->aci_abort, "A-RELEASE.RESPONSE");
+}
+\f
+
+clear_vte() /*Clear VT Environment. */
+{
+
+ /*Nothing to do for now since we have no formalized environment
+ and we exit VTP when association ends.
+ */
+}
+\f
+
+vgvt_ind() /*Indication to User that peer has given the token*/
+{
+
+ /*Don't know how to indicate this to user yet*/
+}
+\f
+
+vrtq_ind() /*Indicate to User that peer has requested token*/
+{
+
+ /*Don't know how to give indication to user.
+ Synchronous? Asynch interrupt??? */
+}
+\f
+
+give_token() /*Transfer Token to peer. For VTP, all tokens are given
+ at once so no need to discriminate between them.
+ */
+{
+
+ int vt_tokens;
+ struct PSAPindication vt_pi;
+
+ vt_tokens = ST_RLS_TOKEN;
+
+ if(PGTokenRequest(sd,vt_tokens,&vt_pi) == NOTOK
+ && vt_pi.pi_abort.pa_reason != PC_OPERATION)
+ ps_adios (&vt_pi.pi_abort, "P-GIVE-TOKENS.REQUEST");
+}
+\f
+
+request_token() /*Request Tokens from peer*/
+{
+
+ int vt_tokens;
+ struct PSAPindication vt_pi;
+
+ vt_tokens = ST_RLS_TOKEN;
+
+ if(PPTokenRequest(sd,vt_tokens,NULLPEP,0,&vt_pi) == NOTOK
+ && vt_pi.pi_abort.pa_reason != PC_OPERATION)
+ ps_adios (&vt_pi.pi_abort, "P-PLEASE-TOKENS.REQUEST");
+}
+\f
+send_all() /*TEMP -- Should be supplied by Sector 5 actions*/
+{
+ advise(LLOG_DEBUG,NULLCP, "send_all dummy routine");
+}
+
+/* \f */
+
+void acs_adios (aa, event)
+register struct AcSAPabort *aa;
+char *event;
+{
+ acs_advise (aa, event);
+
+ finalbye ();
+
+ _exit (1);
+}
+
+
+static void acs_advise (aa, event)
+register struct AcSAPabort *aa;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (aa -> aca_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ AcErrString (aa -> aca_reason),
+ aa -> aca_cc, aa -> aca_cc, aa -> aca_data);
+ else
+ (void) sprintf (buffer, "[%s]", AcErrString (aa -> aca_reason));
+
+ advise (LLOG_NOTICE,NULLCP, "%s: %s (source %d)", event, buffer,
+ aa -> aca_source);
+}
+
+
+static void ps_adios (pab, event)
+register struct PSAPabort *pab;
+char *event;
+{
+ ps_advise (pab, event);
+
+ finalbye ();
+
+ _exit (1);
+}
+
+
+static void ps_advise (pab, event)
+register struct PSAPabort *pab;
+char *event;
+{
+ char buffer[BUFSIZ];
+
+ if (pab -> pa_cc > 0)
+ (void) sprintf (buffer, "[%s] %*.*s",
+ PErrString (pab -> pa_reason),
+ pab -> pa_cc, pab -> pa_cc, pab -> pa_data);
+ else
+ (void) sprintf (buffer, "[%s]", PErrString (pab -> pa_reason));
+
+ advise (LLOG_NOTICE,NULLCP, "%s: %s%s", event, buffer,
+ pab -> pa_peer ? " (peer initiated)" : "");
+}
--- /dev/null
+/* vtpm.h - VTPM: definitions */
+
+/*
+ * $Header: /f/osi/vt/RCS/vtpm.h,v 7.1 91/02/22 09:48:32 mrose Interim $
+ *
+ *
+ * $Log: vtpm.h,v $
+ * Revision 7.1 91/02/22 09:48:32 mrose
+ * Interim 6.8
+ *
+ * Revision 7.0 89/11/23 22:31:58 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include <errno.h>
+#include <stdio.h>
+
+#include "acsap.h" /* definitions for AcS-USERs */
+#include "logger.h"
+
+/* Make sure this is here in new versions */
+/*#include "sector1.h"*/
+
+
+#define TRUE 1
+#define FALSE 0
+
+#define ERR -1
+#define E_ERROR -1
+#define E_EOF -2
+
+#define E_NOEVENT 1
+#define E_READ 2
+
+#define INPUT 1
+#define OUTPUT 2
+
+#define DEFINED 1
+#define UNDEFINED 0
+
+#define BASIC 1
+
+#define WACI_WACA 0
+#define WAVAR 1
+
+#define FAILURE 0
+#define SUCCESS 1
+#define WARNING 2
+
+#define ECHO_NOW 0
+#define NOT_ECHO_NOW 1
+
+#define DISPLAY 0
+#define CONTROL 2
+
+#define SEQUENCED 1
+#define NONSEQUENCED 2
+
+#define COLL_DET 1
+#define PROFILE_NG 4
+
+#define TEXT 5
+
+#define WOULDBLOCK -3
+
+/* type identifiers */
+#define G_COLLISION_WINNER 1
+#define G_PARM_VLIST 6
+#define G_RESULT3 11
+
+/* Incoming Events -- Table 25, ISO 9041 */
+
+#define VASSreq 1 /*VT-ASSOCIATE request*/
+#define VASSrsp 2 /*VT-ASSOCIATE response*/
+#define VBRKreq 3 /*VT-BREAK request*/
+#define VBRKrsp 4 /*VT-BREAK response*/
+#define VDACKreq 5 /*VT-ACK-RECEIPT request*/
+#define VDATreq_u 6 /*VT-DATA request urgent priority*/
+#define VDATreq_h 7 /*VT-DATA request high priority*/
+#define VDATreq_n 8 /*VT-DATA request normal*/
+#define VDATreq_sqtr 9 /*VT-DATA request trigger control*/
+#define VDELreq 10 /*VT-DELIVER request*/
+#define VENEGreq 11 /*VT-END-NEG request*/
+#define VENEGrsp 12 /*VT-END-NEG response*/
+#define VGVTreq 13 /*VT-GIVE-TOKENS request*/
+#define VNACCreq 14 /*VT-NEG-ACCEPT (negotiation accept)*/
+#define VNINVreq 15 /*Negotiation Invitaion*/
+#define VNOFFreq 16 /*Negotiation Offer*/
+#define VNREJreq 17 /*Negotiation Reject*/
+#define VRELreq 18 /*VT-RELEASE request*/
+#define VRELrsp 19 /*VT-RELEASE response*/
+#define VRQTreq 20 /*VT-REQUEST-TOKENS request*/
+#define VSNEGreq 21 /*Start Negotiation request*/
+#define VSNEGrsp 22 /*Start Negotiation response*/
+#define VSWPreq 23 /*Switch Profile request*/
+#define VSWPrsp 24 /*Switch Profile response*/
+#define VUABreq 25 /*VT-U-ABORT request*/
+#define APQ 26 /*VT-P-ABORT request*/
+#define ASQ 27 /*Associate Request*/
+#define ASR 28 /*Associate Response*/
+#define AUQ 29 /*VT-U-ABORT request*/
+#define BKQ 30 /*Break Request*/
+#define BKR 31 /*Break Response*/
+#define DAQ 32 /*VT-ACK-RECEIPT*/
+#define DLQ 33 /*VT-DELIVER*/
+#define HDQ 34 /*VT-EXPEDITED-DATA*/
+#define ENQ 35 /*End Negotiation Request*/
+#define ENR 36 /*End Negotiation Response*/
+#define GTQ 37 /*VT-GIVE-TOKEN*/
+#define NAQ 38 /*Negotiation Accept Request*/
+#define NDQ_ntr 39 /*VT-DATA -- No Trigger Update*/
+#define NDQ_tr 40 /*VT-DATA -- Trigger Update*/
+#define NJQ 41 /*Negotiation Reject Request*/
+#define NIQ 42 /*Negotiation Invite Request*/
+#define NOQ 43 /*Negotiation Offer Request*/
+#define RLQ 44 /*VT-RELEASE-REQ*/
+#define RLR 45 /*VT-RELEASE-RESP*/
+#define RTQ 46 /*VT-REQUEST-TOKEN*/
+#define SPQ 47 /*VT-SWITCH-PROFILE-REQ*/
+#define SPR 48 /*VT-SWITCH-PROFILE-RESP*/
+#define SNQ 49 /*Start Negotiation Request*/
+#define SNR 50 /*Start Negotiation Response*/
+#define UDQ 51 /*VT-UNCONTROLLED-DATA*/
+#define AUTO 52 /*Internal event not defined by VTP*/
+#define VTAB 53 /*Irrecoverable exception condition*/
+#define PAB 54 /*Failure Indication*/
+
+/* Outgoing Events -- Table 27, ISO 9041 */
+
+#define VACKind 55 /*VT-ACK-RECEIPT Indication*/
+#define VASSind 56 /*VT-ASSOCIATE Indication*/
+#define VASScnf 57 /*VT-ASSOCIATE Confirm*/
+#define VBRKind 58 /*VT-BREAK Indication*/
+#define VBRKcnf 59 /*VT-BREAK Confirm*/
+#define VDATind_u 60 /*VT-DATA indication -- urgent object*/
+#define VDATind_h 61 /*VT-DATA indication -- high object*/
+#define VDATind_n 62 /*VT-DATA indication -- normal object*/
+#define VDATind_Vnt 63 /*Sequence of Vnt VT-DATA normal*/
+#define VDELind 64 /*VT-DELIVER indication*/
+#define VENEGind 65 /*VT-END-NEG indication*/
+#define VENEGcnf 66 /*VT-END-NEG confirm*/
+#define VGVTind 67 /*VT-GIVE-TOKENS indication*/
+#define VNINVind 68 /*VT-NEG-INVITE indication*/
+#define VNOFFind 69 /*VT-NEG-OFFER indication*/
+#define VNACCind 70 /*VT-NEG-ACCEPT indication*/
+#define VNREJind 71 /*VT-NEG-REJECT indication*/
+#define VPABind 72 /*VT-P-ABORT indication*/
+#define VRELind 73 /*VT-RELEASE indication*/
+#define VRELcnf 74 /*VT-RELEASE confirm*/
+#define VRQTind 75 /*VT-REQUEST-TOKENS indication*/
+#define VSNEGind 76 /*VT-START-NEG indication*/
+#define VSNEGcnf 77 /*VT-START-NEG confirm*/
+#define VSWPind 78 /*VT-SWITCH-PROFILE indication*/
+#define VSWPcnf 79 /*VT-SWITCH-PROFILE confirm*/
+#define VUABind 80 /*VT-U-ABORT indication*/
+#define NDQseq_ntr 81 /*Sequence of NDQ-ntr to xmit updates*/
+#define NDQseq_tr 82 /*1 NDQ-tr preceeded by >=1 NDQ-ntr*/
+#define NDQ_x_tr 83
+#define NDQ_x_ntr 84
+
+
+
+/* Sector 1 States */
+
+#define S1_01 0 /*No Association*/
+#define S1_02B 1 /*Associate -- Awaiting target*/
+#define S1_02S 2 /*Associate -- Awaiting target*/
+#define S1_03B 3 /*Associate -- Awaiting User*/
+#define S1_03S 4 /*Associate -- Awaiting User*/
+#define S1_10B 5 /*Environment Not Agreed*/
+#define S1_10N 6
+#define S1_10T 7
+#define S1_50B 8
+#define S1_51Q 9 /*Release -- Awaiting Peer*/
+#define S1_51R 10 /*Release -- Awaiting User*/
+#define S1_51N 11 /*Release -- Awaiting User*/
+#define S1_51T 12 /*Release -- Awaiting Peer*/
+
+
+/* Sector 5 States */
+
+#define S5_400B 0 /*Data Transfer*/
+#define S5_402B 1 /*Data Xfer -- Awaiting Ack from user*/
+#define S5_420B 2 /*Data Xfer -- Awaiting Ack from peer*/
+#define S5_422B 3 /*Data xfer -- Awaiting Ack (Both)*/
+#define S5_40N 4 /*Data Transfer*/
+#define S5_40T 5 /*Data Transfer*/
+#define S5_42T 6 /*Data Xfer -- Awaiting Ack from peer*/
+#define S5_42N 7 /*Data Xfer -- Awaiting Ack from user*/
+#define S5_61 8 /*Break Request rcv'd from User*/
+#define S5_62 9 /*Break Request rcv'd from Peer*/
+
+
+#define INITIATOR 0
+#define ACCEPTOR 1
+#define ACHOICE 2
+
+
+
+/* PDU Types (Table 4, ISO 9041) */
+
+#define ASQ_PDU 0
+#define ASR_PDU 1
+#define RLR_PDU 2
+#define AUQ_PDU 3
+#define APQ_PDU 4
+#define HDQ_PDU 5
+#define NDQ_PDU 6
+#define UDQ_PDU 7
+#define BKQ_PDU 8
+#define BKR_PDU 9
+#define DLQ_PDU 10
+#define DAQ_PDU 11
+#define SPQ_PDU 12
+#define SPR_PDU 13
+#define SNQ_PDU 14
+#define SNR_PDU 15
+#define ENQ_PDU 16
+#define ENR_PDU 17
+#define NIQ_PDU 18
+#define NOQ_PDU 19
+#define NAQ_PDU 20
+#define NJQ_PDU 21
+
+#define PEPYPARM int *
+
+PE pre, pwe;
+PE mkdeliver();
+int fd,
+ readfds,
+ writefds,
+ exfds,
+ sd,
+ connected,
+ netfile;
+
+char *dprofile, *cprofile;
+char *myname, ttyname();
+extern PE p_ondq;
+extern LLog _vt_log, *vt_log;
+
+
+extern int errno;
+extern unsigned state, sector;
+
+int vns,
+ allpmde, /* all draft VTE parameters defined */
+ allpmdu, /* all draft VTE parameters defined or undefined */
+ cnw, /* collision winner right assigned to this VTPM */
+ dcno, /* no delivery control */
+ dcqua, /* quarantine delivery control */
+ dcsim, /* simple delivery control */
+ pmacc, /* parameter values acceptable */
+ dr_pm_st,/* draft parameter status:
+ DEFINED,
+ UNDEFINED,
+ OFI, (offered, initiator)
+ OFR, (offered, responder)
+ COFI, (counter-offered, initiator)
+ COFR, (counter-offered, responder)
+ INVI, (invited, initiator)
+ INVR (invited, responder)
+ */
+ pracc,
+ vtpma,
+ vcwa, /* whether the collision winner right is owned */
+ vena, /* agreement on current VTE */
+ vnt, /* number of VT service data units held for local delivery */
+ vns, /* number of VT service data units held for transmission */
+ vacc, /*action choice: switch, restore, or not specified*/
+ vacp, /*action proposal: switch, restore, or responder
+ choice*/
+ vrea, /*failure reason: collision detected or profile not
+ supplied*/
+ vrjo, /*rejection option: retain, discard, or responder
+ choice*/
+ vrsl, /*result: succes, failure, or success with warning*/
+ vsmd, /*1 if S-Mode, 0 if A-Mode*/
+ vtok, /*1 if tokens held, 0 otherwise*/
+ vtkp, /*token parameters*/
+ waca, /*WACA right*/
+ vra, /*Boolean recording of acknowledgement request*/
+ G_Func_Units, /*Bit map of Functional Units requested*/
+ wavar, /* boolean, this VTPM has the token */
+ waci, /* boolean, this VTPM is assigned the waci right */
+ del_cont; /* type of delivery control */
+
+
+/*
+ profile is name of the profile. This is also used for the draft profile.
+*/
+
+int s1_01(),
+ s1_02B(),
+ s1_02S(),
+ s1_03B(),
+ s1_03S(),
+ s1_10B(),
+ s1_10N(),
+ s1_10T(),
+ s1_50B(),
+ s1_51Q(),
+ s1_51R(),
+ s1_51N(),
+ s1_51T();
+
+int s5_400B(),
+ s5_402B(),
+ s5_420B(),
+ s5_422B(),
+ s5_40N(),
+ s5_40T(),
+ s5_42N(),
+ s5_42T(),
+ s5_61(),
+ s5_62();
+
+
+extern struct SSAPref sfs;
+extern struct SSAPref *sf;
+extern struct PSAPaddr *pa;
+extern struct AcSAPconnect accs;
+extern struct AcSAPconnect *acc;
+extern struct AcSAPrelease acrs;
+extern struct AcSAPrelease *acr;
+extern struct AcSAPindication acis;
+extern struct AcSAPindication *aci;
+extern struct AcSAPabort *aca;
+extern AEI aei;
+extern OID ctx,
+ pci;
+
+extern struct AcSAPstart acss;
+extern struct AcSAPstart *acs;
+extern struct PSAPstart *ps;
+extern struct PSAPindication pi;
+extern struct PSAPdata px;
+extern struct PSAPfinish *pf;
+
+void finalbye ();
+void adios (), advise ();
+void acs_adios (), acs_advise ();
+void ps_adios (), ps_advise ();
+
+int connected; /*TEMP -- for sector 1 testing only -- will be supplied by VTP*/
+
+char *malloc();
--- /dev/null
+/* vtuser.c - VT user routines */
+
+#ifndef lint
+static char *rcsid = "$Header: /f/osi/vt/RCS/vtuser.c,v 7.5 91/02/22 09:48:34 mrose Interim $";
+#endif
+
+/*
+ * $Header: /f/osi/vt/RCS/vtuser.c,v 7.5 91/02/22 09:48:34 mrose Interim $
+ *
+ *
+ * $Log: vtuser.c,v $
+ * Revision 7.5 91/02/22 09:48:34 mrose
+ * Interim 6.8
+ *
+ * Revision 7.4 90/12/11 10:53:12 mrose
+ * lock-and-load
+ *
+ * Revision 7.3 90/10/23 20:44:48 mrose
+ * update
+ *
+ * Revision 7.2 90/07/09 14:52:10 mrose
+ * sync
+ *
+ * Revision 7.1 89/11/30 23:51:45 mrose
+ * pa2str
+ *
+ * Revision 7.0 89/11/23 22:32:00 mrose
+ * Release 6.0
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+#include "vtpm.h"
+#include "sector1.h"
+#include "sector5.h"
+#include <sys/ioctl.h>
+
+#undef PTYBUG /*When testing Break and demon not started from rc.local,
+ this turns off resetting local echo so ioctl to pty
+ will not cause demon to hang up.
+ */
+
+#undef PEPYPARM
+#define PEPYPARM int *
+
+
+extern char peerhost[];
+extern struct PSAPaddr ts_bound;
+static char *myservice = "terminal";
+
+static char *mycontext = "iso vt";
+static char *mypci = "iso vt pci";
+
+static char ascii_go_repertoire[] = {0x1a,0x28,0x42,0x00}; /*ESC 2/8 4/2*/
+ /*should be followed by 3 "voids" whatever that is*/
+static char full_ascii_repertoire[] = {0x1a,0x28,0x42,/*VOID*/0x1a,0x21,0x40,0x00};
+ /*Approximation to GO & CO ASCII sets*/
+
+extern char *isodeversion;
+extern char *my_displayobj;
+extern int G_Func_Units; /*Functional Units for this Association*/
+extern int vcwa; /*Collision Winner (TRUE if owned by this peer)*/
+extern int vsmd, vtok;
+extern int transparent;
+extern char na_image;
+extern char ni_image;
+extern VT_PROFILE vtp_profile;
+extern int telnet_profile;
+extern int do_break;
+extern int debug;
+
+int default_rep_flag = 0;
+
+/*************************************************************************/
+/* VASS_REQ - create an ASQ PDU and generate a VASSreq event to */
+/* send it. */
+/* */
+/* PARAMETERS - */
+/* */
+/* CLASS - class of VTP service (only BASIC supported) */
+/* */
+/* ACC_RI - access rights */
+/* */
+/* PROFILE - designator of the VT profile to request */
+/*************************************************************************/
+/* ARGSUSED */
+vass_req(class, acc_ri, profile)
+int class, acc_ri;
+VT_PROFILE *profile;
+{
+ PE a_req;
+ ASQ_MSG ud;
+ char my_version, my_fu;
+ OID p_oid;
+ int i;
+
+ my_version = 0x01;
+ if(do_break) my_fu = destBreak;
+ else my_fu = 0x00;
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.class = class;
+ ud.valid_imp = 0;
+ ud.coll_winner = ACHOICE;
+ ud.valid_coll = 1;
+ ud.version.bitstring = my_version;
+ ud.version.bitcount = 1;
+ if( !strcmp(profile->profile_name,"telnet") )
+ {
+ ud.valid_prof = 1;
+ ud.asq_profile.oid_true = 1;
+ if((p_oid = ode2oid(profile->profile_name)) == NULLOID)
+ adios(NULLCP,"%s: unknown profile", profile->profile_name);
+ ud.asq_profile.prof_oid = p_oid;
+
+ ud.asq_profile.num_sp_param = 0;
+ ud.asq_profile.num_cds_objects = 0;
+ ud.asq_profile.num_css_objects = 0;
+ ud.asq_profile.num_dev_objects = 0;
+ ud.asq_profile.del_ctrl.bitcount = 0;
+
+ ud.asq_profile.num_cds_objects = 1;
+ ud.asq_profile.cds_offer_list[0].obj_name = "D";
+ for(i=0; i<ud.asq_profile.num_cds_objects; i++)
+ {
+ ud.asq_profile.cds_offer_list[i].valid_x_dim = 0;
+ ud.asq_profile.cds_offer_list[i].valid_y_dim= 0;
+ ud.asq_profile.cds_offer_list[i].valid_z_dim = 0;
+ ud.asq_profile.cds_offer_list[i].erasure.bitcount = 0;
+ ud.asq_profile.cds_offer_list[i].valid_emp_list = 0;
+ ud.asq_profile.cds_offer_list[i].valid_fore_color = 0;
+ ud.asq_profile.cds_offer_list[i].valid_back_color = 0;
+ ud.asq_profile.cds_offer_list[i].access_right.bitcount = 0;
+ ud.asq_profile.cds_offer_list[i].valid_rep_list = 0;
+ }
+ if(!vtp_profile.arg_val.tel_arg_list.full_ascii)
+ {
+ ud.asq_profile.cds_offer_list[0].valid_rep_list = 1;
+ ud.asq_profile.cds_offer_list[0].rep_offer.valid_cap = 1;
+ ud.asq_profile.cds_offer_list[0].rep_offer.capability.type = 0;
+ ud.asq_profile.cds_offer_list[0].rep_offer.capability.value = 1;
+ ud.asq_profile.cds_offer_list[0].rep_offer.num_reps = 1;
+ ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].rep_type = 2;
+ ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].valid_font_cap = 0;
+ ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].num_fonts = 0;
+ ud.asq_profile.cds_offer_list[0].rep_offer.repertoire[0].rep_assign =
+ ascii_go_repertoire;
+ }
+
+ ud.asq_profile.cds_offer_list[0].valid_x_dim = 1;
+ ud.asq_profile.cds_offer_list[0].x_dim.bound_type = 0;
+ ud.asq_profile.cds_offer_list[0].x_dim.addressing.bitcount = 0;
+ ud.asq_profile.cds_offer_list[0].x_dim.absolute.bitcount = 0;
+ ud.asq_profile.cds_offer_list[0].x_dim.window_type = 2;
+ ud.asq_profile.cds_offer_list[0].x_dim.window.type = 0;
+ ud.asq_profile.cds_offer_list[0].x_dim.window.value =
+ vtp_profile.arg_val.tel_arg_list.x_window;
+
+ vtok = 1;
+ vsmd = 0;
+ }
+ else if( !strcmp(profile->profile_name,"default") )
+ {
+ ud.valid_prof = 0;
+ ud.asq_profile.oid_true = 0;
+ ud.asq_profile.num_sp_param = 0;
+ ud.asq_profile.num_cds_objects = 0;
+ ud.asq_profile.num_css_objects = 0;
+ ud.asq_profile.num_dev_objects = 0;
+ vtok = 1;
+ vsmd = 0;
+ }
+ else
+ adios(NULLCP, "%s: unsupported profile", profile->profile_name);
+
+ ud.func_units.bitstring = my_fu;
+ ud.func_units.bitcount = 5;
+
+ if(build_ASQPDU_ASQpdu(&a_req,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+ adios(NULLCP, "ASQ build failure (%s)", PY_pepy);
+
+ (void)do_event(VASSreq, a_req);
+}
+
+\f
+/******************************************************************************/
+/* VASS_RESP - create an ASR PDU and generate a VASSRSP event to send it.*/
+/* */
+/* PARAMETERS - */
+/* */
+/* RESULT - SUCCESS or FAILURE */
+/******************************************************************************/
+
+vass_resp(result)
+int result;
+{
+ PE a_resp;
+ char my_version, my_fu;
+ ASR_MSG ud;
+ int i;
+
+ my_version = 0x01;
+ if(G_Func_Units & destBreak) do_break = 1;
+ else do_break = 0;
+ my_fu = G_Func_Units & destBreak; /*VT-Break is only Functional Unit
+ we will accept*/
+ bzero ((char *) &ud, sizeof ud);
+ ud.valid_reason = 0;
+ ud.result = result;
+ ud.valid_imp = 0;
+ ud.valid_coll = 1;
+ if(vcwa == TRUE) ud.coll_winner = ACCEPTOR;
+ else ud.coll_winner = INITIATOR;
+ ud.version.bitstring = my_version;
+ ud.version.bitcount = 1;
+ if( !strcmp(vtp_profile.profile_name,"telnet") )
+ {
+ ud.valid_arg_list = 1;
+ ud.arg_list.num_css_objects = 0;
+ ud.arg_list.num_dev_objects = 0;
+ ud.arg_list.num_cds_objects = 1;
+
+ ud.arg_list.cds_val[0].obj_name = "D";
+ for(i=0; i<ud.arg_list.num_cds_objects; i++)
+ {
+ ud.arg_list.cds_val[i].dimensions = 0;
+ ud.arg_list.cds_val[i].valid_x_dim = 0;
+ ud.arg_list.cds_val[i].valid_y_dim = 0;
+ ud.arg_list.cds_val[i].valid_z_dim = 0;
+ ud.arg_list.cds_val[i].valid_erasure= 0;
+ ud.arg_list.cds_val[i].valid_emp_list = 0;
+ ud.arg_list.cds_val[i].valid_fore_color = 0;
+ ud.arg_list.cds_val[i].valid_back_color = 0;
+ ud.arg_list.cds_val[i].valid_access_right = 0;
+ ud.arg_list.cds_val[i].valid_rep_list = 0;
+ ud.arg_list.cds_val[i].rep_value.repertoire[0].valid_font_cap = 0;
+ ud.arg_list.cds_val[i].rep_value.repertoire[0].num_fonts = 0;
+ }
+ if( !default_rep_flag)
+ {
+ ud.arg_list.cds_val[0].valid_rep_list = 1;
+ ud.arg_list.cds_val[0].rep_value.valid_cap = 1;
+ ud.arg_list.cds_val[0].rep_value.capability = 1;
+ ud.arg_list.cds_val[0].rep_value.num_reps = 1;
+ ud.arg_list.cds_val[0].rep_value.repertoire[0].rep_type = 2;
+ ud.arg_list.cds_val[0].rep_value.repertoire[0].rep_assign =
+ vtp_profile.arg_val.tel_arg_list.full_ascii ?
+ full_ascii_repertoire : ascii_go_repertoire;
+ }
+ ud.arg_list.num_sp_param = 0;
+ ud.arg_list.cds_val[0].valid_x_dim = 1;
+ ud.arg_list.cds_val[0].x_dim.bound_type = 0;
+ ud.arg_list.cds_val[0].x_dim.valid_addr = 0;
+ ud.arg_list.cds_val[0].x_dim.valid_abs = 0;
+ ud.arg_list.cds_val[0].x_dim.window_type = 2;
+ ud.arg_list.cds_val[0].x_dim.window =
+ vtp_profile.arg_val.tel_arg_list.x_window;
+
+ }
+ else if( !strcmp(vtp_profile.profile_name,"default") )
+ {
+ ud.valid_arg_list = 0;
+ ud.arg_list.num_sp_param = 0;
+ ud.arg_list.num_cds_objects = 0;
+ ud.arg_list.num_css_objects = 0;
+ ud.arg_list.num_dev_objects = 0;
+ }
+ else
+ adios (NULLCP, "invalid profile stored");
+ ud.func_units.bitstring = my_fu;
+ ud.func_units.bitcount = 5;
+
+ if(build_ASRPDU_ASRpdu((PE *)&a_resp,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+ advise(LLOG_NOTICE,NULLCP, "ASR build failure (%s) -- continuing",
+ PY_pepy);
+ return(do_event(VASSrsp, a_resp));
+}
+
+\f
+/*************************************************************************/
+/* "pe" will be to store NDQ contents that could not be mapped to */
+/* the cbuf because of lack of buffer space. There is only one, */
+/* because a new NDQ can be combined with "pe" rather than creating */
+/* a queue of PEs */
+/*************************************************************************/
+
+PE pe_buf = NULLPE;
+
+
+/************************************************************************/
+/* VRELREQ - Generate a VRELREQ to VT State Machine */
+/* */
+/* PARAMETERS - none */
+/************************************************************************/
+
+vrelreq()
+{
+ PE r_req;
+
+ r_req = NULLPE;
+ (void)do_event(VRELreq,r_req);
+}
+\f
+/*************************************************************************/
+/* VRELRSP - create an RLR PDU and send it and generate a VRELRSP-S */
+/* */
+/* PARAMETERS - */
+/* */
+/* RESULT - success or failure */
+/* */
+/*************************************************************************/
+
+vrelrsp(result)
+int result;
+{
+
+ int offset = 0;
+ PE r_rsp, r_result, r_coll;
+
+ if ((r_rsp = pe_alloc(PE_CLASS_CONT, PE_FORM_CONS, RLR_PDU)) == NULLPE)
+ adios (NULLCP, "RLR build failure (out of memory)");
+
+ if ((r_result = num2prim((integer)result,PE_CLASS_CONT,0)) == NULLPE)
+ adios (NULLCP, "RLR build failure (out of memory)");
+
+ if (seq_add(r_rsp,r_result,offset) == NOTOK)
+ adios (NULLCP, "RLR build failure (%s)", pe_error(r_rsp -> pe_errno));
+
+ if(result == COLL_DET)
+ {
+ if((r_coll = num2prim((integer)0,PE_CLASS_CONT,2)) == NULLPE)
+ adios (NULLCP, "RLR build failure (out of memory)");
+ if (seq_add(r_rsp,r_coll,++offset) == NOTOK)
+ adios (NULLCP, "RLR build failure (%s)",
+ pe_error(r_rsp -> pe_errno));
+ }
+ if (seq2prim(r_rsp) == NULLPE)
+ adios(NULLCP, "RLR encode error, seq2prim: (%s)", PY_pepy);
+ (void)do_event(VRELrsp,r_rsp);
+
+ pe_free(r_coll);
+ pe_free(r_result);
+ pe_free(r_rsp);
+
+}
+\f
+
+vrelcnf()
+{
+ if (debug)
+ advise(LLOG_DEBUG, NULLCP, "Release Confirmed");
+}
+\f
+
+vrelind()
+{
+ if (AcFINISHser(sd,pf,aci) == NOTOK)
+ acs_adios (&aci->aci_abort, "A-RELEASE.INDICATION");
+
+ vrelrsp(SUCCESS);
+ return(OK);
+}
+
+\f
+
+PE p_ondq = NULLPE; /* the current "ndq" being prepared for sending*/
+PE p_ovtsdi = NULLPE; /* the current "vtsdi" */
+int sdi_count = 0; /* count of "vtsdi"s in current NDQ*/
+PE p_oobjupdt = NULLPE; /* the current "object_update" */
+int obj_count = 0; /* count of "object_update"s in current "vtsdi"*/
+int updt_count = 0; /* count of updates in the current "object update"*/
+int cur_emode = NOT_ECHO_NOW; /* echo mode (ECHO_NOW or NOT_ECHO_NOW)*/
+
+/*************************************************************************/
+/* VT_TEXT - Add a text update to the PE that represents */
+/* an NDQ of buffered updates awaiting delivery. */
+/* */
+/* When we do a control object update, the current buffer of */
+/* display object updates is terminated and a new one will be */
+/* started next time a display object update is queued. */
+/* (this is so we can synchronize control updates with */
+/* display updates.) */
+/* */
+/* Likewise, whenever we queue a display object update, we */
+/* terminate the current sequence of control object updates. */
+/* */
+/* Whenever we change echo mode (ECHO_NOW or NOT_ECHO_NOW) */
+/* we have to start a new "vtsdi". */
+/* This requires that we terminate the current buffers of */
+/* display object and control object updates. */
+/* */
+/* PARAMETERS - */
+/* */
+/* STR - the character string to be added to the NDQ PDU. */
+/* LEN - Number of characters in the string. */
+/*************************************************************************/
+
+vt_text(str, len)
+ char *str;
+ int len;
+{
+ TEXT_UPDATE ud;
+
+ if (debug > 6)
+ {
+ int i;
+
+ (void)ll_log(vt_log, LLOG_DEBUG, NULLCP, ("vt_text sending"));
+ (void)ll_printf (vt_log, "<<");
+ for(i=0; i<len; i++)
+ (void)ll_printf (vt_log, "%02x ", *(str+i));
+ (void)ll_printf (vt_log, ">>\n");
+ (void)ll_sync (vt_log);
+ }
+
+ bzero ((char *) &ud, sizeof ud);
+ ud.echo_sw = cur_emode;
+ ud.type_sw = 0; /*Display object*/
+ ud.updates.do_list.do_name = my_displayobj;
+ ud.updates.do_list.do_type = DO_TEXT; /*Text*/
+ ud.updates.do_list.do_cmd.text_ud.text_ptr = str;
+ ud.updates.do_list.do_cmd.text_ud.text_count = len;
+ send_queue(ud);
+
+ return(OK);
+}
+\f
+
+send_queue(ud) /*Build NDQ with update supplied in ud structure*/
+TEXT_UPDATE ud;
+{
+
+ PE vtsdip;
+
+ if(p_ondq == NULLPE) /*Nothing waiting to be sent*/
+ {
+ if(build_NDQPDU_NDQpdu(&p_ondq,1,NULL,NULLCP,(PEPYPARM)&ud) == NOTOK)
+ adios(NULLCP,"NDQ build failure (%s)", PY_pepy);
+ p_ondq->pe_context = 1;
+ }
+ else
+ {
+ if(build_NDQPDU_VTsdi(&vtsdip,1,NULL,NULLCP,(int *)&ud) == NOTOK)
+ adios(NULLCP,"VTsdi build failure (%s)", PY_pepy);
+ vtsdip->pe_context = 1;
+ if(seq_add(p_ondq,vtsdip,-1) == NOTOK)
+ adios(NULLCP,"NDQ build failure (%s)",
+ pe_error(p_ondq->pe_errno));
+ }
+}
+
+\f
+
+/* SETEMODE - set echo mode
+
+ PARAMETERS -
+
+ MODE - ECHO_NOW or NOT_ECHO_NOW
+*/
+
+setemode(mode)
+ int mode;
+{
+ if (mode != ECHO_NOW && mode != NOT_ECHO_NOW)
+ return(NOTOK);
+ if (cur_emode != mode) {
+ p_ovtsdi = NULLPE;
+ sdi_count = 0;
+ p_oobjupdt = NULLPE;
+ obj_count = 0;
+ cur_emode = mode;
+ }
+ return(OK);
+}
+\f
+
+/* this data structure will buffer character output
+ that is ready to be read by the application or terminal.
+*/
+
+#define CBUFSIZE 10240
+
+struct char_buffer {
+ int max_len, queued;
+ unsigned char *head, *tail;
+ unsigned char buf[CBUFSIZE];
+};
+
+struct char_buffer cbuf = { CBUFSIZE, 0 };
+
+/************************************************************************/
+/* GETCH - get a character from the buffer waiting to */
+/* be read by the application */
+/* */
+/* RETURNS - the character, NOTOK if no data, or an error code (<0)*/
+/************************************************************************/
+
+
+int
+getch()
+{
+ int c;
+
+ if (data_pending() == FALSE) {
+ if (!connected)
+ return(E_EOF);
+ else
+ return(WOULDBLOCK);
+ }
+ c = *cbuf.head;
+ if (++cbuf.head >= cbuf.buf + CBUFSIZE)
+ cbuf.head = cbuf.buf;
+ cbuf.queued--;
+ if (debug > 1)
+ advise(LLOG_DEBUG, NULLCP, "normal return from getch, c is %c,queued is %d", c,cbuf.queued);
+ return(c);
+}
+
+/* at some point we need to use the async. interface to the network
+ so that at any time when data becomes available, we trap to a vtpm
+ function to handle it. This function will examine the type of
+ network event and act accordingly. Each time the function is invoked
+ it should completely process the data received and free the PSAPdata
+ structure for use in processing the next network event.
+ If it is an expedited
+ data request, for instance, it is treated differently from a P-DATA.
+ If an NDQ is
+ received all the data should be read from the PSAPread structure and
+ mapped to the cbuf.
+ If the cbuf fills up in the process of doing this, the PE containing the
+ remaining updates should be put in a queue of pending PEs.
+*/
+\f
+
+/* This macro does the same thing as PXFREE except it does not free
+ the PEs in the px_info array. We will use this instead of PXFREE
+ because we need to free the data PEs one at a time as they are
+ processed.
+ Any unprocessed (pending) PEs are maintained in a queue
+ by the VTPM. If some of the PEs received from a PDATArequest are in
+ this queue a call to PXFREE would free the
+ data and leave dangling references in the queue.
+
+ Note that the vtuser may have at most one unprocessed or partially
+ processed PE. The VTPM can potentially have any number of unprocessed
+ PEs in its queue.
+*/
+
+#define PFIN(px) \
+{ \
+ register int PXI; \
+ \
+ if ((px) -> px_realinfo) \
+ pe_free ((px) -> px_realinfo), (px) -> px_realinfo = NULLPE; \
+ else { \
+ for (PXI = (px) -> px_ninfo - 1; PXI >= 0; PXI--) \
+ if ((px) -> px_info[PXI]) \
+ (px) -> px_info[PXI] = NULLPE; \
+ (px) -> px_ninfo = 0; \
+ } \
+}
+\f
+
+int
+data_pending()
+{
+ int result;
+ PE *peptr = NULLPEP;
+
+ if (queued())
+ return(TRUE);
+
+ /* something was already in the cbuf
+ */
+
+ if (pe_buf != NULLPE) {
+
+ /* there seems to be something to map
+ */
+
+ map(pe_buf);
+ if (queued())
+ return(TRUE);
+ }
+ result = get_event(sd, peptr);
+
+ /* if there was no network event
+ */
+ if (result == NOTOK)
+ return(FALSE);
+
+ /* get_event may have resulted in data being read and mapped to the
+ cbuf
+ */
+
+ if (queued())
+ return(TRUE);
+
+ /* if there is no data left and get_event resulted in the association
+ being released
+ */
+ if (!connected) {
+ (void)putch(EOF);
+ return(TRUE);
+ }
+
+ /* there's nothing to read right now, but we're still connected
+ */
+ return(FALSE);
+}
+\f
+
+int
+queued()
+{
+ return(cbuf.queued);
+}
+
+\f
+/*************************************************************************/
+/* PUTCH - put a character on the buffer to be read by the */
+/* application */
+/* */
+/* RETURNS - OK on success, NOTOK otherwise */
+/*************************************************************************/
+int
+putch(c)
+ char c;
+{
+ if (debug > 1) {
+ advise(LLOG_DEBUG, NULLCP, "in putch, queued is %d, c is %c", cbuf.queued, c);
+ advise(LLOG_DEBUG, NULLCP, "cbuf.buf is %d, cbuf.head is %d, cbuf.tail is %d", (int)cbuf.buf, (int)cbuf.head, (int)cbuf.tail);
+ advise(LLOG_DEBUG, NULLCP, "cbuf.max_len is %d", (int)cbuf.max_len);
+ }
+ if (cbuf.queued >= CBUFSIZE) {
+ if (debug > 1)
+ advise(LLOG_DEBUG, NULLCP, "***********************\nputch: queued exceeds CBUFSIZE ***************");
+ return(NOTOK);
+ }
+ if (cbuf.queued <= 0) {
+ cbuf.tail = cbuf.head = cbuf.buf;
+ cbuf.queued = 0;
+ if (debug)
+ advise(LLOG_DEBUG, NULLCP, "tail and head set to %d", (int)cbuf.buf);
+ }
+ *(cbuf.tail) = c;
+ if (++(cbuf.tail) > cbuf.buf + CBUFSIZE)
+ cbuf.tail = cbuf.buf;
+ cbuf.queued++;
+ return(OK);
+}
+
+\f
+/*************************************************************************/
+/* VTSEND - send the updates that have been put into the PE */
+/* called "p_ondq". */
+/*************************************************************************/
+
+vtsend()
+{
+ if(p_ondq == NULLPE) return;
+ vtdata(p_ondq);
+ pe_free(p_ondq);
+ p_ondq = NULLPE;
+ p_ovtsdi = NULLPE;
+ sdi_count = 0;
+ p_oobjupdt = NULLPE;
+ obj_count = 0;
+ updt_count = 0;
+}
+\f
+/************************************************************************/
+/* VTDATA - generate a VDATREQ event to send an NDQ */
+/* */
+/* PARAMETERS */
+/* */
+/* NDQ - a presentation element containing an NDQ. */
+/************************************************************************/
+
+vtdata(ndq)
+ PE ndq;
+{
+ if (ndq == NULLPE)
+ return;
+
+ (void)do_event(VDATreq_n,ndq);
+}
+
+\f
+/************************************************************************/
+/* MKDELIVER - create a DLQ. Requests for an acknowlegement are not */
+/* allowed at this time. */
+/************************************************************************/
+
+PE
+mkdeliver(ack)
+ int ack;
+{
+ PE p_dlq;
+
+ if (ack != FALSE)
+ adios(NULLCP, "DLQ PDUs can only be sent without an ACK request");
+ if ((p_dlq = bool2prim(ack)) == NULLPE)
+ adios (NULLCP, "DLQ build failure (out of memory)");
+ p_dlq->pe_id = DLQ_PDU;
+ p_dlq->pe_class = PE_CLASS_CONT;
+ p_dlq->pe_context = 1;
+ return(p_dlq);
+}
+\f
+/**************************************************************************/
+/* VDELREQ - create a deliver request PE and generate a VDELreq */
+/* event to send it. */
+/**************************************************************************/
+
+vdelreq(ack)
+ int ack;
+{
+ PE p_dlq;
+
+ if (ack)
+ adios(NULLCP,
+ "ACK requests in deliver PDUs not supported at this time");
+ p_dlq = mkdeliver(FALSE);
+
+ (void)do_event(VDELreq,p_dlq);
+}
+
+\f
+/**************************************************************************/
+/* VDELIND - we queue up data to go to the terminal when the NDQ */
+/* is received, so there's really nothing */
+/* to do when we get a VDELIND */
+/* */
+/* PARAMETERS: */
+/* ACK - TRUE or FALSE according to whether */
+/* acknowledgement is requested or not. */
+/**************************************************************************/
+
+vdelind(del_pe,ack)
+ PE del_pe;
+ int ack;
+{
+ if (ack) {
+ if (debug)
+ advise(LLOG_DEBUG, NULLCP, "vdelind with ack requested not implemented!");
+ }
+ pe_free(del_pe);
+}
+\f
+/************************************************************************/
+/* VDATIND - On receiving a data indication we will go ahead and */
+/* map the contents onto the character buffer to go to the terminal */
+/* */
+/* PARAMETERS - "type" can be SEQUENCED or NONSEQUENCED */
+/* only SEQUENCED is implemented now */
+/************************************************************************/
+
+vdatind(type, pe)
+ int type;
+ PE pe;
+{
+ if (type != SEQUENCED)
+ adios(NULLCP, "unimplemented NDQ type %d", type);
+ map(pe);
+}
+
+vhdatind(pe)
+PE pe;
+{
+
+ advise(LLOG_NOTICE,NULLCP,"vhdatind(): HDQ's not supported\n");
+ pe_free(pe);
+}
+
+vudatind(pe)
+PE pe;
+{
+
+ TEXT_UPDATE ud;
+
+ if(unbuild_UDQPDU_UDQpdu(pe,1,NULLIP,NULLVP,(PEPYPARM) &ud) == NOTOK)
+ {
+ advise(LLOG_NOTICE,NULLCP,"UDQ parse failure\n");
+ }
+ else
+ {
+ control_ud((CO_UPDATE *) &(ud.updates.co_list) );
+ free( (char *)ud.updates.co_list.co_name);
+ pe_free(pe);
+ }
+}
+\f
+/*****************************************************************************/
+/* Connect_request: */
+/* */
+/* Sends an ASQ, waits for a confirm. */
+/* */
+/* Returns the file descriptor that corresponds to the network socket */
+/* for the association, or NOTOK if the association failed. */
+/* */
+/* The assumption is made that the acs_sd data element of the AcSAPstart*/
+/* structure is same as the file descriptor for the network socket used */
+/* by the association. */
+/*****************************************************************************/
+
+con_req()
+{
+ int uevent;
+
+ if (debug)
+ advise(LLOG_DEBUG, NULLCP, "in con_req");
+
+ vass_req(1,WACI_WACA,&vtp_profile);
+ if (acc->acc_result != ACS_ACCEPT) {
+ advise(LLOG_NOTICE,NULLCP, "association rejected: [%s]",
+ AcErrString (acc -> acc_result));
+ state = S1_01;
+ return NOTOK;
+ }
+
+ if (debug) {
+ advise(LLOG_DEBUG, NULLCP, "got associate confirm event, sd is %d", acc->acc_sd);
+ advise(LLOG_DEBUG, NULLCP, "acc_ninfo is %d", acc->acc_ninfo);
+ advise(LLOG_DEBUG, NULLCP, "pe_id is %d", acc->acc_info[0]->pe_id);
+ advise(LLOG_DEBUG, NULLCP, "pe_class is %d", acc->acc_info[0]->pe_class);
+ advise(LLOG_DEBUG, NULLCP, "pe_form is %d", acc->acc_info[0]->pe_form);
+ }
+
+ if (acc->acc_ninfo < 1)
+ adios(NULLCP, "no ASQ PDU sent with the associate confirm");
+
+ sd = acc->acc_sd;
+ uevent = do_event(ASR,acc->acc_info[0]);
+
+ if (debug)
+ advise(LLOG_DEBUG, NULLCP, "got user event %d", uevent);
+
+ if(uevent == SUCCESS) return(sd);
+ else return(-1);
+}
+
+\f
+
+read_asq(pe) /*Unwrap ASQ PDU. Use information it contains to fill in
+ some global values (profile_id,G_Func_Units,vcwa).
+ Return 0 if ASQ is improperly formatted or missing a
+ required field. For now, only the more obvious fields are
+ checked and only transparent and telnet profiles
+ are handled. Return PROFILE_NG if profile is not
+ supported. Return 1 if ASQ is valid.
+ */
+PE pe;
+{
+
+ int i,n, D;
+ ASQ_MSG ud;
+
+ bzero ((char *) &ud, sizeof ud);
+ if(unbuild_ASQPDU_ASQpdu(pe,1,NULLIP,NULLVP,(PEPYPARM)&ud) == NOTOK)
+ {
+ advise(LLOG_NOTICE,NULLCP, "ASQ parse failure (%s)", PY_pepy);
+ return(0);
+ }
+
+
+ if(!ud.class)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASQ without Class");
+ return(0);
+ }
+ if(ud.valid_coll)
+ {
+ if(ud.coll_winner == INITIATOR) vcwa = FALSE;
+ else vcwa = TRUE;
+ }
+ G_Func_Units = ud.func_units.bitstring & 0x1f;
+ if( (!ud.valid_prof) || (!ud.asq_profile.oid_true) ||
+ !oid_cmp(ud.asq_profile.prof_oid,ode2oid("default")) )
+ {
+ vtp_profile.profile_name = "default";
+ my_displayobj = "DISPLAY-OBJECT-1";
+ telnet_profile = 0;
+ return(1);
+ }
+ if( !oid_cmp(ud.asq_profile.prof_oid,ode2oid("telnet")) )
+ {
+ vtp_profile.profile_name = "telnet";
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 0xff;
+ vtp_profile.arg_val.tel_arg_list.x_window = -1;
+
+ D = -1;
+ for(n=0; n<ud.asq_profile.num_cds_objects; n++)
+ {
+ if( *ud.asq_profile.cds_offer_list[n].obj_name == 'D')
+ {
+ D = n;
+ break;
+ }
+ }
+ if(D < 0)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASQ with no D Display Object");
+ return(0);
+ }
+
+ if( !ud.asq_profile.cds_offer_list[D].valid_rep_list )
+ {
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+ default_rep_flag = 1;
+ }
+ else /*Repertoire specified*/
+ {
+ if(ud.asq_profile.cds_offer_list[D].rep_offer.num_reps
+ > MAXREPS)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASQ with too many repertoires");
+ return(0);
+ }
+ for(i=0; i< ud.asq_profile.cds_offer_list[D].rep_offer.num_reps;
+ i++)
+ {
+ if(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_type != 2)
+ continue;
+ if(!strncmp(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_assign,
+ ascii_go_repertoire,sizeof(ascii_go_repertoire)))
+ {
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 0;
+ advise(LLOG_DEBUG, NULLCP, "Using ASCII GO Repertoire.");
+ break;
+ }
+ if(!strncmp(ud.asq_profile.cds_offer_list[D].rep_offer.repertoire[i].rep_assign,
+ full_ascii_repertoire,sizeof(full_ascii_repertoire)))
+ {
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+ break;
+ }
+ }
+ if(vtp_profile.arg_val.tel_arg_list.full_ascii < 0) return(0);
+ }
+ transparent = 0;
+
+ if(ud.asq_profile.cds_offer_list[D].valid_x_dim == 0)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASQ with no X-Window");
+ return(0);
+ }
+ if(ud.asq_profile.cds_offer_list[D].x_dim.window_type != 2)
+ /*If not integer type window field*/
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASQ with invalid X-Window");
+ return(0);
+ }
+ if(ud.asq_profile.cds_offer_list[D].x_dim.window.type
+ == 0) /*If single value*/
+ {
+ vtp_profile.arg_val.tel_arg_list.x_window =
+ ud.asq_profile.cds_offer_list[D].x_dim.window.value;
+ }
+ else if(ud.asq_profile.cds_offer_list[D].x_dim.window.type == 1)
+ /*If range*/
+ {
+ if((ud.asq_profile.cds_offer_list[D].x_dim.window.min_val
+ <= 80) &&
+ (ud.asq_profile.cds_offer_list[D].x_dim.window.max_val
+ >= 80))
+ {
+ vtp_profile.arg_val.tel_arg_list.x_window = 80;
+ }
+ else
+ {
+ vtp_profile.arg_val.tel_arg_list.x_window =
+ ud.asq_profile.cds_offer_list[D].x_dim.window.min_val;
+ }
+
+ }
+ if(vtp_profile.arg_val.tel_arg_list.x_window < 0)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASQ without x-window");
+ return(0);
+ }
+ if(vtp_profile.arg_val.tel_arg_list.full_ascii < 0)
+ {
+ advise(LLOG_DEBUG, NULLCP, "Using Default for ASCII repertoire (Full ASCII)");
+ vtp_profile.arg_val.tel_arg_list.full_ascii = 1;
+ }
+ }
+ else
+ {
+ advise(LLOG_DEBUG, NULLCP, "Unknown Profile Requested");
+ return(PROFILE_NG);
+ }
+
+ return(1);
+}
+\f
+vasscnf(pe) /*Handle ASR received from Acceptor*/
+PE pe;
+{
+
+ ASR_MSG udr;
+ int rep, n;
+ int window_flag = 0;
+ int rep_flag = 0;
+
+ bzero ((char *) &udr, sizeof udr);
+ if(unbuild_ASRPDU_ASRpdu(pe,1,NULLIP,NULLVP,(PEPYPARM)&udr) == NOTOK)
+ {
+ advise (LLOG_NOTICE,NULLCP, "ASR parse failure (%s)", PY_pepy);
+ return(NOTOK);
+ }
+ if(udr.result != SUCCESS)
+ {
+ advise(LLOG_NOTICE,NULLCP, "Association rejected by Peer VT");
+ return(NOTOK);
+ }
+ if(udr.valid_coll) vcwa = udr.coll_winner;
+ else
+ advise(LLOG_DEBUG, NULLCP, "Received ASR with no collision winner");
+ if(!strcmp(vtp_profile.profile_name,"transparent"))
+ {
+ if(!udr.arg_list.cds_val[0].valid_rep_list) /*No repertoires*/
+ {
+ if(strcmp(vtp_profile.arg_val.tr_arg_list.cur_rep,
+ TRANSPARENT))
+ /*If don't want default for this profile*/
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR with no repertoire");
+ return(NOTOK);
+ }
+ }
+ if(strcmp(vtp_profile.arg_val.tr_arg_list.cur_rep,
+ udr.arg_list.cds_val[0].rep_value.repertoire[0].rep_assign))
+ /*Only support 1 repertoire in transparent*/
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR--Invalid repertoire for transparent profile");
+ return(NOTOK);
+ }
+ }
+ else if(!strcmp(vtp_profile.profile_name,"telnet"))
+ {
+ if(udr.arg_list.num_sp_param < 1)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR without enough Special Arguments");
+ return(0);
+ }
+ for(n=0; n<udr.arg_list.num_sp_param; n++)
+ {
+ if(udr.arg_list.sp_val[n].param_num == 1)
+ {
+ if(udr.arg_list.sp_val[n].param_type == 1)
+ /*If integer type*/
+ {
+ if(vtp_profile.arg_val.tel_arg_list.x_window !=
+ udr.arg_list.sp_val[n].args.int_arg)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR with invalid X-Window");
+ return(NOTOK);
+ }
+ else ++window_flag;
+ }
+ }
+ else if(udr.arg_list.sp_val[n].param_num == 2)
+ /*ASCII Repertoire type*/
+ {
+ if(udr.arg_list.sp_val[n].param_type == 0)
+ /*If Boolean*/
+ {
+ if(vtp_profile.arg_val.tel_arg_list.full_ascii)
+ rep = 1;
+ else rep = 0;
+ if(udr.arg_list.sp_val[n].args.bool_arg != rep)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR with invalid Repertoire");
+ return(NOTOK);
+ }
+ ++rep_flag;
+ }
+ }
+ } /*End for loop*/
+ if(!window_flag)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR without x-window");
+ return(NOTOK);
+ }
+ if(!rep_flag)
+ {
+ advise(LLOG_DEBUG, NULLCP, "ASR with no repertoire");
+ return(NOTOK);
+ }
+ }
+ return(OK);
+}
+\f
+
+asq(data)
+PE data;
+{
+ int srequirements;
+ struct PSAPctxlist vclist;
+ OID vt_asn;
+ struct QOStype qos;
+
+ qos.qos_reliability = HIGH_QUALITY;
+ qos.qos_sversion = 2;
+
+ if (debug)
+ advise(LLOG_DEBUG, NULLCP, "in asq");
+
+ acc = &accs;
+ acr = &acrs;
+ aci = &acis;
+
+/* I'm relying on "peerhost" being an external char * that
+ has the name of the host we want to connect to
+*/
+ if ((aei = _str2aei (peerhost, myservice, "iso vt", 1, NULLCP, NULLCP))
+ == NULLAEI)
+ adios (NULLCP, "unable to resolve service: %s", PY_pepy);
+ if ((pa = aei2addr (aei)) == NULLPA)
+ adios (NULLCP, "address translation failed");
+
+ if ((ctx = ode2oid (mycontext)) == NULLOID)
+ adios (NULLCP, "%s: unknown object descriptor", mycontext);
+ if ((ctx = oid_cpy (ctx)) == NULLOID)
+ adios (NULLCP, "out of memory");
+ if ((pci = ode2oid (mypci)) == NULLOID)
+ adios (NULLCP, "%s: unknown object descriptor", mypci);
+ if ((pci = oid_cpy (pci)) == NULLOID)
+ adios (NULLCP, "out of memory");
+
+ if ((sf = addr2ref (PLocalHostName ())) == NULL) {
+ sf = &sfs;
+ (void) bzero ((char *) sf, sizeof *sf);
+ }
+
+ PLOG (vt_log, print_VT_PDUs, data, NULLCP, 0);
+ aca = &aci->aci_abort;
+ srequirements = SR_DUPLEX | SR_RESYNC | SR_TYPEDATA;
+ srequirements &= ~SR_RLS_EXISTS;
+
+ if((vt_asn = oid_cpy (pci)) == NULLOID)
+ adios (NULLCP, "out of memory");
+ vclist.pc_nctx = 1;
+ vclist.pc_ctx[0].pc_id = 1;
+ vclist.pc_ctx[0].pc_asn = vt_asn;
+ vclist.pc_ctx[0].pc_atn = NULLOID;
+ data -> pe_context = 1;
+
+ if (AcAssocRequest (ctx, NULLAEI, aei, NULLPA, pa,
+ &vclist, pci,
+ 0, srequirements, SERIAL_MIN, 0, sf, &data, 1, &qos,
+ acc, aci) == NOTOK)
+ acs_adios (aca, "A-ASSOCIATE.REQUEST");
+
+ if (acc -> acc_result != ACS_ACCEPT)
+ return;
+
+ sd = acc->acc_sd;
+ ts_bound = acc -> acc_connect.pc_responding; /* struct copy */
+#ifdef DEBUG
+ {
+ register int i;
+ register struct PSAPconnect *pc = &acc -> acc_connect;
+ register struct PSAPctxlist *pl = &pc -> pc_ctxlist;
+
+ advise (LLOG_DEBUG, NULLCP, "context: %s",
+ oid2ode (acc -> acc_context));
+
+ advise (LLOG_DEBUG, NULLCP,
+ "responding AE title: %s, responding PSAP address: %s",
+ sprintaei (&acc -> acc_respondtitle),
+ paddr2str (&pc -> pc_responding, NULLNA));
+
+ for (i = 0; i < pl -> pc_nctx; i++)
+ advise (LLOG_DEBUG, NULLCP, "ctx %d: 0x%x 0x%x %d",
+ pl -> pc_ctx[i].pc_id, pl -> pc_ctx[i].pc_asn,
+ pl -> pc_ctx[i].pc_atn, pl -> pc_ctx[i].pc_result);
+ advise (LLOG_DEBUG, NULLCP, "default %d", pc -> pc_defctxresult);
+ advise (LLOG_DEBUG, NULLCP, "p/s requirements 0x%x/0x%x",
+ pc -> pc_prequirements, pc -> pc_srequirements);
+ }
+#endif
+}
+
+vt_disconnect()
+{
+ if (AcRelRequest (sd, ACF_NORMAL, NULLPEP, 0, NOTOK, acr, aci)
+ == NOTOK)
+ acs_adios (aca, "A-RELEASE.REQUEST");
+ if(acr->acr_affirmative) {
+ connected = FALSE;
+ (void) do_event (RLR, acr -> acr_info[0]);
+ }
+
+ ACRFREE (acr);
+
+}
+
+\f
+
+#define ASYNC 0
+
+#define RMASK \
+ "\020\01HALFDUPLEX\02DUPLEX\03EXPEDITED\04MINORSYNC\05MAJORSYNC\06RESYNC\
+\07ACTIVITY\010NEGOTIATED\011CAPABILITY\012EXCEPTIONS\013TYPEDATA"
+
+#define PMASK \
+ "\020\01MANAGEMENT\02RESTORATION"
+
+/* \f DATA */
+
+long time ();
+char *ctime ();
+int result;
+
+/*PE pe;*/
+\f
+/*************************************************************************/
+/* ASS_IND */
+/*************************************************************************/
+
+ass_ind (argc, argv)
+ int argc;
+ char **argv;
+{
+ register struct PSAPctxlist *pl;
+
+
+ aca = &aci->aci_abort;
+ ps = &acs->acs_start;
+ pl = &ps -> ps_ctxlist;
+
+ if (AcInit (argc, argv, acs, aci) == NOTOK)
+ acs_adios (aca, "initialization fails");
+
+ advise (LLOG_NOTICE,NULLCP,
+ "A-ASSOCIATE.INDICATION: <%d, %s, %s, %s, %d>",
+ acs -> acs_sd, oid2ode (acs -> acs_context),
+ sprintaei (&acs -> acs_callingtitle),
+ sprintaei (&acs -> acs_calledtitle), acs -> acs_ninfo);
+
+ advise (LLOG_NOTICE,NULLCP,
+ "PSAP: <%d, %s, %s, %d, %s,",
+ ps -> ps_sd,
+ paddr2str (&ps -> ps_calling, NULLNA),
+ paddr2str (&ps -> ps_called, NULLNA),
+ pl -> pc_nctx, sprintb (ps -> ps_prequirements, PMASK));
+ advise (LLOG_NOTICE,NULLCP,
+ " %s, %d, %d>",
+ sprintb (ps -> ps_srequirements, RMASK), ps -> ps_isn,
+ ps -> ps_ssdusize);
+
+ (void) strcpy (peerhost,
+ na2str (ps -> ps_calling.pa_addr.sa_addr.ta_addrs));
+
+ sd = acs->acs_sd;
+
+/* ACSFREE(acs);
+*/
+
+ PLOG (vt_log, print_VT_PDUs, acs -> acs_info[0], NULLCP, 1);
+
+ return( do_event(ASQ,acs->acs_info[0]) );
+}
+
+\f
+
+/* ARGSUSED */
+
+vassind(pe)
+ PE pe;
+{
+ return(vass_resp(SUCCESS));
+}
+
+\f
+vbrkreq()
+{
+ PE brk_pe;
+ BRcnt brk;
+
+ bzero ((char *) &brk, sizeof brk);
+ brk.BKQcont.token_val = NOBKTOK;
+ brk.BKQcont.ExplPtr.xval = 0;
+ brk.BKQcont.ExplPtr.yval = 0;
+ brk.BKQcont.ExplPtr.zval = NULLCOORD;
+ if ((build_VT_BKQ__pdu(&brk_pe,1,NULL,NULLCP,(PEPYPARM)&brk)) == NOTOK)
+ adios (NULLCP, "BKQ build failed (%s)", PY_pepy);
+ brk_pe->pe_context = 1;
+ flushbufs(); /* flush local buffers */
+ (void)do_event(VBRKreq,brk_pe);
+}
+\f
+vbrkrsp()
+{
+ PE brk_pe;
+ BRcnt brk;
+
+ bzero ((char *) &brk, sizeof brk);
+ brk.BKRcont.token_val = NOBKTOK;
+ brk.BKRcont.ExplPtr.xval = 0;
+ brk.BKRcont.ExplPtr.yval = 0;
+ brk.BKRcont.ExplPtr.zval = NULLCOORD;
+ if ((build_VT_BKR__pdu(&brk_pe,1,NULL,NULLCP,(int *)&brk)) == NOTOK)
+ adios (NULLCP, "BKR build failed (%s)", PY_pepy);
+ brk_pe->pe_context = 1;
+ (void)do_event(VBRKrsp,brk_pe);
+}
+
+\f
+/* ARGSUSED */
+vbrkind(brk_pe)
+PE brk_pe;
+{
+ flushbufs();
+ vtok = 1; /* got tokens from peer */
+ advise(LLOG_DEBUG, NULLCP, "Received VT-BREAK");
+ vt_clr_obj(); /*Initialize Control Objects*/
+ vbrkrsp();
+ if(telnet_profile)
+ {
+#ifndef PTYBUG
+#ifdef BSD44
+ ptyecho(0);
+#else
+ setmode(0,ECHO); /*Return to Local Echo. This call is not
+ the same for user (vtp) and server (vtpd) so for
+ now, VT-BREAK can only be requested at user side.*/
+#endif
+ vt_rem_echo(&na_image);
+#endif
+ vt_sup_ga(&na_image);
+ kill_proc();
+ }
+ /*Re-Negotiate Remote Echo and Suppress Go Ahead*/
+}
+\f
+/*ARGSUSED */
+vbrkcnf(brk_pe)
+PE brk_pe;
+{
+ (void)printf("\r\n[break]\r\n");
+ if(telnet_profile)
+ {
+#ifndef PTYBUG
+ vt_rem_echo(&ni_image);
+#endif
+ vt_sup_ga(&ni_image);
+ }
+}
+