John Forkosh Associates ®
E D S   S o u r c e   L i s t i n g s
Copyright © 1986-2010, John Forkosh Associates, Inc.
All rights reserved.

Click for:   homepage,   resume



  CCCCCCC    OOOOOO   NN      NN TTTTTTTTTT EEEEEEEEEE NN      NN TTTTTTTTTT   SSSSSSS 
 CCCCCCCCC  OOOOOOOO  NNN     NN TTTTTTTTTT EEEEEEEEEE NNN     NN TTTTTTTTTT  SSSSSSSSS
CC      CC OO      OO NNNN    NN TT  TT  TT  EE     EE NNNN    NN TT  TT  TT SS        
CC         OO      OO NN NN   NN     TT      EEEEEE    NN NN   NN     TT      SSSSSSS  
CC         OO      OO NN   NN NN     TT      EEEEEE    NN   NN NN     TT       SSSSSSS 
CC      CC OO      OO NN    NNNN     TT      EE     EE NN    NNNN     TT             SS
 CCCCCCCCC  OOOOOOOO  NN     NNN    TTTT    EEEEEEEEEE NN     NNN    TTTT    SSSSSSSSS 
  CCCCCCC    OOOOOO   NN      NN    TTTT    EEEEEEEEEE NN      NN    TTTT     SSSSSSS  

   1: eds_ackmsg.c
   2: eds_chgkbd.c
   3: eds_cli.c
   4: eds_clishell.c
   5: eds_clishell.h
   6: eds_crtdriver.c
   7: eds_devtblinit.c
   8: eds_kbdinit.c
   9: eds_kbdnes.c
  10: eds_kdbnum.c
  11: eds_kbdxlate.c
  12: eds_rdcrtmbx.c
  13: eds_stokbd.c
  14: eds_stotcp.c
  15: eds_tcpdef.h
  16: eds_tcpmain.c
  17: keyboard.txt
  18: ttydef.txt


EEEEEEEEEE DDDDDDDD     SSSSSSS                  AA      CCCCCCC  KKKK    KK MM      MM
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS                AAAA    CCCCCCCCC KKKK   KK  MMM    MMM
 EE     EE  DD     DD SS                       AA  AA  CC      CC  KK   KK   MMMM  MMMM
 EEEEEE     DD     DD  SSSSSSS                AA    AA CC          KKKKKK    MM MMMM MM
 EEEEEE     DD     DD   SSSSSSS              AAAAAAAAA CC          KKKKK     MM  MM  MM
 EE     EE  DD     DD         SS            AAAAAAAAAA CC      CC  KK  KKK   MM      MM
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ AA      AA  CCCCCCCCC KKKK   KK  MM      MM
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________ AA      AA   CCCCCCC  KKKK    KK MM      MM

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    ackmsg
  7:  *
  8:  * Purpose:     Acknowledges a TCP terminal message.
  9:  *
 10:  * Call:        ackmsg ( process_id, msglevel, opcode, crtmsg )
 11:  *
 12:  * Arguments:
 13:  *              process_id (I)  addr of char string containing process_id.
 14:  *
 15:  *              msglevel (I)    int containing message level,
 16:  *                              which determines amount of printing.
 17:  *
 18:  *              opcode (I)      addr of 1-character string containing
 19:  *                              "a", "n", or "f" for ack,nak,flush
 20:  *
 21:  *              crtmsg (I)      addr of crtmsghdr struct conatining
 22:  *                              message from TCP to CRT which is to be acked.
 23:  *
 24:  * Returns:     - int
 25:  *              SS$_NORMAL      for successful completion,
 26:  *              SS$_status      or error status otherwise.
 27:  *
 28:  * Source:      EDS_ACKMSG.C
 29:  *
 30:  * --------------------------------------------------------------------------
 31:  * Revision History:
 32:  *
 33:  * 04/24/86     J.Forkosh       Installation.
 34:  *
 35:  ****************************************************************************/
 36: 
 37: #include stdio
 38: #include ssdef
 39: #include "eds$shl:eds_symdef.h"
 40: #include "eds$shl:eds_mbxdef.h"
 41: #include "eds$shl:eds_opsdef.h"
 42: 
 43: int     ackmsg ( process_id, msglevel, opcode, crtmsg )
 44: char    *process_id;
 45: int     msglevel;
 46: char    *opcode;
 47: struct  crtmsghdr_struct *crtmsg;
 48: {
 49: /* -------------------------------------------------------------------------
 50: Allocations and Declarations
 51: -------------------------------------------------------------------------- */
 52: static  struct tcpmsghdr_struct ackmsg; /* acknowledgement loopback to tcp */
 53: char    partner_id[4];                  /* process_id of TCP partner */
 54: int     vms_stat;                       /* return stat from wrtmbxmsg */
 55: 
 56: /* -------------------------------------------------------------------------
 57: Format the ackmsg reply
 58: -------------------------------------------------------------------------- */
 59: ackmsg.reqseqnum = crtmsg->msgseqnum;   /* msgnum being acked */
 60: ackmsg.dev_num = crtmsg->dev_num;       /* device number */
 61: switch ( *opcode )                      /* choose an opcode for the ack */
 62:         {
 63:         case 'a': ackmsg.opcode = EDS$_ACKMSG;  break;
 64:         case 'n': ackmsg.opcode = EDS$_NAKMSG;  break;
 65:         case 'f': ackmsg.opcode = EDS$_WAKMSG;  break;
 66:         default:  return ( SS$_BADPARAM );
 67:         }
 68: 
 69: /* -------------------------------------------------------------------------
 70: Mail acknowledgement
 71: -------------------------------------------------------------------------- */
 72: *partner_id = crtmsg->process_id;       /* id of partner TCP process */
 73: partner_id[1] = '\000';                 /* null-terminated */
 74: vms_stat = wrtmbxmsg( process_id,msglevel,partner_id,tcpmsghdr_size,&ackmsg );
 75: return ( vms_stat );
 76: }


EEEEEEEEEE DDDDDDDD     SSSSSSS               CCCCCCC  HHHH  HHHH   GGGGGG   KKKK    KK
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             CCCCCCCCC HHHH  HHHH  GGGGGGGG  KKKK   KK 
 EE     EE  DD     DD SS                    CC      CC  HH    HH  GG          KK   KK  
 EEEEEE     DD     DD  SSSSSSS              CC          HHHHHHHH  GG    GGG   KKKKKK   
 EEEEEE     DD     DD   SSSSSSS             CC          HHHHHHHH  GG   GGGGG  KKKKK    
 EE     EE  DD     DD         SS            CC      CC  HH    HH  GG      GG  KK  KKK  
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________  CCCCCCCCC HHHH  HHHH  GGGGGGGG  KKKK   KK 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________   CCCCCCC  HHHH  HHHH   GGGGGG   KKKK    KK

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    chgkbd
  7:  *
  8:  * Purpose:     Changes the keyboard in the device table of a terminal.
  9:  *
 10:  * Call:        chgkbd ( process_id, msglevel, dev_ptr, ikbd )
 11:  *
 12:  * Arguments:
 13:  *              process_id (I)  addr of char string containing process id
 14:  *
 15:  *              msglevel (I)    int containing printf message level
 16:  *
 17:  *              dev_ptr (I)     addr of devtable_struct for the terminal
 18:  *                              device whose keyboard is to be changed.
 19:  *
 20:  *              ikbd (I)        int containing the keyboard# >=0.
 21:  *                              If ikbd<0 then dummy keyboard with < CR > term.
 22:  *
 23:  * Returns:     - int           SS$_NORMAL for successful completion.
 24:  *
 25:  * Source:      EDS_CHGKBD.C
 26:  *
 27:  * --------------------------------------------------------------------------
 28:  * Revision History:
 29:  * 10/08/86     J.Forkosh       Installation.
 30:  *
 31:  ****************************************************************************/
 32: 
 33: #include stdio
 34: #include ssdef
 35: #include "eds$shl:eds_symdef.h"
 36: #include "eds$shl:eds_mbxdef.h"
 37: #include "eds$tcp:eds_tcpdef.h"
 38: #include "eds$shl:eds_dcpdef.h"
 39: #include "eds$lib:eds_devdef.h"
 40: #include "eds$shl:eds_glbdef.h"
 41: #define getbit(x,bit) ( (x >>bit) & 1 )
 42: #define setbit(x,bit) ( x |= (1<< bit) )
 43: #define clrbit(x,bit) ( x &= ~(1<< bit) )
 44: #define getlongbit(x,bit) getbit(*(x+bit/8),bit%8)
 45: #define setlongbit(x,bit) setbit(*(x+bit/8),bit%8)
 46: #define clrlongbit(x,bit) clrbit(*(x+bit/8),bit%8)
 47: 
 48: int     chgkbd ( process_id, msglevel, dev_ptr, ikbd )
 49: char    *process_id;
 50: int     msglevel;
 51: struct  devtable_struct *dev_ptr;
 52: int     ikbd;
 53: {
 54: 
 55: /* -------------------------------------------------------------------------
 56: Allocations and Declarations
 57: -------------------------------------------------------------------------- */
 58: struct  dcptable_struct *dcp_ptr;       /* and to imbedded dcptable */
 59: struct  glbhdr_struct *kbdhdr;          /* keyboard sect global header */
 60: struct  kbdtbl_struct *kbdtbl;          /* 1st keyboard table */
 61: char    *kbd_sect;                      /* local crt addr in devtable */
 62: int     ichar,tval;                     /* char#, termtblval */
 63: static  char dummy_termtbl[] = "\r\000"; /* terminators for dummy keyboard */
 64: 
 65: /* -------------------------------------------------------------------------
 66: Init device table and keyboard table pointers
 67: -------------------------------------------------------------------------- */
 68: dcp_ptr = &(dev_ptr->dcptable);         /* struct ptr to embedded dcptable */
 69: kbd_sect = dev_ptr->kbd_sect;           /* extract global addr from devtable */
 70: kbdhdr= kbd_sect;                       /* keyboard sect starts with glb hdr */
 71: kbdtbl= kbd_sect+glbhdr_size;           /* followed by keyboard tables */
 72: 
 73: /* -------------------------------------------------------------------------
 74: If ikbd>=0 then this is a normal keyboard switch
 75: -------------------------------------------------------------------------- */
 76: if ( ikbd >= 0 )
 77:         {
 78:         /* --- got ikbd, so init corresponding fields in device table --- */
 79:         dev_ptr->keyboard = ikbd;               /* keyboard table# */
 80:         dcp_ptr->maxmsg = kbdtbl[ikbd].maxmsg;  /* set maxmsg for keyboard */
 81:         dev_ptr->msgsiz = 0;                    /* no partial msg in buffer */
 82:         for ( ichar=0; ichar<32; ichar++ )      /* copy termtbl to devtable */
 83:                 dcp_ptr->termtbl[ichar] = kbdtbl[ikbd].termtbl[ichar];
 84:         }
 85: 
 86: /* -------------------------------------------------------------------------
 87: If ikbd<0 then iabs(ikbd)=maxmsg and kbd_sect contains terminators
 88: -------------------------------------------------------------------------- */
 89: if ( ikbd < 0 )
 90:         {
 91:         dev_ptr->keyboard = ikbd;               /* dummy keyboard table# */
 92:         dcp_ptr->maxmsg = 32;                   /* default maxmsg */
 93:         dev_ptr->msgsiz = 0;                    /* no partial msg in buffer */
 94:         for ( ichar=0; ichar<32; ichar++ )      /* reset termtbl */
 95:                 dcp_ptr->termtbl[ichar] = '\000';
 96:         for ( ichar=0; (tval=(int)(dummy_termtbl[ichar]))>0; ichar++ )
 97:                 setlongbit(dcp_ptr->termtbl,tval);
 98:         }
 99: 
100: /* -------------------------------------------------------------------------
101: Finally, initialize various and sundry other device table fields
102: -------------------------------------------------------------------------- */
103: if ( FALSE )            /* --- we probably won't need to re-init these --- */
104:         {
105:         dev_ptr->operatormsg.opcode = '\000';   /* no opcode to start */
106:         dev_ptr->select_opcode = '\000';        /* no prev source selected */
107:         dev_ptr->prefix_opcode = 0;             /* no pending prefix opcode */
108:         strcpy(dev_ptr->operatormsg.nesid,"       \000"); /* blank nesid */
109:         dev_ptr->operatormsg.page = 0;          /* page#0 to start */
110:         for ( ichar=0; ichar<4; ichar++ )       /* and all 4 num's */
111:                 dev_ptr->operatormsg.num[ichar] = 0;
112:         dev_ptr->operatormsg.string[0]= '\000'; /* and a null string */
113:         }
114: 
115: /* --- print flow control information --- */
116: if ( msglevel > 25 )
117:         {
118:         printf("\nCRT_%s> (chgkbd) devnam=%s, kbd#%d, maxmsg=%d\n\ttermtbl=",
119:         process_id,dcp_ptr->devnam,ikbd,dcp_ptr->maxmsg);
120:         for(ichar=0;ichar<32;ichar++)
121:                 { tval=dcp_ptr->termtbl[ichar]; printf("%2.2X",tval); }
122:         }
123: return ( SS$_NORMAL );
124: }


EEEEEEEEEE DDDDDDDD     SSSSSSS               CCCCCCC  LLLLL        IIIIII             
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             CCCCCCCCC LLLLL        IIIIII             
 EE     EE  DD     DD SS                    CC      CC  LL            II               
 EEEEEE     DD     DD  SSSSSSS              CC          LL            II       .       
 EEEEEE     DD     DD   SSSSSSS             CC          LL            II      ...      
 EE     EE  DD     DD         SS            CC      CC  LL     LL     II     .....     
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________  CCCCCCCCC LLLLLLLLLL   IIIIII    ...      
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________   CCCCCCC  LLLLLLLLLL   IIIIII     .       

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    eds_cli
  7:  *
  8:  * Purpose:     Command-line interpreter for EDS applications driver programs.
  9:  *              This "cli" is passed the command-line arguments (argc,argv),
 10:  *              and an array of strings containing arg numbers.  It then
 11:  *              creates mailboxes, event flag clusters, global sections,
 12:  *              and opens rms files for the application to read, etc.
 13:  *
 14:  * Call:        eds_cli ( argc, argv, arg_strings,
 15:  *                      msglevel, mbx_chans, sect_ptrs, file_ptrs ) 
 16:  *
 17:  * Arguments:
 18:  *              argc (I)        int containing the number of command-line args,
 19:  *                              as supplied to main() by VMS.
 20:  *
 21:  *              argv (I)        addr of array of char strings containing
 22:  *                              the command-line args, as supplied to main()
 23:  *                              by VMS.
 24:  *
 25:  *              maxmsg (I)      int containing max bytes per mailbox message.
 26:  *
 27:  *              bufquo (I)      int containing max bytes per mailbox buffer.
 28:  *
 29:  *              pagcnt (I)      int containing number of 512-byte pages
 30:  *                              per global section.
 31:  *
 32:  *              arg_strings (I) addr of array of char strings containing
 33:  *                              the args to be used for creating mailboxes,
 34:  *                              common event flag clusters, global sections,
 35:  *                              and for opening rms files (see Notes below).
 36:  *
 37:  *              msglevel (O)    addr of int returning either the value of
 38:  *                              the last command-line arg (which is always
 39:  *                              the message level if it's numeric and >0),
 40:  *                              or 0.
 41:  *
 42:  *              mbx_chans (O)   addr of int array returning mailbox chans -
 43:  *                              the first int, mbx_chan[0], returns a channel
 44:  *                              to this process's mailbox, and subsequent ints
 45:  *                              return chans to partner process's mailboxes
 46:  *                              as specified in arg_strings[0].
 47:  *
 48:  *              sect_ptrs (O)   addr of array of char ptrs returning pointers
 49:  *                              to global sections that were mapped to partner
 50:  *                              processes as specified by arg_strings[2].
 51:  *
 52:  *              file_ptrs (O)   addr of array of FILE ptrs returning pointers
 53:  *                              to rms files that were opened (read only)
 54:  *                              as specified by arg_strings[3].
 55:  *
 56:  * Source:      EDS_CLI.C
 57:  *
 58:  * --------------------------------------------------------------------------
 59:  * Revision History:
 60:  *
 61:  * 03/18/86     J.Forkosh       Installation.
 62:  *
 63:  ****************************************************************************/
 64: 
 65: #include stdio
 66: #include ssdef
 67: #include "eds$shl:eds_symdef.h"
 68: #include "eds$shl:eds_glbdef.h"
 69: #define PROGRAM_ID "CLI_"
 70: 
 71: int     eds_cli ( argc, argv, maxmsg, bufquo, pagcnt, arg_strings,
 72:                 msglevel, mbx_chans, sect_ptrs, file_ptrs ) 
 73: int     argc;
 74: char    *argv[];
 75: int     maxmsg;
 76: int     bufquo;
 77: int     pagcnt;
 78: char    *arg_strings[];
 79: int     *msglevel;
 80: int     *mbx_chans;
 81: int     *sect_ptrs;
 82: int     *file_ptrs;
 83: {
 84: 
 85: /* -------------------------------------------------------------------------
 86: Allocations and Declarations
 87: -------------------------------------------------------------------------- */
 88: /* --- process identification variables --- */
 89: char    process_id[16];                 /* this process - always argv[1] */
 90: char    partner_id[64];                 /* process_id of partner process */
 91: char    program_id[16];                 /* for printf identification */
 92: 
 93: /* --- each string contains the arg numbers for mailboxes, etc. --- */
 94: int     istring,ichar,iarg;             /* index into arg_strings */
 95: 
 96: /* --- the mailboxes, global sections, and rms files opened --- */
 97: int     nmbx,nglb,nrms;                 /* number of mbx's, glb's, rms files */
 98: FILE    *fopen();                       /* file pointer for application info */
 99: 
100: /* --- various and sundry variables --- */
101: char    arg[2];                         /* ascii digit in ichar-th position */
102: char    device_name[64];                /* EDS_STUB + DEVICE_STUB + PROCESS */
103: int     ixlate,gotxlate;                /* glbdef_xlate table index and flag */
104: int     glb_pagcnt,glb_recsz;           /* default or xlated pagcnt, recsz */
105: int     glb_bufquo,glb_maxmsg;          /* default or xlated bufquo, maxmsg */
106: struct  glbhdr_struct *glb_sect;        /* ptr to global sect hdr for init */
107: int     ihdr;                           /* index to header process string */
108: int     vms_stat;                       /* return stat from system services */
109: 
110: /* --- Special mnemonic args are translated by the eds_cli as follows --- */
111: struct  {       
112:         char    *mnemonic;      /* single char on command line or arg string */
113:         char    *stub;          /* mnemonic replaced by stub for creation */
114:         int     pagbuf;         /* section page count or mailbox bufquo */
115:         int     recmax;         /* section record size or mailbox maxmsg */
116:         }
117: glbdef_xlate[] =
118:         {
119:         {SEQ_MNEM, SEQ_STUB, SEQ_BUFQUO, SEQ_MAXMSG},   /* sequence# mailbox */
120:         {KBD_MNEM, KBD_STUB, KBD_PAGCNT, KBD_RECSZ},    /* keyboard section */
121:         {CRT_MNEM, CRT_STUB, CRT_PAGCNT, CRT_RECSZ},    /* screen section */
122:         {TCP_MNEM, TCP_STUB, TCP_PAGCNT, TCP_RECSZ},    /* state section */
123:         {  "\000",       "",          0,         0}     /* end-of-table */
124:         } ;
125: 
126: /* -------------------------------------------------------------------------
127: Get "hard-coded" command-line arguments (first and last).
128: -------------------------------------------------------------------------- */
129: /* --- First and last args are process_id and msglevel. --- */
130: strcpy ( process_id, argv[1] );         /* process_id is always 1st arg */
131: strcpy ( program_id, PROGRAM_ID );      /* start program_id with stub, ... */
132: strcat ( program_id, process_id );      /* ... and concat process_id to it */
133: if ( (*msglevel=atoi(argv[argc-1]))<1 ) /* optional msglevel is last arg ... */
134:         *msglevel = MSGLEVEL;           /* ... or else use default value */
135: 
136: /* --- Print initialization message. --- */
137: if ( *msglevel > 1 )                    /* print out image name and args */
138:         printf ("\n%s> image=%s,\n\tprocess_id=%s, msglevel=%d",
139:         program_id,argv[0],process_id,*msglevel);
140: 
141: /* -------------------------------------------------------------------------
142: Get application-dependent arguments, and issue system calls for mbx's, etc.
143: -------------------------------------------------------------------------- */
144: /* --- Start off with no mailboxes, no global sections, no rms files --- */
145: nmbx = 0;                               /* init mbx count (index to chans) */
146: nglb = 0;                               /* init global section count */
147: nrms = 0;                               /* init rms file count */
148: 
149: /* --- Set up nested loop to go over each char in each string --- */
150: for ( istring=0; istring<5; istring++ ) /* there are 5 command-line strings */
151: for ( ichar=0; ichar < strlen(arg_strings[istring]); ichar++ )
152:         {                               /* for each char in each string ... */
153: 
154: /* --- Convert ichar-th char in istring-th string to int arg number --- */
155:         arg[0] = *(arg_strings[istring]+ichar);  /* get a char from string, */
156:         arg[1] = '\0';                  /* and null-terminate it */
157: 
158:         if ( (iarg=atoi(arg)) > 0 )     /* convert ascii arg to int, ... */
159:                 strcpy (partner_id,argv[iarg]); /* use argv if conversion ok */
160:         else
161:                 strcpy (partner_id,arg);        /* else use string literal */
162:         if ( strlen(partner_id) < 1 )   /* got a null argument for partner */
163:                 continue;                       /* so go on to next one */
164: 
165: /* --- check for mnemonic translation --- */
166:         ixlate= 0;                      /* start at beginning of xlate table */
167:         gotxlate = FALSE;               /* haven't translated */
168:         while ( strlen(glbdef_xlate[ixlate].mnemonic) > 0 ) /* null at end */
169:                 {                       /* if partner_id matches mnemonic */
170:                 if ( !strcmp( glbdef_xlate[ixlate].mnemonic, partner_id ) )
171:                         {               /* replace partner_id with new stub */
172:                         strcpy ( partner_id, glbdef_xlate[ixlate].stub );
173:                         gotxlate=TRUE;  /* set flag indicating translation */
174:                         break;
175:                         }
176:                 ixlate++;               /* try the next mnemonic */
177:                 }
178: 
179: /* --- init device_name with system stub --- */
180:         strcpy (device_name,EDS_STUB);  /* init device name with stub */
181: 
182: /* -------------------------------------------------------------------------
183: Now either: 0,1)crembx, 2)ascefc, 3)crmpsc, or 4)fopen, depending on istring.
184: -------------------------------------------------------------------------- */
185:         switch ( istring )
186:         {
187: 
188: /* --- Just issue a groupmbx() and drop through to case 1 for crembx() --- */
189:         case 0:                         /* mailbox for this process */
190:                 if ( (vms_stat=groupmbx()) != SS$_NORMAL )
191:                         {               /* fatal err - couldn't groupmbx */
192:                         if ( *msglevel > 0 )
193:                                 printf("\n%s> groupmbx() = %s",
194:                                 program_id,vmsmsg(vms_stat));
195:                         exit(-1);       /* exit after printing err msg */
196:                         }
197: 
198:                 if ( *msglevel > 1 )    /* print completion message */
199:                         printf("\n%s> groupmbx() = %s",
200:                         program_id,vmsmsg(vms_stat));
201: 
202: /* --- Issue a crembx() for this process (case 0) and its partners --- */
203:         case 1:                         /* mailbox for process and partners */
204:                 strcat(device_name,MBX_STUB);   /* add MBX_STUB and */
205:                 strcat(device_name,partner_id); /* add process_id */
206:                 glb_bufquo = bufquo;            /* init default bufquo */
207:                 glb_maxmsg = maxmsg;            /* init default maxmsg */
208:                 if ( gotxlate )                 /* replace defaults if xlate */
209:                         {
210:                         glb_bufquo = glbdef_xlate[ixlate].pagbuf;
211:                         glb_maxmsg = glbdef_xlate[ixlate].recmax;
212:                         }
213: 
214:                 if ( (vms_stat = crembx         /* issue call to create box */
215:                         (device_name,           /* mailbox name */
216:                         glb_maxmsg,             /* max bytes per msg */
217:                         glb_bufquo,             /* total bytes in box */
218:                         mbx_chans+nmbx))        /* addr where chan returned */
219:                 != SS$_NORMAL )
220: 
221:                         {               /* fatal err - couldn't create box */
222:                         if ( *msglevel > 0 )    /* print err msg */
223:                                 printf("\n%s> crembx(%s) = %s",
224:                                 program_id,device_name,
225:                                 vmsmsg(vms_stat));
226:                         exit(-1);       /* exit for fatal crembx() err */
227:                         }
228: 
229:                 nmbx++;                 /* bump mailbox count */
230:                 if ( *msglevel > 1 )    /* print completion message */
231:                         printf("\n%s> crembx(%s) = %s",
232:                         program_id,device_name,vmsmsg(vms_stat));
233:                 break;                  /* done with this case */
234: 
235: /* --- associate common event flag cluster for cluster(s) 2 (and 3) --- */
236:         case 2:                 /* associate common efn cluster */
237:                 if ( ichar > 1 ) break;         /* only clusters 2 and 3 */
238:                 strcat(device_name,EFC_STUB);   /* add EFC_STUB and */
239:                 strcat(device_name,partner_id); /* add process_id */
240: 
241:                 if ( (vms_stat = ascefc         /* issue ascefc call */
242:                         (2+ichar,               /* cluster 2,3 (ichar=0,1) */
243:                         device_name))           /* name of cluster */
244:                 != SS$_NORMAL )
245: 
246:                         {               /* fatal err - couldn't ascefc */
247:                         if ( *msglevel > 0 )    /* print err msg */
248:                                 printf("\n%s> ascefc(%s) = %s",
249:                                 program_id,device_name,
250:                                 vmsmsg(vms_stat));
251:                         exit(-1);       /* exit for fatal ascefc() err */
252:                         }
253: 
254:                 if ( *msglevel > 1 )    /* print completion message */
255:                         printf("\n%s> ascefc(%s) = %s",
256:                         program_id,device_name,vmsmsg(vms_stat));
257:                 break;                  /* done with this case */
258: 
259: /* --- Create and map global section --- */
260:         case 3:                 /* create and map global section */
261:                 strcat(device_name,GLB_STUB);   /* add GLB_STUB and */
262:                 strcat(device_name,partner_id); /* add process_id */
263:                 glb_pagcnt = pagcnt;            /* init for default pagcnt */
264:                 if ( gotxlate )                 /* replace with xlate pagcnt */
265:                         {
266:                         glb_pagcnt = glbdef_xlate[ixlate].pagbuf;
267:                         glb_recsz = glbdef_xlate[ixlate].recmax;
268:                         }
269: 
270:                 vms_stat = crmpsc               /* issue crmpsc call */
271:                         (device_name,           /* name of global section */
272:                         glb_pagcnt,             /* number of 512-byte pages */
273:                         sect_ptrs+nglb);        /* pointer to this section */
274: 
275:                 if ((vms_stat!=SS$_NORMAL) && (vms_stat!=SS$_CREATED))
276:                         {               /* fatal err - couldn't crmpsc */
277:                         if ( *msglevel > 0 )    /* print err msg */
278:                                 printf("\n%s> crmpsc(%s) = %s",
279:                                 program_id,device_name,
280:                                 vmsmsg(vms_stat));
281:                         exit(-1);       /* exit for fatal crmpsc() err */
282:                         }
283: 
284:                 if ( gotxlate && (vms_stat==SS$_CREATED) )
285:                         {               /* init system-wide global sections */
286:                         glb_sect = *(sect_ptrs+nglb);   /* glb hdr ptr */
287:                         glb_sect->lockflag = TRUE;      /* lock the section */
288:                         strcpy(glb_sect->sectnam,partner_id);   /* sect id */
289:                         glb_sect->pagcnt = glb_pagcnt;  /* init pagcnt */
290:                         glb_sect->recsz = glb_recsz;    /* init recsz */
291:                         glb_sect->maxused = -1;         /* init maxused */
292:                                                 /* #recs that will fit... */
293:                         glb_sect->maxrecs = ((512*glb_pagcnt)-(glbhdr_size+1))
294:                                                 /(glb_recsz + 1);
295:                         glb_sect->offset1 = glbhdr_size+1 + glb_sect->maxrecs;
296:                         for(ihdr=0; ihdr <= glb_sect->maxrecs; ihdr++)
297:                                 glb_sect->process_id[ihdr]='\000';
298:                         glb_sect->lockflag = FALSE;     /* unlock section */
299:                         if ( *msglevel > 1 )
300:                                 printf("\n%s> Section %s init= %d max recs",
301:                                 program_id,partner_id,glb_sect->maxrecs);
302:                         }
303: 
304:                 nglb++;                         /* bump global section count */
305:                 if ( *msglevel > 1 )            /* print completion message */
306:                         printf("\n%s> crmpsc(%s) = %s",
307:                         program_id,device_name,vmsmsg(vms_stat));
308:                 break;                  /* done with this case */
309: 
310: /* --- fopen() an RMS file for the application --- */
311:         case 4:                 /* fopen() an RMS file */
312:                 strcpy (device_name,partner_id);        /* filename is arg */
313: 
314:                 if ( (file_ptrs[nrms] = fopen   /* issue fopen call */
315:                         (device_name,           /* name of file */
316:                         "r"))                   /* read only */
317:                 == NULL )
318: 
319:                         {               /* fatal err - couldn't fopen */
320:                         if ( *msglevel > 0 )    /* print err msg */
321:                                 printf("\n%s> fopen(%s) = NULL",
322:                                 program_id,device_name);
323:                         exit(-1);       /* exit for fatal fopen() err */
324:                         }
325: 
326:                 nrms++;                 /* bump rms file count */
327:                 if ( *msglevel > 1 )    /* print completion message */
328:                         printf("\n%s> fopen(%s) = SS$_NORMAL",
329:                         program_id,device_name);
330:                 break;                  /* done with this case */
331: 
332: /* --- No defaults (cases hard-coded) --- */
333:         default:
334:                 if ( *msglevel > 0 )    /* print err msg */
335:                         printf("\n%s> err, switch(istring=%d)",
336:                         program_id,istring);
337:                 break;
338:         }                               /* --- end of switch --- */
339:         }                       /* --- end of nested istring/ichar loop --- */
340: return ( SS$_NORMAL );  /* --- return to main() --- */
341: }


EEEEEEEEEE DDDDDDDD     SSSSSSS               CCCCCCC  LLLLL        IIIIII     SSSSSSS 
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             CCCCCCCCC LLLLL        IIIIII    SSSSSSSSS
 EE     EE  DD     DD SS                    CC      CC  LL            II     SS        
 EEEEEE     DD     DD  SSSSSSS              CC          LL            II      SSSSSSS  
 EEEEEE     DD     DD   SSSSSSS             CC          LL            II       SSSSSSS 
 EE     EE  DD     DD         SS            CC      CC  LL     LL     II             SS
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________  CCCCCCCCC LLLLLLLLLL   IIIIII   SSSSSSSSS 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________   CCCCCCC  LLLLLLLLLL   IIIIII    SSSSSSS  

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Program:     eds_clishell
  7:  *
  8:  * Purpose:     Generic command-line interpreter shell program for EDS.
  9:  *              This "front-end" shell reads all command-line arguments,
 10:  *              creates mailboxes, event flag clusters, global sections,
 11:  *              opens rms files for the application to read, etc.
 12:  *
 13:  * Call:        $ eds "process_id" "arg2" "...etc" ["msglevel"]
 14:  *              (where $eds :== $sys$sysdevice:[]image_file_name.exe
 15:  *              has been installed as a foreign command)
 16:  *
 17:  * Arguments:
 18:  *              process_id (I)  the single-character process_id that uniquely
 19:  *                              identifies the spawned process, e.g., for
 20:  *                              creating mailboxes, etc.
 21:  *
 22:  *              arg2 (I)        the second command-line arg, whose meaning
 23:  *                              is application-dependent.
 24:  *
 25:  *              ...etc (I)      all remaining (application-dependent) args.
 26:  *
 27:  *              msglevel (I)    optional - the last arg, if present,
 28:  *                              is always the message level (it must be 
 29:  *                              numeric and >0).
 30:  *
 31:  * Source:      EDS_CLISHELL.C
 32:  *
 33:  * --------------------------------------------------------------------------
 34:  * Revision History:
 35:  *
 36:  * 04/22/86     J.Forkosh       Installation.
 37:  *
 38:  ****************************************************************************/
 39: 
 40: /* -------------------------------------------------------------------------
 41: Generic include files
 42: -------------------------------------------------------------------------- */
 43: #include stdio
 44: #include ssdef
 45: /* --- symdef, mbxdef, glbdef are the minimum set of EDS include files --- */
 46: #include "eds$shl:eds_symdef.h"
 47: #include "eds$shl:eds_mbxdef.h"
 48: #include "eds$shl:eds_glbdef.h"
 49: 
 50: /* -------------------------------------------------------------------------
 51: Application-dependent defines (_ARG defines are used to interpret command line)
 52: -------------------------------------------------------------------------- */
 53: #define EVENT_CLUSTER "remove this stmt if event flags not used for wakeup"
 54: #define PROGRAM_ID "EDS_"
 55: #define MIN_ARGC 2
 56: #define MAX_ARGC 3
 57: #define PID_ARGS "1"
 58: #define MBX_ARGS ""
 59: #define EFC_ARGS "Z"
 60: #define GLB_ARGS ""
 61: #define RMS_ARGS ""
 62: #define PID_MAXMSG MBX_MAXMSG           /* max bytes per mailbox message */
 63: #define PID_BUFQUO MBX_BUFQUO           /* total bytes per mailbox buffer */
 64: #define PID_PAGCNT GLB_PAGCNT           /* number pages per global section */
 65: char *instructions[] =                  /* print these for wrong argc count */
 66:         {
 67:         "Usage: $ eds \"process_id\" \"arg2\" \"...etc\" [\"msglevel\"]",
 68:         ""
 69:         };
 70: 
 71: /* -------------------------------------------------------------------------
 72: Global variables for application
 73: -------------------------------------------------------------------------- */
 74: /* -------------------------- Event Flag Table --------------------------- */
 75: #ifdef EVENT_CLUSTER
 76: int     efn_table[] =
 77:                 {
 78:                 0,                      /* to be filled in with process_id */
 79:                 255                     /* illegal efn terminates table */
 80:                 } ;
 81: #endif
 82: /* ----------------------------------------------------------------------- */
 83: 
 84: main ( argc, argv )
 85: int     argc;
 86: char    *argv[];
 87: {
 88: /* -------------------------------------------------------------------------
 89: Allocations and Declarations for Application variables
 90: -------------------------------------------------------------------------- */
 91: 
 92: /* -------------------------------------------------------------------------
 93: Beginning of executable code ...
 94: -------------------------------------------------------------------------- */
 95: #include "eds$shl:eds_clishell.h"       /* first execute the generic shell */
 96: 
 97: /* -------------------------------------------------------------------------
 98: THIS IS THE END OF THE SHELL CODE (Application-level code follows)
 99: -------------------------------------------------------------------------- */
100: 
101: /* -------------------------------------------------------------------------
102: Wait for events requiring action
103: -------------------------------------------------------------------------- */
104: while ( TRUE )
105: {                       /* --- beginning of while(TRUE) loop --- */
106: 
107: got_mail = FALSE;                       /* set this TRUE when we get mail */
108: #ifdef EVENT_CLUSTER
109: /* --- first try reading any "leftover" unsolicited mail --- */
110: get_mail:
111: if ( (vms_stat = readmbx(pidchan, 0,0,0, mbx_maxmsg, mbx_buff, mbx_iosb))
112: != SS$_NORMAL )                         /* got a message upon return */
113:         {
114:         if ( msglevel > 0 )             /* print error if can't read box */
115:                 printf("\n%s> Can't readmbx, err=%s",
116:                 program_id,vmsmsg(vms_stat));
117:         continue;                       /* couldn't read so try again */
118:         }
119: 
120: if ( (msglen = (int)mbx_iosb[1]) > 0 )  /* if we have mail */
121:         got_mail = TRUE;                /* raise the mailbox flag */
122: 
123: /* --- wait for a flag if we don't have unsolicited mail --- */
124: else
125:         {
126:         if ( (vms_stat = wflor( efcn,efn_table,&efn ))  /* wait for set flag */
127:         != SS$_NORMAL )
128:                 {
129:                 if ( msglevel > 0 )     /* print error if can't read efn */
130:                         printf("\n%s> Can't wflor, err=%s",
131:                         program_id,vmsmsg(vms_stat));
132:                 continue;               /* couldn't read efn so try again */
133:                 }
134:         if ( msglevel > 9 )             /* print a flow control message */
135:                 printf("\n%s> Wflor, efn=%d",program_id,efn);
136:         if ( efn == mbx_efn )           /* if a mailbox message woke us ... */
137:                 goto get_mail;          /* ... go back and read it */
138:         }
139: #else
140: /* --- Read a mailbox message --- */
141: if ( (vms_stat = readmbxw(pidchan, mbx_maxmsg, mbx_buff, &msglen))
142: == SS$_NORMAL )                         /* got a message upon return */
143:         got_mail = TRUE;                /* so raise the mailbox flag */
144: else                                    /* we got an error return */
145:         {
146:         if ( msglevel > 0 )             /* print error if can't read box */
147:                 printf("\n%s> Can't readmbxw, err=%s",
148:                 program_id,vmsmsg(vms_stat));
149:         continue;                       /* couldn't read so try again */
150:         }
151: #endif
152: 
153: /* --- display the mailbox message --- */
154: if ( got_mail && (msglevel > 9) )       /* print a mail flow control message */
155:         printf("\n%s> Readmbxw, process_id=%c, opcode=%d, msgseq#%d",
156:         program_id,mbxhdr->process_id,mbxhdr->opcode,mbxhdr->msgseqnum);
157: if ( got_mail && (trace > 9) )          /* mail the msg to trace for dump */
158:         wrtmbxmsg ( process_id,msglevel, trace_id, msglen,mbxhdr );
159: 
160: /* -------------------------------------------------------------------------
161: Handle mail messages according to their opcode
162: -------------------------------------------------------------------------- */
163: if ( got_mail ) switch ( mbxhdr->opcode )
164: {                               /* --- beginning of Mailbox Switch --- */
165: /* --- first check for an exit message --- */
166: case EDS$_EXITMSG:                      /* got an exit opcode */
167:         goto end_of_job;                /* break out of loop for exit */
168: 
169: /* --- check for a message from the system manager --- */
170: case EDS$_MGMTMSG:                      /* got a system manager message */
171:         /* --- first parse it as "key=value" and xlate the value --- */
172:         if((bufflen=mbxmsg->bufflen)>64)/* max manager msg is 64 bytes */
173:                 bufflen = 16;           /* else truncate at 16 */
174:         msgbuf[bufflen] = '\000';       /* make sure msg is null-terminated */
175:         if((msgdelim=strchr(msgbuf,'=')) == 0) /* does msg contain '='? */
176:                 msgval = 0;             /* no - so no delim, only got a key */
177:         else    {                       /* yes - got value following the key */
178:                 msgval=atoi(msgdelim+1);/* so xlate the value */
179:                 *msgdelim = '\000';     /* and null-terminate the key */
180:                 }
181:         /* --- now check the key to see what manager wants done --- */
182:         if(!strcmp(msgbuf,"exit"))      /* manager is forcing us to exit */
183:                 goto end_of_job;        /* so take his word for it and leave */
184:         if(!strcmp(msgbuf,"msglevel"))  /* he wants to change msglevel */
185:                 msglevel = msgval;      /* so set it accordingly */
186:         if(!strcmp(msgbuf,"trace"))     /* he wants to set a trace */
187:                 {                       /* get (new) process_id for trace */
188:                 if (strlen(trace_id)>0) /* first close old mbx chan */
189:                         closechan(process_id,msglevel,trace_id);
190:                 *trace_id = '\000';     /* trace process_id reset */
191:                 trace = 0;              /* and trace flag reset */
192:                 if ( msgval > 0 )       /* we're turning trace on */
193:                         {               /* so set trace flag and process_id */
194:                         if ( trnlnm(0,EDS$_TRACELNM,trace_id) == SS$_NORMAL )
195:                                 trace = msgval; /* trace process up */
196:                         else    { trace = 0;    /* trace process isn't up */
197:                                 *trace_id = '\000'; }   
198:                         }
199:                 }
200:         break;
201: 
202: /* --- we didn't trap the opcode so it's unknown --- */
203: default:                                /* got an unknown opcode */
204:         if ( msglevel > 1 )             /* so print an error message */
205:                 printf("\n%s> Unknown opcode=%d(decimal), from process_id=%c.",
206:                 program_id,(int)(mbxhdr->opcode),mbxhdr->process_id);
207:         break;
208: }                               /* --- end of Mailbox Switch --- */
209: 
210: }                       /* --- end of while(TRUE) loop --- */
211: 
212: 
213: /* -------------------------------------------------------------------------
214: End of Job.
215: -------------------------------------------------------------------------- */
216: end_of_job:
217: if ( msglevel > 0 )                     /* print end-of-job message */
218:         printf("\n%s> End-of-Job",program_id);
219: }       /* --- end of main() --- */


EEEEEEEEEE DDDDDDDD     SSSSSSS               CCCCCCC  LLLLL        IIIIII     SSSSSSS 
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             CCCCCCCCC LLLLL        IIIIII    SSSSSSSSS
 EE     EE  DD     DD SS                    CC      CC  LL            II     SS        
 EEEEEE     DD     DD  SSSSSSS              CC          LL            II      SSSSSSS  
 EEEEEE     DD     DD   SSSSSSS             CC          LL            II       SSSSSSS 
 EE     EE  DD     DD         SS            CC      CC  LL     LL     II             SS
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________  CCCCCCCCC LLLLLLLLLL   IIIIII   SSSSSSSSS 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________   CCCCCCC  LLLLLLLLLL   IIIIII    SSSSSSS  

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Include:     eds_clishell
  7:  *
  8:  * Purpose:     Generic command-line interpreter shell program for EDS.
  9:  *              This "front-end" shell reads all command-line arguments,
 10:  *              creates mailboxes, event flag clusters, global sections,
 11:  *              opens rms files for the application to read, etc.
 12:  *
 13:  * Notes:       See EDS_CLISHELL.C for detailed comments.
 14:  *
 15:  * Source:      EDS_CLISHELL.H
 16:  *
 17:  * --------------------------------------------------------------------------
 18:  * Revision History:
 19:  *
 20:  * 04/22/86     J.Forkosh       Installation.
 21:  *
 22:  ****************************************************************************/
 23: 
 24: /* -------------------------------------------------------------------------
 25: Allocations and Declarations for EDS Shell variables
 26: -------------------------------------------------------------------------- */
 27: /* --- process identification variables --- */
 28: char    process_id[8];                  /* this process - always argv[1] */
 29: char    program_id[32];                 /* for printf identification */
 30: 
 31: /* --- each string contains the arg numbers for mailboxes, etc. --- */
 32: static  char *arg_strings[] =
 33:                 {                       /* --- arg number strings --- */
 34:                 PID_ARGS,               /* mailbox to this process_id */
 35:                 MBX_ARGS,               /* partner process mailboxes */
 36:                 EFC_ARGS,               /*    "       "    clusters */
 37:                 GLB_ARGS,               /*    "       "    sections */
 38:                 RMS_ARGS                /* rms file for application info */
 39:                 };
 40: 
 41: /* --- the mailboxes, global sections, and rms files opened --- */
 42: int     mbx_chans[8];                   /* mbx chans to process_id,partners */
 43: char    *sect_ptrs[8];                  /* pointers to global sections */
 44: FILE    *file_ptrs[8];                  /* file pointer for application info */
 45: 
 46: /* --- various and sundry variables --- */
 47: int     mbx_maxmsg = PID_MAXMSG;        /* max bytes per mailbox message */
 48: int     mbx_bufquo = PID_BUFQUO;        /* total bytes per mailbox buffer */
 49: int     glb_pagcnt = PID_PAGCNT;        /* number pages per global section */
 50: int     efcn=EFCN;                      /* common event flag cluster number */
 51: int     efn;                            /* the efn that wasset when we wake */
 52: int     mbx_efn;                        /* event flag set when mail waiting */
 53: int     got_mail;                       /* local flag set when mail wakes us */
 54: unsigned char mbx_buff[PID_MAXMSG];     /* mailbox message buffer */
 55: struct  mbxmsghdr_struct *mbxhdr;       /* message header to address buffer */
 56: struct  mbxmsg_struct *mbxmsg;          /* and a default msg to addr buffer */
 57: int     msglen,bufflen;                 /* total msg length, mbxmsg->bufflen */
 58: char    *strchr(),*msgbuf,*msgdelim;    /* to help pasre system manager msgs */
 59: int     msgval;                         /* xlated atoi(system manager msg) */
 60: int     pidchan = 0;                    /* mailbox chan for this process */
 61: short   mbx_iosb[4];                    /* iosb for unsolicited mail */
 62: int     msglevel;                       /* message level for printf's */
 63: int     trace = 0;                      /* trace level, init for no traces */
 64: char    trace_id[8] = "\000";           /* process_id of the trace process */
 65: int     vms_stat;                       /* return stat from system services */
 66: int     iline;                          /* dummy instruction line loop index */
 67: 
 68: /* -------------------------------------------------------------------------
 69: Verify arg count, and get "hard-coded" command-line arguments (first and last).
 70: -------------------------------------------------------------------------- */
 71: /* --- Verify argc count.  Print instructions and exit if no good. --- */
 72: if ( argc < MIN_ARGC || argc > MAX_ARGC ) /* if #args out of range */
 73:         {                               /* print instructions and exit */
 74:         for( iline=0; strlen(instructions[iline])>0; iline++)
 75:                 printf("\n%s",instructions[iline]);
 76:         exit(-1);
 77:         }
 78: 
 79: /* --- First and last args are process_id and msglevel. --- */
 80: strcpy ( process_id, argv[1] );         /* process_id is always 1st arg */
 81: strcpy ( program_id, PROGRAM_ID );      /* start program_id with stub, ... */
 82: strcat ( program_id, process_id );      /* ... and concat process_id to it */
 83: 
 84: /* -------------------------------------------------------------------------
 85: Get application-dependent command-line arguments by calling eds_cli
 86: -------------------------------------------------------------------------- */
 87: vms_stat=eds_cli( argc, argv, mbx_maxmsg, mbx_bufquo, glb_pagcnt, arg_strings,
 88:                 &msglevel, mbx_chans, sect_ptrs, file_ptrs );
 89: 
 90: /* -------------------------------------------------------------------------
 91: Initialize application variables
 92: -------------------------------------------------------------------------- */
 93: if ( strlen(PID_ARGS) > 0 )
 94:         pidchan = mbx_chans[0];         /* incoming mail is on this channel */
 95: mbxhdr = mbx_buff;                      /* and always starts with a header */
 96: mbxmsg = mbx_buff;                      /* and is often in this form */
 97: msgbuf = mbxmsg->buffer;                /* address of mbxmsg->buffer[0] */
 98: #ifdef EVENT_CLUSTER
 99: efn_table[0] =
100: #endif
101: mbx_efn = (int)(*process_id - 'A') + 1; /* efn set by partner sending mail */
102: 
103: /* -------------------------------------------------------------------------
104: THIS IS THE END OF THE SHELL CODE (Application-level code follows)
105: -------------------------------------------------------------------------- */


EEEEEEEEEE DDDDDDDD     SSSSSSS               CCCCCCC  RRRRRRRR   TTTTTTTTTT DDDDDDDD  
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             CCCCCCCCC RRRRRRRRR  TTTTTTTTTT DDDDDDDDD 
 EE     EE  DD     DD SS                    CC      CC  RR     RR TT  TT  TT  DD     DD
 EEEEEE     DD     DD  SSSSSSS              CC          RRRRRRRR      TT      DD     DD
 EEEEEE     DD     DD   SSSSSSS             CC          RRRRRRR       TT      DD     DD
 EE     EE  DD     DD         SS            CC      CC  RR   RR       TT      DD     DD
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________  CCCCCCCCC  RR    RR     TTTT    DDDDDDDDD 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________   CCCCCCC   RR     RR    TTTT    DDDDDDDD  

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Program:     eds_crtdriver
  7:  *
  8:  * Purpose:     Stub for loopback test
  9:  *
 10:  * Call:        $ crt "crtid" ["msglevel"]
 11:  *              (where $crt :== $sys$sysdevice:[]eds_crtdriver.exe
 12:  *              has been installed as a foreign command)
 13:  *
 14:  * Arguments:
 15:  *              crtid (I)       process_id (always first command-line arg)
 16:  *
 17:  *              msglevel (I)    message level (always last [optional] arg)
 18:  *
 19:  * Source:      EDS_CRTDRIVER.C
 20:  *
 21:  * --------------------------------------------------------------------------
 22:  * Revision History:
 23:  *
 24:  * 03/19/86     J.Forkosh       Installation.
 25:  *
 26:  ****************************************************************************/
 27: 
 28: /* -------------------------------------------------------------------------
 29: Generic include files
 30: -------------------------------------------------------------------------- */
 31: #include stdio
 32: #include ssdef
 33: /* --- symdef, mbxdef, glbdef are the minimum set of EDS include files --- */
 34: #include "eds$shl:eds_symdef.h"
 35: #include "eds$shl:eds_mbxdef.h"
 36: #include "eds$shl:eds_glbdef.h"
 37: /* --- include files specific to the crt application --- */
 38: #include "eds$shl:eds_dcpdef.h"
 39: #include "eds$lib:eds_devdef.h"
 40: 
 41: /* -------------------------------------------------------------------------
 42: Application-dependent defines (_ARG defines are used to interpret command line)
 43: -------------------------------------------------------------------------- */
 44: #define EVENT_CLUSTER "remove this stmt if common event flags not used"
 45: #ifdef EVENT_CLUSTER
 46: #define EFC_ARGS "1"
 47: #else
 48: #define EFC_ARGS ""
 49: #endif
 50: 
 51: #define PROGRAM_ID "CRT_"
 52: #define MIN_ARGC 2
 53: #define MAX_ARGC 3
 54: #define PID_ARGS "1"
 55: #define MBX_ARGS ""
 56: #define GLB_ARGS "sk"
 57: #define RMS_ARGS ""
 58: #define PID_MAXMSG MBX_MAXMSG           /* max bytes per mailbox message */
 59: #define PID_BUFQUO MBX_BUFQUO           /* total bytes per mailbox buffer */
 60: #define PID_PAGCNT GLB_PAGCNT           /* number pages per global section */
 61: char *instructions[] =                  /* print these for wrong argc count */
 62:         {
 63:         "Usage: $ crt \"process_id\" [\"msglevel\"]",
 64:         ""
 65:         };
 66: 
 67: #ifdef EVENT_CLUSTER
 68: int     efn_table[] =
 69:                 {
 70:                 0,
 71:                 255
 72:                 } ;
 73: #endif
 74: 
 75: main ( argc, argv )
 76: int     argc;
 77: char    *argv[];
 78: {
 79: /* -------------------------------------------------------------------------
 80: Allocations and Declarations for CRT application variables
 81: -------------------------------------------------------------------------- */
 82: #define TERMINATION_MSG "Exit"
 83: #define SMALLSCREEN_MSG "small_screen"
 84: #define _cup(row,col)   "\033[row;col\110"
 85: #define _wipe_clr       "\033[0;0H\033[2J"
 86: #define _cvt(x,n)       gcvt((double)(x),n,cvtbuf)
 87: char    crtid[16];                      /* name of crt */
 88: int     small_screen=0;                 /* 1 to build small output screen */
 89: int     crtchan;                        /* crt mailbox chan */
 90: int     dev_num;                        /* device number from mailbox msg */
 91: int     exit_flag=0;                    /* set to 1 when time to exit */
 92: struct  crtmsg_struct crtmsg;           /* crt input mailbox messages */
 93: struct  tcpinitmsg_struct *tcpinitmsg;  /* to address crtmsg as a tcpinitmsg */
 94: struct  tcpmsg_struct tcpmsg;           /* tcp output mailbox messages */
 95: struct  mbxmsghdr_struct *replymsg;     /* target struct ptr for reply */
 96: char    *sect_ptr();                    /* converts dev_num to ptr into ... */
 97: struct  devtable_struct *dev_ptr;       /* ... device table structure */
 98: struct  dcptable_struct *dcp_ptr;       /* imbedded dcptable within devtable */
 99: char    *dev_sect;                      /* ptr to devtable global section */
100: char    *kbd_sect;                      /* ptr to keyboard global section */
101: char    opcode[2];                      /* opcode of mailbox message */
102: char    partner_id[2];                  /* process_id of partner process */
103: char    crttext[128],tcptext[512];      /* in- and out- message text */
104: char    *gcvt(),cvtbuf[64];             /* for numeric->character conversion */
105: int     textlen,cvtlen,replylen;        /* lengths of text buffers */
106: char    *daytime(),prev_op[99];         /* for thruput timing tests */
107: int     nscreens[99],stime[99],etime[99]; /* #screens, start,end test times */
108: 
109: /* -------------------------------------------------------------------------
110: Beginning of executable code ...
111: -------------------------------------------------------------------------- */
112: #include "eds$shl:eds_clishell.h"       /* first execute the generic shell */
113: 
114: /* -------------------------------------------------------------------------
115: THIS IS THE END OF THE SHELL CODE (Application-level code follows)
116: -------------------------------------------------------------------------- */
117: /* --- local copies of command-line args, and returns from cli --- */
118: strcpy ( crtid, argv[1] );              /* crtid is 1st command line arg */
119: crtchan = mbx_chans[0];                 /* channel of crt's mailbox */
120: dev_sect= sect_ptrs[0];                 /* ptr to devtable global section */
121: kbd_sect= sect_ptrs[1];                 /* ptr to keyboard table section */
122: if ( msglevel > 0 )
123:         printf ("\n%s> Initialization complete.",program_id);
124: 
125: /* -------------------------------------------------------------------------
126: Wait for messages
127: -------------------------------------------------------------------------- */
128: while ( TRUE )
129: {
130: 
131: /* --- get the next mailbox message --- */
132: if ( 
133: (vms_stat=rdcrtmbx
134:         (process_id,msglevel,crtchan,dev_sect,kbd_sect,opcode,&crtmsg))
135: != SS$_NORMAL )                         /* get a message from a partner */
136:         {                               /* got an error return instead */
137:         if ( msglevel > 0 )             /* so print an err msg */
138:                 printf ("\n%s> Can't rdcrtmbx, err=%s",
139:                 program_id,vmsmsg(vms_stat));
140:         continue;                       /* and try another pass */
141:         }
142: 
143: /* --- first ack the msg to post another qio --- */
144: ackmsg ( process_id, msglevel, "a", &crtmsg );
145: 
146: /* --- extract fields from message header --- */
147: partner_id[0] = crtmsg.hdr.process_id;  /* process that sent us the msg */
148: partner_id[1] = '\000';                 /* null-terminated */
149: 
150: /* --- print flow control msg --- */
151: if ( msglevel > 9 )
152:         {
153:         if ( *opcode==EDS$_MSG )        /* keyboard input from a tcp */
154:         {
155:         dev_num = crtmsg.hdr.dev_num;   /* get the device number */
156:         dev_ptr = sect_ptr(dev_sect,dev_num,0); /* and a ptr into devtable */
157:         printf("\n%s> Recv'd mbxmsg: tcp_%s, seq#%d, dev#%d, text=%.32s",
158:         program_id,partner_id,crtmsg.hdr.msgseqnum,crtmsg.hdr.dev_num,
159:         dev_ptr->operatormsg.string);
160:         }
161:         else                            /* msg was init or not from a tcp */
162:         printf("\n%s> Recv'd mbxmsg: partner=%s, opcode=%d, seq#%d, dev#%d",
163:         program_id,partner_id,*opcode,crtmsg.hdr.msgseqnum,crtmsg.hdr.dev_num);
164:         }
165: /* -------------------------------------------------------------------------
166: Handle each message type differently according to its opcode
167: -------------------------------------------------------------------------- */
168: switch ( *opcode )
169:         {
170: 
171: case EDS$_MSG:
172: case EDS$_INITMSG:
173: /* --- extract relevant fields from struct --- */
174:         dev_num = crtmsg.hdr.dev_num;   /* get the device number */
175:         dev_ptr = sect_ptr(dev_sect,dev_num,0); /* and a ptr into devtable */
176:         dcp_ptr = &(dev_ptr->dcptable);         /* and imbedded dcptable */
177:         textlen = dev_ptr->operatormsg.num[3];  /* extract the text length */
178:         if ( *opcode != EDS$_MSG )              /* init textlen and prev_op */
179:                 { textlen=0; prev_op[dev_num]='\000'; }
180:         if ( textlen > 64 ) textlen=64;         /* test check on length */
181:         strncpy(crttext,dev_ptr->operatormsg.string,textlen); /* local copy */
182:         crttext[textlen] = '\0';        /* and null-terminate it */
183:         if ( !strncmp(crttext,SMALLSCREEN_MSG,strlen(SMALLSCREEN_MSG)) )
184:                 {
185:                 small_screen = 1-small_screen;
186:                 }
187:         if ( !strncmp(crttext,TERMINATION_MSG,strlen(TERMINATION_MSG)) )
188:                 {                       /* user entered exit request */
189:                 exit_flag=1;            /* so set exit flag */
190:                 strcpy ( crttext,"End_of_Job" ); /* and replace echo-ed msg */
191:                 }
192: 
193: /* --- format an output screen buffer --- */
194:         strcpy(tcptext,_wipe_clr);
195:         if ( small_screen == 0 )
196:                 {
197:                 strcat(tcptext,_cup(2,1)); strcat(tcptext,"Device: ");
198:                         strcat(tcptext,dcp_ptr->devnam);
199:                 strcat(tcptext,_cup(2,30)); strcat(tcptext,"CRT: _");
200:                         strcat(tcptext,process_id);
201:                 strcat(tcptext,_cup(2,40)); strcat(tcptext,"TCP: _");
202:                         strcat(tcptext,partner_id);
203:                 strcat(tcptext,_cup(2,65)); strcat(tcptext,"KeyBoard#");
204:                         strcat(tcptext,_cvt(dev_ptr->keyboard,3));
205:                 strcat(tcptext,_cup(3,27)); strcat(tcptext,daytime(0));
206:                 }
207:         if ( *opcode == EDS$_MSG )
208:                 {
209:                 if ( prev_op[dev_num] != dev_ptr->operatormsg.opcode )
210:                         { daytime(&stime[dev_num]); nscreens[dev_num]=0;
211:                         prev_op[dev_num]=dev_ptr->operatormsg.opcode; }
212:                 if ( small_screen == 0 )
213:                         {
214:                         strcat(tcptext,_cup(6,1));
215:                         strcat(tcptext,"Command String: ");
216:                         strcat(tcptext,crttext);
217:                         strcat(tcptext,_cup(8,1));
218:                         }
219:                 strcat(tcptext,"Bytes=");
220:                 textlen=strlen(tcptext); strcat(tcptext,"   ");
221:                 daytime(&etime[dev_num]);
222:                 if ( small_screen == 0 )
223:                         {
224:                         strcat(tcptext," Secs=");
225:                         strcat(tcptext,_cvt(etime[dev_num]-stime[dev_num],8));
226:                         strcat(tcptext," Scrns=");
227:                         strcat(tcptext,_cvt(1+nscreens[dev_num],4));
228:                         }
229:                 if ( nscreens[dev_num] > 0 )
230:                 { strcat(tcptext," Secs/Scrn="); strcat(tcptext,
231:                 _cvt((etime[dev_num]-stime[dev_num])/nscreens[dev_num],4)); }
232:                 nscreens[dev_num]++;
233:                 }
234:         if ( small_screen == 0 )
235:                 {
236:                 strcat(tcptext,_cup(12,1)); strcat(tcptext,"---Msg Vector---");
237:                 strcat(tcptext,_cup(13,1)); strcat(tcptext,"Opcode: ");
238:                         strcat(tcptext,_cvt(dev_ptr->operatormsg.opcode,4));
239:                 strcat(tcptext,_cup(14,1)); strcat(tcptext,"NESid: ");
240:                         strncat(tcptext,dev_ptr->operatormsg.nesid,8);
241:                 strcat(tcptext,_cup(15,1)); strcat(tcptext,"Page: ");
242:                         strcat(tcptext,_cvt(dev_ptr->operatormsg.page,6));
243:                 strcat(tcptext,_cup(16,1)); strcat(tcptext,"Num1: ");
244:                         strcat(tcptext,_cvt(dev_ptr->operatormsg.num[0],6));
245:                 strcat(tcptext,_cup(17,1)); strcat(tcptext,"Num2: ");
246:                         strcat(tcptext,_cvt(dev_ptr->operatormsg.num[1],6));
247:                 strcat(tcptext,_cup(21,1));strcat(tcptext,"Enter Command-->");
248:                 }
249:         _cvt(strlen(tcptext),5); cvtlen=0;
250:                 while(cvtbuf[cvtlen]!='\000')
251:                         tcptext[textlen++] = cvtbuf[cvtlen++];
252: 
253: /* --- format mailbox message reply --- */
254:         tcpmsg.hdr.opcode = EDS$_MSG;
255:         tcpmsg.hdr.reqseqnum = crtmsg.hdr.msgseqnum;
256:         tcpmsg.hdr.dev_num = crtmsg.hdr.dev_num;
257:         tcpmsg.hdr.bufflen = strlen(tcptext)+1;
258:         strcpy(tcpmsg.buffer,tcptext);
259:         replymsg = &tcpmsg;
260:         replylen = tcpmsghdr_size + tcpmsg.hdr.bufflen;
261:         break;
262: 
263: default:
264:         replylen = 0;                   /* no reply for unknown opcode */
265:         break;
266:         }
267: 
268: /* -------------------------------------------------------------------------
269: Mail reply to sending process if a reply is required
270: -------------------------------------------------------------------------- */
271: if ( replylen > 0 )                     /* got a reply if replylen>0 */
272:         {
273:         if ( 
274:         (vms_stat=wrtmbxmsg
275:                 (process_id,msglevel,partner_id,replylen,replymsg))
276:         != SS$_NORMAL )
277:                 {
278:                 if ( msglevel > 0 )
279:                         printf ("\n%s> Can't wrtmbxmsg, replylen=%d, err=%s",
280:                         program_id,replylen,vmsmsg(vms_stat));
281:                 }
282:         }
283: if ( exit_flag != 0 ) break;            /* time to exit - get out of loop */
284: }       /* --- end of while(TRUE) loop --- */
285: 
286: /* -------------------------------------------------------------------------
287: Mail termination msg back to all TCP's
288: -------------------------------------------------------------------------- */
289: end_of_job:
290: sleep ( 1 );                            /* wait a few secs for last msg */
291: tcpmsg.hdr.opcode = EDS$_EXITMSG;
292: tcpmsg.hdr.reqseqnum = 0;
293: tcpmsg.hdr.dev_num = 0;
294: tcpmsg.hdr.bufflen = 0;
295: if ( (vms_stat=wrtmbxmsg(process_id,msglevel,"",tcpmsghdr_size,&tcpmsg))
296: != SS$_NORMAL )
297:         {
298:         if ( msglevel > 0 )
299:                 printf ("\n%s> Can't wrtmbxmsg termination msg, err=%s",
300:                 program_id,vmsmsg(vms_stat));
301:         }
302: }


EEEEEEEEEE DDDDDDDD     SSSSSSS             DDDDDDDD   EEEEEEEEEE VV      VV TTTTTTTTTT
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            DDDDDDDDD  EEEEEEEEEE VV      VV TTTTTTTTTT
 EE     EE  DD     DD SS                     DD     DD  EE     EE VV      VV TT  TT  TT
 EEEEEE     DD     DD  SSSSSSS               DD     DD  EEEEEE    VV      VV     TT    
 EEEEEE     DD     DD   SSSSSSS              DD     DD  EEEEEE     VV    VV      TT    
 EE     EE  DD     DD         SS             DD     DD  EE     EE   VV  VV       TT    
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ DDDDDDDDD  EEEEEEEEEE    VVVV       TTTT   
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________ DDDDDDDD   EEEEEEEEEE     VV        TTTT   

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    devtblinit
  7:  *
  8:  * Purpose:     Initializes the device table from the crt task
  9:  *              after receiving an EDS$_INIT message from the tcp.
 10:  *
 11:  * Call:        devtblinit(process_id, msglevel, dev_num, dev_sect, kbd_sect)
 12:  *
 13:  * Arguments:
 14:  *              process_id (I)  addr of char string containing process id
 15:  *
 16:  *              msglevel (I)    int containing printf message level
 17:  *
 18:  *              dev_num(I)      int containing global device number.
 19:  *
 20:  *              dev_sect (I)    addr of device table global section.
 21:  *
 22:  *              kbd_sect (I)    addr of keyboard table global section.
 23:  *
 24:  * Returns:     - int
 25:  *              SS$_NORMAL      for successful completion,
 26:  *              SS$_status      or error status otherwise.
 27:  *
 28:  * Source:      EDS_DEVTBLINIT.C
 29:  *
 30:  * --------------------------------------------------------------------------
 31:  * Revision History:
 32:  *
 33:  * 04/07/86     J.Forkosh       Installation.
 34:  *
 35:  ****************************************************************************/
 36: 
 37: #include stdio
 38: #include ssdef
 39: #include "eds$shl:eds_symdef.h"
 40: #include "eds$shl:eds_mbxdef.h"
 41: #include "eds$tcp:eds_tcpdef.h"
 42: #include "eds$shl:eds_dcpdef.h"
 43: #include "eds$lib:eds_devdef.h"
 44: #include "eds$shl:eds_glbdef.h"
 45: #define NESID "       "
 46: 
 47: int     devtblinit ( process_id, msglevel, dev_num, dev_sect, kbd_sect )
 48: char    *process_id;
 49: int     msglevel;
 50: int     dev_num;
 51: char    *dev_sect;
 52: char    *kbd_sect;
 53: {
 54: 
 55: /* -------------------------------------------------------------------------
 56: Allocations and Declarations
 57: -------------------------------------------------------------------------- */
 58: struct  devtable_struct *dev_ptr;       /* ptr to device table structure */
 59: struct  dcptable_struct *dcp_ptr;       /* and to imbedded dcptable */
 60: struct  glbhdr_struct *kbdhdr;          /* keyboard sect global header */
 61: struct  kbdtbl_struct *kbdtbl;          /* 1st keyboard table */
 62: static  char entkbd,*defkbd,defkbdtbl[]=/* entitlement for default keyboard */
 63:         "0123456789ABCDEF";
 64: char    *strchr();                      /* lookup defkbd in defkbdtbl */
 65: char    *sect_ptr();                    /* converts device # to struct ptr */
 66: int     istate,ikbd;                    /* initial state, keyboard table# */
 67: int     ichar,tval;                     /* char#, termtblval */
 68: int     vms_stat;                       /* return stat from system services */
 69: 
 70: /* -------------------------------------------------------------------------
 71: Init fields in device table structure for this device
 72: -------------------------------------------------------------------------- */
 73: /* --- get ptrs to device table and to keyboard table --- */
 74: vms_stat = SS$_NORMAL;                  /* init return stat */
 75: dev_ptr = sect_ptr(dev_sect,dev_num,0); /* struct ptr to devtable */
 76: dcp_ptr = &(dev_ptr->dcptable);         /* and to imbedded dcptable */
 77: kbdhdr= kbd_sect;                       /* keyboard sect starts with glb hdr */
 78: kbdtbl= kbd_sect+glbhdr_size;           /* followed by 5 keyboard tables */
 79: kbdhdr->lockflag = FALSE;               /* unlock so keyboard task can exit */
 80: 
 81: /* --- init keyboard# is determined using entitlements[device_state] --- */
 82: ikbd = 0;                               /* default keyboard table# */
 83: istate = dev_ptr->device_state;         /* initial state of device */
 84: if (istate>0                            /* legal init state is between 1 and */
 85: && istate<=strlen(dev_ptr->entitlements)) /* length of entitlement string */
 86:         {                               /* ok - get init kbd# from enttls */
 87:         entkbd = dev_ptr->entitlements[istate-1]; /* pull out istateth char */
 88:         if ( (entkbd != 'X')            /* if device is entitled to it */
 89:         &&   ((defkbd=strchr(defkbdtbl,entkbd)) != 0) ) /* look up kbd# */
 90:                 ikbd= defkbd-defkbdtbl; /* new kbd# is offset into table */
 91:         }
 92: 
 93: /* --- got ikbd, now initialize corresponding fields in device table --- */
 94: dev_ptr->keyboard = ikbd;               /* keyboard table# */
 95: dcp_ptr->maxmsg = kbdtbl[ikbd].maxmsg;  /* set maxmsg for keyboard */
 96: dev_ptr->msgsiz = 0;                    /* no partial msg in buffer yet */
 97: for ( ichar=0; ichar<32; ichar++ )      /* copy termtbl from kbd to dev */
 98:         dcp_ptr->termtbl[ichar] = kbdtbl[ikbd].termtbl[ichar];
 99: 
100: /* --- finally, initialize various and sundry other device table fields --- */
101: dev_ptr->kbd_sect = kbd_sect;           /* crt-local addr of global kbd sect */
102: dev_ptr->operatormsg.opcode = '\000';   /* no opcode to start */
103: dev_ptr->select_opcode = '\000';        /* no previous source selected */
104: dev_ptr->prefix_opcode = 0;             /* no pending prefix opcode */
105: strcpy(dev_ptr->operatormsg.nesid,NESID); /* as well as blank nesid */
106: dev_ptr->operatormsg.page = 0;          /* page#0 to start */
107: for ( ichar=0; ichar<4; ichar++ )       /* and all 4 num's */
108:         dev_ptr->operatormsg.num[ichar] = 0;
109: dev_ptr->operatormsg.string[0]= '\000'; /* and a null string */
110: 
111: /* --- print initialization information --- */
112: if ( msglevel > 9 )
113:         {
114:         printf("\nCRT_%s> (devtblinit) dev#%d, nam=%s, kbd#%d, maxmsg=%d",
115:         process_id,dev_num,dcp_ptr->devnam,ikbd,dcp_ptr->maxmsg);
116:         printf("\nCRT_%s> termtbl=",process_id);
117:         for(ichar=0;ichar<32;ichar++)
118:                 { tval=dcp_ptr->termtbl[ichar]; printf("%2.2X",tval); }
119:         }
120: return ( vms_stat );
121: }


EEEEEEEEEE DDDDDDDD     SSSSSSS             KKKK    KK BBBBBBBB   DDDDDDDD     IIIIII  
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            KKKK   KK  BBBBBBBBB  DDDDDDDDD    IIIIII  
 EE     EE  DD     DD SS                     KK   KK    BB     BB  DD     DD     II    
 EEEEEE     DD     DD  SSSSSSS               KKKKKK     BBBBBBBB   DD     DD     II    
 EEEEEE     DD     DD   SSSSSSS              KKKKK      BBBBBBBB   DD     DD     II    
 EE     EE  DD     DD         SS             KK  KKK    BB     BB  DD     DD     II    
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ KKKK   KK  BBBBBBBBB  DDDDDDDDD    IIIIII  
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________ KKKK    KK BBBBBBBB   DDDDDDDD     IIIIII  

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Program:     eds_kbdinit
  7:  *
  8:  * Purpose:     Reads the keyboard definition tables from an RMS file
  9:  *              and stores them in a system-wide global structure.
 10:  *
 11:  * Call:        $ kbd "process_id" "keyboardfile" ["msglevel"]
 12:  *              (where $kbd :== $sys$sysdevice:[]eds_kbdinit.exe
 13:  *              has been installed as a foreign command)
 14:  *
 15:  * Arguments:
 16:  *              process_id (I)  single-character process identification
 17:  *
 18:  *              keyboardfile(I) name of the rms file that contains the
 19:  *                              keyboard definition tables.
 20:  *
 21:  *              msglevel (I)    optional - the last arg, if present,
 22:  *                              is always the message level (it must be 
 23:  *                              numeric and >0).
 24:  *
 25:  * Source:      EDS_KBDINIT.C
 26:  *
 27:  * --------------------------------------------------------------------------
 28:  * Revision History:
 29:  *
 30:  * 04/07/86     J.Forkosh       Installation.
 31:  *
 32:  ****************************************************************************/
 33: 
 34: /* -------------------------------------------------------------------------
 35: Generic include files
 36: -------------------------------------------------------------------------- */
 37: #include stdio
 38: #include ssdef
 39: /* --- symdef, mbxdef, glbdef are the minimum set of EDS include files --- */
 40: #include "eds$shl:eds_symdef.h"
 41: #include "eds$shl:eds_mbxdef.h"
 42: #include "eds$shl:eds_glbdef.h"
 43: 
 44: /* -------------------------------------------------------------------------
 45: Application-dependent defines (_ARG defines are used to interpret command line)
 46: -------------------------------------------------------------------------- */
 47: #define PROGRAM_ID "KBD_"
 48: #define MIN_ARGC 3
 49: #define MAX_ARGC 4
 50: #define PID_ARGS ""
 51: #define MBX_ARGS ""
 52: #define EFC_ARGS ""
 53: #define GLB_ARGS "k"
 54: #define RMS_ARGS "2"
 55: #define PID_MAXMSG MBX_MAXMSG           /* max bytes per mailbox message */
 56: #define PID_BUFQUO MBX_BUFQUO           /* total bytes per mailbox buffer */
 57: #define PID_PAGCNT GLB_PAGCNT           /* number pages per global section */
 58: char *instructions[] =                  /* print these for wrong argc count */
 59:         {
 60:         "Usage: $ kbd \"process_id\" \"keybdfile\" [\"msglevel\"]",
 61:         ""
 62:         };
 63: 
 64: main ( argc, argv )
 65: int     argc;
 66: char    *argv[];
 67: {
 68: /* -------------------------------------------------------------------------
 69: Allocations and Declarations for application variables
 70: (the programmer puts any application-specific declarations here...)
 71: -------------------------------------------------------------------------- */
 72: FILE    *kbd_file;                      /* name of rms keyboard file */
 73: char    *kbd_sect;                      /* address of global section */
 74: struct  glbhdr_struct *glbhdr;          /* global header in global section */
 75: struct  kbdtbl_struct *kbdtbl;          /* keyboard table in global section */
 76: int     ikbd,ikey;                      /* kbd(0-4) and key(0-127) indexes */
 77: int     nkeys;                          /* number of keys */
 78: 
 79: /* -------------------------------------------------------------------------
 80: Beginning of executable code ...
 81: -------------------------------------------------------------------------- */
 82: #include "eds$shl:eds_clishell.h"       /* first execute the generic shell */
 83: 
 84: /* -------------------------------------------------------------------------
 85: THIS IS THE END OF THE SHELL CODE (Application-level code follows)
 86: -------------------------------------------------------------------------- */
 87: /* --- make copies of generic stub arguments for kbd's personal use --- */
 88: glbhdr = kbd_sect = sect_ptrs[0];       /* addr as *char and glbhdr struct */
 89: kbdtbl = kbd_sect + glbhdr_size;        /* 1st table follows global hdr */
 90: kbd_file = file_ptrs[0];                /* ptr to rms keyboard file */
 91: glbhdr->lockflag = TRUE;                /* partner will reset when he maps */
 92: 
 93: /* --- init the keyboard tables --- */
 94:                                         /* offset1 points to current end */
 95: glbhdr->offset1 = glbhdr_size + NKBDS*kbdtbl_size + 32;
 96: for ( ikbd=0; ikbd < NKBDS; ikbd++ )    /* loop over all the keyboard tables */
 97:         {
 98:         kbdtbl[ikbd].maxmsg = 8;        /* init the qio maxmsg size */
 99:         for( ikey=0; ikey<32; ikey++ )  /* init the terminator tables */
100:                 {                       /* debug- terminate on any char < 32 */
101:                 kbdtbl[ikbd].termtbl[ikey] = '\000';
102:                 /* if ( ikey < 4 ) kbdtbl[ikbd].termtbl[ikey] = '\377'; */
103:                 }
104:         for( ikey=0; ikey<128; ikey++ ) /* init the macro strings */
105:                 {                       /* zero address means no xlation */
106:                 kbdtbl[ikbd].offset[ikey] = 0;
107:                 }
108:         }
109: 
110: /* --- read the rms file to fill in the keyboard tables --- */
111: nkeys = eds_readfile ( process_id, msglevel, kbd_file, kbd_sect, 0 );
112: 
113: if ( msglevel > 3 )
114:         printf("\n%s> Keyboard Table Initialization Complete - nkeys=%d",
115:         program_id,nkeys);
116: 
117: /* --- Wait for lockflag to be reset (by the 1st CRT partner task) --- */
118: while ( glbhdr->lockflag ) sleep(2);    /* keep looping until partner maps */
119: if ( msglevel > 2 )
120:         printf("\n%s> Exiting - partner has mapped to section",program_id);
121: exit(SS$_NORMAL);
122: }                               /* --- end of main() --- */


EEEEEEEEEE DDDDDDDD     SSSSSSS             KKKK    KK BBBBBBBB   DDDDDDDD   NN      NN
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            KKKK   KK  BBBBBBBBB  DDDDDDDDD  NNN     NN
 EE     EE  DD     DD SS                     KK   KK    BB     BB  DD     DD NNNN    NN
 EEEEEE     DD     DD  SSSSSSS               KKKKKK     BBBBBBBB   DD     DD NN NN   NN
 EEEEEE     DD     DD   SSSSSSS              KKKKK      BBBBBBBB   DD     DD NN   NN NN
 EE     EE  DD     DD         SS             KK  KKK    BB     BB  DD     DD NN    NNNN
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ KKKK   KK  BBBBBBBBB  DDDDDDDDD  NN     NNN
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________ KKKK    KK BBBBBBBB   DDDDDDDD   NN      NN

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    kbdnes
  7:  *
  8:  * Purpose:     Converts a keyboard string to an nes id.
  9:  *
 10:  * Call:        kbdnes ( process_id,msglevel, opcode, msg_buff, dev_ptr )
 11:  *
 12:  * Arguments:
 13:  *              process_id (I)  addr of char string containing process id.
 14:  *              msglevel (I)    int containing printf message level.
 15:  *              opcode (I)      single char containing "source" key opcode.
 16:  *              msg_buff (I)    addr of char string containing operand
 17:  *                              string to be converted to nes id.
 18:  *              dev_ptr(O)      addr of an devtable structure returning
 19:  *                              the nes id and associated parameters
 20:  *                              (e.g., page) in dev_ptr->operatormsg.
 21:  *
 22:  * Returns:     - int           SS$_NORMAL for successful completion,
 23:  *                              VMS error status otherwise.
 24:  *              
 25:  * Notes:
 26:  *              A nes string consists of four (or less) fields in any order:
 27:  *              Field   Format          Notes
 28:  *              -----   ------          -----
 29:  *              State   n:  (nnn:)      1-3 digits followed by :
 30:  *              Party   z:              one character followed by :
 31:  *              Office  z;              one character followed by ;
 32:  *              CD      n;  (nnn;)      1-3 digits followed by ;
 33:  *              County  n-  (nnn-)      1-3 digits followed by -
 34:  *
 35:  * Source:      EDS_KBDNES.C
 36:  *
 37:  * --------------------------------------------------------------------------
 38:  * Revision History:
 39:  *
 40:  * 04/15/86     J.Forkosh       Installation.
 41:  * 09/04/86     J.Forkosh       County-level functionality added to nesid.
 42:  *
 43:  ****************************************************************************/
 44: 
 45: #include stdio
 46: #include ssdef
 47: #include "eds$shl:eds_mbxdef.h"
 48: #include "eds$shl:eds_dcpdef.h"
 49: #include "eds$lib:eds_devdef.h"
 50: #define MAXNUMLEN 3
 51: #define MAXCHRLEN 1
 52: #define COUNTY 4
 53: int i;
 54: #define bytcpy(target,source,n) for(i=0;i < n;i++) (target)[i]=(source)[i]
 55: #define bytset(target,source,n) for(i=0;i < n;i++) (target)[i]=source
 56: 
 57: /* --- lexical scanner table --- */
 58: struct  {
 59:         char    delim;          /* delimter terminating field */
 60:         char    format;         /* '9'=numeric, 'x'=alpha */
 61:         char    defstr[8];      /* default string (indicates field len) */
 62:         int     dreqd;          /* TRUE if terminating delimiter required */
 63:         int     offset;         /* field offset, - value for left-justified */
 64:         int     fldlen;         /* field length, same as strlen(defstr) */
 65:         }
 66: lextbl[] =
 67:         { /* delim format defstr dreqd off len */
 68:         {    ':',    '9',  "00", TRUE,  0,  2 },        /* state */
 69:         {    ':',    'x',   " ", FALSE, 2,  1 },        /* office */
 70:         {    ',',    'x',   " ", FALSE, 3,  1 },        /* party */
 71:         {    ',',    '9', "000", FALSE, 4,  3 },        /* CD */
 72:         {    '-',    '9', "000", TRUE, 99,  3 },        /* county */
 73:         { '\000', '\000',    "", FALSE, 7,  0 }};       /* end-of-table */
 74: 
 75: int     kbdnes ( process_id,msglevel, opcode, msg_buff, dev_ptr )
 76: char    *process_id;
 77: int     msglevel;
 78: char    opcode;
 79: char    *msg_buff;
 80: struct  devtable_struct *dev_ptr;
 81: {
 82: /* -------------------------------------------------------------------------
 83: Allocations and Declarations
 84: -------------------------------------------------------------------------- */
 85: static  char *tokptr,token[16];         /* nes token from msg_buff */
 86: static  char nesbld[16];                /* buffers to build nesid */
 87: static  char tokbfr[8][16];             /* buffers to store tokens */
 88: static  int got_lex[8];                 /* flags set when we get token */
 89: char    *bldptr;                        /* points to nesbld or tokbfr */
 90: char    delim,format,*defstr;           /* delimiter and format, and defstr */
 91: char    *nesid;                         /* ptr to nesid in operatormsg */
 92: int     itbl,offset,byte0;              /* token format variables */
 93: int     fldlen,toklen;                  /* len for token's field */
 94: int     did_cvt,cvtstat;                /* convert flag and return status */
 95: 
 96: /* -------------------------------------------------------------------------
 97: For no arg default case, just bump page number
 98: -------------------------------------------------------------------------- */
 99: if ( *msg_buff == '\000' )              /* no args in msg_buff */
100:         {                               /* so bump page/part if same source */
101:         if ( opcode == dev_ptr->select_opcode ) /* same source? */
102:                 dev_ptr->operatormsg.page++;    /* bump the page/part number */
103:         else    dev_ptr->operatormsg.page=0;    /* or else reset it */
104:         dev_ptr->select_opcode = opcode;        /* store for next call */
105:         return(SS$_NORMAL);             /* and don't change anything else */
106:         }
107: 
108: /* -------------------------------------------------------------------------
109: Got args, so parse input a token at a time
110: -------------------------------------------------------------------------- */
111: /* --- init some variables --- */
112: dev_ptr->select_opcode = opcode;        /* store source key for next call */
113: dev_ptr->operatormsg.page = 0;          /* always reset page number if args */
114: nesid = dev_ptr->operatormsg.nesid;     /* get a ptr to the nesid */
115: bytcpy(nesbld,nesid,7);                 /* local copy of nesid */
116: nesbld[7] = '\000';                     /* always null-terminated */
117: bytcpy(token,nesbld,2);token[2]='\000'; /* get a local copy of state */
118: if ( atoi(token) > 63 )                 /* state>63 means a county nesid */
119:         { distcvt(1,nesbld,tokbfr[COUNTY]); /* so convert it back */
120:         did_cvt = TRUE; }               /* and set flag to re-convert later */
121: else    did_cvt = FALSE;                /* haven't converted a county */
122: for ( itbl=0; itbl<8; itbl++ )          /* don't default same field twice */
123:         got_lex[itbl] = FALSE;          /* so far, no defaults found */
124: 
125: /* --- get a token terminated by a delim --- */
126: next_token:                             /* come here for each new token */
127: tokptr = token;                         /* start a new token at start */
128: toklen = 0;                             /* len of token is 0 so far */
129: format = '9';                           /* assume numeric until char */
130: while ( *msg_buff != '\000' )           /* while we still have more chars */
131:         {
132:         for ( itbl=0; (delim=lextbl[itbl].delim)!='\000'; itbl++ )
133:                 if (delim == *msg_buff  /* got a delimiter */
134:                 && format == lextbl[itbl].format ) /* with right format */
135:                         {msg_buff++;    /* bump past delimiter */
136:                         got_lex[itbl]=TRUE; /* don't default to this fld */
137:                         goto got_token;}/* and go process complete token */
138:         if ( (format=='x' && toklen>=MAXCHRLEN) ) /* if largest char arg */
139:         /* ||(format=='9' && toklen>=MAXNUMLEN) )  or if largest numeric arg */
140:                 break;                  /* then don't accumulate any more */
141:         if ( (*msg_buff < '0') || (*msg_buff > '9') ) /* check format */
142:                 { if(format=='9' && toklen>0) /* switched from num to char */
143:                         break;          /* so assume end of token */
144:                 format = 'x'; }         /* one alpha char - can't be number */
145:         *tokptr++ = *msg_buff++;        /* wasn't delim so copy token char */
146:         toklen++;                       /* bump the token length */
147:         }
148: 
149: /* --- end of msg_buff, either default token or time to go home --- */
150: if ( tokptr == token )          /* no token, so return to caller */
151:         {
152:         nesbld[7] = '\000';     /* null-terminate build buffer for nesid */
153:         cvtstat = 99;           /* default ok return stat from distcvt */
154:         if ( got_lex[COUNTY] )  /* operator gave us a county, so convert it */
155:                 { cvtstat = distcvt(0,nesbld,tokbfr[COUNTY]); }
156:         if ( cvtstat >= 0 )     /* check return status (or ok default) */
157:                 bytcpy(nesid,nesbld,7); /* if ok, move nesid to operatormsg */
158:         nesid[7] = '\000';      /* to be safe, null-terminate nesid */
159:         if ( msglevel > 9 )     /* and print nesid for flow control */
160:                 { if(!got_lex[COUNTY])
161:                 printf("\nCRT_%s> (kbdnes) nesbld/id=%s/%s",
162:                 process_id,nesbld,dev_ptr->operatormsg.nesid);
163:                 else
164:                 printf("\nCRT_%s> (kbdnes) cvt=%d, cnt=%s, nesbld/id=%s/%s",
165:                 process_id,cvtstat,tokbfr[COUNTY],nesbld,nesid); }
166:         return ( SS$_NORMAL );  /* and go home to caller */
167:         }
168: 
169: /* -------------------------------------------------------------------------
170: Got a complete token (either with explicit delim, or reached end of msg_buff)
171: -------------------------------------------------------------------------- */
172: got_token:
173: *tokptr = '\000';                       /* first null-terminate token */
174: /* --- No delim?  Try to match field length and format, else default. --- */
175: if ( delim == '\000' )                  /* got a token but no delim */
176:         {                               /* so choose default delimiter */
177:         for ( itbl=0; (delim=lextbl[itbl].delim)!='\000'; itbl++ )
178:                 if( !lextbl[itbl].dreqd /* if delim not required */
179:                 /* && toklen <= lextbl[itbl].fldlen */ /* and not too long */
180:                 && format == lextbl[itbl].format /* and right format */
181:                 && !got_lex[itbl] )     /* and if not already parsed */
182:                         break;          /* then let's use it, else ... */
183:         if ( delim == '\000' )          /* no match, so forget it */
184:                 goto next_token;        /* and try the next token */
185:         if ( format != '9' )            /* for alpha tokens */
186:                 got_lex[itbl] = TRUE;   /* don't re-use this default */
187:         }
188: 
189: /* --- set parameters to copy token to nesid --- */
190: offset = lextbl[itbl].offset;           /* offset to token within nes */
191: byte0 = (offset<0)? -offset:offset;     /* get iabs(offset) as byte0 */
192: if ( byte0 != 99 ) bldptr=nesbld+byte0; /* token goes to field in nesid */
193: else { bldptr=tokbfr[itbl]; bytset(bldptr,'\000',8); } /* else buffer token */
194: defstr = lextbl[itbl].defstr;           /* ptr to default string in lextbl */
195: fldlen = lextbl[itbl].fldlen;           /* length of field in nesid */
196: tokptr = token;                         /* assume we'll copy entire token */
197: if ( toklen > fldlen )                  /* but don't let token overflow fld */
198:         { tokptr=token+(toklen-fldlen); /* use only trailing token chars */
199:         toklen = fldlen; }              /* and only fldlen chars from token */
200: 
201: /* --- copy token as long as it's not null --- */
202: if ( toklen > 0 )                       /* if we got a non-null token */
203:         {
204:         bytcpy(bldptr,defstr,fldlen);   /* init the field with default */
205:         if ( offset >= 0 )              /* this means right-justify token */
206:                 bldptr = bldptr+(fldlen-toklen); /* so reset starting byte */
207:         bytcpy(bldptr,tokptr,toklen);   /* replace default string */
208:         }
209: else                                    /* user supplied null-token/delim */
210:         {
211:         if ( itbl == COUNTY )           /* null county token */
212:                 got_lex[COUNTY]=FALSE;  /* means don't re-convert back */
213:         }
214: 
215: /* --- debugging output --- */
216: if ( msglevel > 99 )
217: printf("\nCRT_%s> (kbdnes) token=%s, toklen=%d, delim=%c, itbl=%d, nesbld=%s",
218: process_id,token,toklen,delim,itbl,nesbld);
219: 
220: /* --- go back for the next token --- */
221: goto next_token;                        /* go back and get next token */
222: }


EEEEEEEEEE DDDDDDDD     SSSSSSS             KKKK    KK BBBBBBBB   DDDDDDDD   NN      NN
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            KKKK   KK  BBBBBBBBB  DDDDDDDDD  NNN     NN
 EE     EE  DD     DD SS                     KK   KK    BB     BB  DD     DD NNNN    NN
 EEEEEE     DD     DD  SSSSSSS               KKKKKK     BBBBBBBB   DD     DD NN NN   NN
 EEEEEE     DD     DD   SSSSSSS              KKKKK      BBBBBBBB   DD     DD NN   NN NN
 EE     EE  DD     DD         SS             KK  KKK    BB     BB  DD     DD NN    NNNN
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ KKKK   KK  BBBBBBBBB  DDDDDDDDD  NN     NNN
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________ KKKK    KK BBBBBBBB   DDDDDDDD   NN      NN

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    kbdnum
  7:  *
  8:  * Purpose:     Converts a keyboard string to numeric values.
  9:  *
 10:  * Call:        kbdnum ( msg_buff, argc, num )
 11:  *
 12:  * Arguments:
 13:  *              msg_buff (I)    addr of char string containing operand
 14:  *                              string to be converted to int numbers.
 15:  *              argc (I)        int containing the number of numbers
 16:  *                              that msg_buff is supposed to represent.
 17:  *                              and terminated by any flag number out of range.
 18:  *              num (O)         addr of int array returning the argc numbers.
 19:  *
 20:  * Returns:     - int           SS$_NORMAL for successful completion,
 21:  *                              VMS error status otherwise.
 22:  *              
 23:  * Notes:
 24:  *
 25:  * Source:      EDS_KBDNUM.C
 26:  *
 27:  * --------------------------------------------------------------------------
 28:  * Revision History:
 29:  *
 30:  * 04/11/86     J.Forkosh       Installation.
 31:  *
 32:  ****************************************************************************/
 33: 
 34: #include stdio
 35: #include ssdef
 36: 
 37: int     kbdnum ( msg_buff, argc, num )
 38: char    *msg_buff;
 39: int     argc;
 40: int     *num;
 41: {
 42: /* -------------------------------------------------------------------------
 43: Allocations and Declarations
 44: -------------------------------------------------------------------------- */
 45: static  char num_str[16],*num_ptr;              /* local copy of msg_buff */
 46: static  char arg2[16];                          /* multiple-argc case */
 47: int     arg1siz;                                /* size of 1st arg */
 48: 
 49: /* --- get local copy of '0'-'9' chars from msg_buff --- */
 50: num_ptr = num_str;                              /* ptr to local buffer */
 51: while ( *msg_buff != '\000' )                   /* loop over msg_buff */
 52:         {                                       /* and range-check it */
 53:         if ( (*msg_buff >= '0') && (*msg_buff <= '9') )
 54:                 *num_ptr++ = *msg_buff;         /* copy numeric chars */
 55:         msg_buff++;                             /* try next input char */
 56:         }
 57: *num_ptr = '\000';                              /* null-terminate local buff */
 58: 
 59: /* --- one arg's simple --- */
 60: if ( argc > 1 ) goto two_args;
 61: *num = atoi(num_str);                           /* convert string */
 62: return ( SS$_NORMAL);                           /* and go home */
 63: 
 64: /* --- note - we only do 1 and 2 args --- */
 65: two_args:
 66: arg1siz = strlen(num_str)/2;                    /* 1st arg is same or less */
 67: strcpy(arg2,num_str+arg1siz);                   /* get 2nd arg */
 68: num_str[arg1siz] = '\000';                      /* num_str is now 1st arg */
 69: *num = atoi(num_str);                           /* convert 1st arg */
 70: *(num+1) = atoi(arg2);                          /* convert 2nd arg */
 71: return ( SS$_NORMAL );                          /* and go home */
 72: }


EEEEEEEEEE DDDDDDDD     SSSSSSS             KKKK    KK BBBBBBBB   DDDDDDDD   XX      XX
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            KKKK   KK  BBBBBBBBB  DDDDDDDDD   XX    XX 
 EE     EE  DD     DD SS                     KK   KK    BB     BB  DD     DD   XX  XX  
 EEEEEE     DD     DD  SSSSSSS               KKKKKK     BBBBBBBB   DD     DD     XX    
 EEEEEE     DD     DD   SSSSSSS              KKKKK      BBBBBBBB   DD     DD     XX    
 EE     EE  DD     DD         SS             KK  KKK    BB     BB  DD     DD   XX  XX  
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ KKKK   KK  BBBBBBBBB  DDDDDDDDD   XX    XX 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________ KKKK    KK BBBBBBBB   DDDDDDDD   XX      XX

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    kbdxlate
  7:  *
  8:  * Purpose:     Translates a keyboard message to internal format.
  9:  *
 10:  * Call:        kbdxlate ( process_id, msglevel, dev_num, dev_sect, kbd_sect )
 11:  *
 12:  * Arguments:
 13:  *              process_id (I)  addr of char string containing process id.
 14:  *
 15:  *              msglevel (I)    int containing printf message level.
 16:  *
 17:  *              dev_num(I)      int containing global device number.
 18:  *
 19:  *              dev_sect (I)    addr of device table global section.
 20:  *
 21:  *              kbd_sect (I)    addr of keyboard table global section.
 22:  *
 23:  * Returns:     - int
 24:  *              SS$_NORMAL      for successful completion,
 25:  *              SS$_status      or error status otherwise.
 26:  *
 27:  * Source:      EDS_KBDXLATE.C
 28:  *
 29:  * --------------------------------------------------------------------------
 30:  * Revision History:
 31:  *
 32:  * 04/08/86     J.Forkosh       Installation.
 33:  *
 34:  ****************************************************************************/
 35: 
 36: #include stdio
 37: #include ssdef
 38: #include "eds$shl:eds_symdef.h"
 39: #include "eds$shl:eds_mbxdef.h"
 40: #include "eds$tcp:eds_tcpdef.h"
 41: #include "eds$shl:eds_dcpdef.h"
 42: #include "eds$lib:eds_devdef.h"
 43: #include "eds$shl:eds_glbdef.h"
 44: #include "eds$shl:eds_opsdef.h"
 45: #include "eds$shl:eds_ops2def.h"
 46: 
 47: int     kbdxlate ( process_id, msglevel, dev_num, dev_sect, kbd_sect )
 48: char    *process_id;
 49: int     msglevel;
 50: int     dev_num;
 51: char    *dev_sect;
 52: char    *kbd_sect;
 53: {
 54: 
 55: /* -------------------------------------------------------------------------
 56: Allocations and Declarations
 57: -------------------------------------------------------------------------- */
 58: char    *sect_ptr();                    /* converts dev# to dev_table ptr */
 59: char    *strchr();                      /* finds a char in a string */
 60: struct  devtable_struct *dev_ptr;       /* ptr to dev_table structure */
 61: struct  dcptable_struct *dcp_ptr;       /* and imbedded dcptable */
 62: struct  glbhdr_struct *kbdhdr;          /* keyboard sect global header */
 63: struct  kbdtbl_struct *kbdtbl;          /* 1st keyboard table */
 64: unsigned char *qio_buff;                /* ptr to raw qio buffer in dcptable */
 65: char    *msg_buff,*crt_buff;            /* ptr to input buff, output buff */
 66: char    *termtbl;                       /* ptr to terminators for prefix ops */
 67: int     qiosiz,msgsiz,kbdsiz,crtsiz, ichar; /* #bytes in, index to buffs*/
 68: int     xlate;                          /* keybd xlation flag */
 69: int     dummy_kbd;                      /* dummy keyboard flag */
 70: static  char kbd_msg[256],token[64];    /* internal buffs for msg,macro */
 71: int     keystroke,ikbd,offset;          /* keystroke, keybd tbl#, xlation */
 72: unsigned char opcode,prev_op,optblcode; /* terminator character/opcode */
 73: int     iop,format,maxsiz;              /* opcode_tbl index,format,maxsiz */
 74: int     inum,argc;                      /* operatormsg num fields */
 75: int     vms_stat;                       /* return stat from system services */
 76: static  char *defkbd,defkbdtbl[]=       /* entitlement for default keybd */
 77:         "0123456789ABCDEF";
 78: 
 79: /* -------------------------------------------------------------------------
 80: Initialization
 81: -------------------------------------------------------------------------- */
 82: /* --- init return status, and keyboard table ptrs --- */
 83: vms_stat = SS$_NORMAL;                  /* init return stat */
 84: kbdhdr= kbd_sect;                       /* keyboard sect starts with glb hdr */
 85: kbdtbl= kbd_sect+glbhdr_size;           /* followed by 5 keyboard tables */
 86: 
 87: /* --- local copies of fields from dev_table --- */
 88: dev_ptr = sect_ptr(dev_sect,dev_num,0); /* struct ptr to devtable */
 89: dcp_ptr = &(dev_ptr->dcptable);         /* and to imbedded dcptable */
 90: ikbd =          dev_ptr->keyboard;      /* keyboard table# in dev_table */
 91: if (ikbd >= 0)  dummy_kbd = FALSE;      /* got a real keyboard number */
 92: else    { dummy_kbd = TRUE; }           /* got a dummy keyboard */
 93: msg_buff =      dev_ptr->msg_buff;      /* (partial) msg buffer in dev_table */
 94: msgsiz =        dev_ptr->msgsiz;        /* #bytes so far in partial msg */
 95: qio_buff =      dev_ptr->qio_buff;      /* qio buffer within devtable struct */
 96: qiosiz =        (int)(dcp_ptr->iosb[1]);/* size of buff before terminator */
 97: iop =           dev_ptr->prefix_opcode; /* non-zero if prefix op pending */
 98: prev_op =       dev_ptr->operatormsg.opcode; /* last opcode */
 99: 
100: if ( msglevel > 99 )                    /* print flow control msg */
101:         printf("\nCRT_%s> (kbdxlate) devnam=%s, qiosiz=%d, qio_buff=%.32s",
102:         process_id,dcp_ptr->devnam,qiosiz,qio_buff);
103: 
104: /* -------------------------------------------------------------------------
105: Now do keyboard translation of msg currently in qio buffer
106: -------------------------------------------------------------------------- */
107: if (qiosiz < dcp_ptr->maxmsg )          /* if we got a terminator interrupt, */
108:         qiosiz++;                       /* then xlate that char too */
109: *kbd_msg = '\000';                      /* start kbd_msg as a null string */
110: kbdsiz = 0;                             /* nothing in the null string */
111: xlate = TRUE;                           /* default to keyboard macro xlation */
112: if ( dummy_kbd ) xlate = FALSE;         /* don't try xlating dummy keyboards */
113: 
114: /* --- xlate the current qio buffer --- */
115: for (ichar=0; ichar < qiosiz; ichar++)  /* for each raw char in the qio_buff */
116:         {
117:         keystroke = *token = qio_buff[ichar]; /* get raw char from buffer */
118:         token[1] = '\000';              /* and null terminate it */
119:         if ( xlate )                    /* do keyboard macro xlation */
120:                 {
121:                 if ( keystroke >=0 && keystroke <= 127 )
122:                   { offset = kbdtbl[ikbd].offset[keystroke]; /* macro offset */
123:                   if ( offset != 0 )            /* got a macro if offset>0 */
124:                         strcpy(token,kbd_sect+offset); } /* xlate to token */
125:                 else { if ( msglevel > 1 )
126:         printf("\nCRT_%s> (kbdxlate) devnam=%s, bad stroke#%d=%d, buff=%.8s",
127:         process_id,dcp_ptr->devnam,ichar,keystroke,qio_buff); }
128:                 }
129:         strcat(kbd_msg,token);          /* and concat token to kbd_msg */
130:         kbdsiz += strlen(token);        /* and bump its length */
131:         if( xlate                       /* if we did xlation */
132:         &&  (*token == EDS$ERSKBD_OP) ) /* and token wants buffer erased */
133:                 {                       /* then we need both buffers cleared */
134:                 *kbd_msg = '\000';      /* so clear current kbd_msg buffer */
135:                 kbdsiz = 0;             /* and set kbdsiz to zero */
136:                 msgsiz = 0;             /* and set msgsiz to clear msg_buff */
137:                 }
138:         if ( kbdsiz + msgsiz > 60       /* don't allow more than 60 chars */
139:         &&   ichar + 2 < qiosiz )       /* unless we're adding terminator */
140:                 ichar = qiosiz - 2;     /* now skip to terminator */
141:         }
142: 
143: /* --- concatanate current qio to end of any previous msg --- */
144: purge_buff:
145: if ( msgsiz < 1 )                       /* see if we have a partial msg */
146:         { msgsiz = 0;                   /* if <1, better be 0 */
147:         *msg_buff = '\000'; }           /* make sure empty buff has a null */
148: kbdsiz = strlen(kbd_msg);               /* length of translated message */
149: if ( msgsiz + kbdsiz > 79 )             /* operator pressed too many keys */
150:         { kbdsiz = 79 - msgsiz;         /* so truncate his input */
151:         if ( kbdsiz < 0 ) kbdsiz = 0;   /* but not too much */
152:         kbd_msg[kbdsiz] = '\000'; }     /* and null-terminate message */
153: msgsiz += kbdsiz;                       /* bump buffer size before concat */
154: if ( msgsiz < 80 )                      /* don't overflow dev_table buffer */
155:         strcat ( msg_buff,kbd_msg );    /* concatanate current msg to buff */
156: else    { msgsiz=0; goto purge_buff; }  /* empty current buff if overflow */
157: dev_ptr->msgsiz = msgsiz;               /* store msgsiz back in dev_table */
158: if ( msgsiz < 1 ) return ( SS$_EOTIN ); /* must have erased entire buffer */
159: 
160: /* -------------------------------------------------------------------------
161: Check last char for opcode
162: -------------------------------------------------------------------------- */
163: /* --- extract opcode from msg_buff (all ops are qio terminators) --- */
164: opcode = msg_buff[msgsiz-1];            /* last msg char may be an opcode */
165: 
166: /* --- now search opcode_tbl for an opcode match --- */
167: if ( dummy_kbd ) {iop=0; goto got_op;}  /* fall through for dummy keyboard */
168: for ( iop=0; (optblcode = opcode_tbl[iop].opcode) != '\000'; iop++ )
169:         if ( opcode == optblcode )      /* got a match */
170:                 {       /* must return for data if we got a prefix opcode */
171:                 if(opcode_tbl[iop].format >= 0  /* this is a postfix op */
172:                 && opcode_tbl[iop].maxsiz >= 0) /* if both are >=0 ... */
173:                         goto got_op;            /* so continue xlation. */
174:                 dev_ptr->prefix_opcode = iop;   /* Got a prefix opcode, so */
175:                 dcp_ptr->maxmsg = opcode_tbl[iop].maxsiz; /* #bytes to read */
176:                 dev_ptr->msgsiz = msgsiz = 0;   /* reset buffer length */
177:                 *msg_buff = '\000';             /* erase buffer for new args */
178:                 }
179: 
180: /* --- no opcode, so get more data (unless we already have a prefix op) --- */
181: if ( dev_ptr->prefix_opcode == 0 )      /* no pending prefix opcode either */
182:         return ( SS$_EOTIN );           /* so it must be partial msg */
183: 
184: /* --- we have a pending prefix op so see if all pending data received --- */
185: iop = dev_ptr->prefix_opcode;           /* set iop as though loop found it */
186: opcode = opcode_tbl[iop].opcode;        /* and set opcode accordingly */
187: maxsiz = opcode_tbl[iop].maxsiz;        /* need this much data for msg */
188: if ( msgsiz < maxsiz )                  /* but we don't have it yet */
189:         return ( SS$_EOTIN );           /* so return for more */
190: 
191: /* --- all pending data for prefix opcode has now been received --- */
192: msg_buff[msgsiz++] = opcode;            /* got entire msg - concat opcode */
193: msg_buff[msgsiz] = '\000';              /* and null-terminate msg */
194: dev_ptr->prefix_opcode = 0;             /* done - reset pending prefix opcode */
195: dcp_ptr->maxmsg = kbdtbl[ikbd].maxmsg;  /* reset qio maxmsg */
196: for ( ichar=0; ichar<32; ichar++ )      /* and termtbl for default keyboard */
197:         dcp_ptr->termtbl[ichar] = kbdtbl[ikbd].termtbl[ichar];
198: 
199: /* -------------------------------------------------------------------------
200: Got a terminating opcode (or buffer for prefix), so xlate completed command
201: -------------------------------------------------------------------------- */
202: got_op:
203: /* --- initialize operatormsg fields --- */
204: dev_ptr->msgsiz = 0;                    /* first reset msgsiz for next msg */
205: if ( !dummy_kbd )                       /* check we have normal keyboard */
206:         dcp_ptr->maxmsg = kbdtbl[ikbd].maxmsg;  /* reset length of qio read */
207: else    dcp_ptr->maxmsg = 32;           /* default maxmsg */
208: dev_ptr->operatormsg.opcode = opcode;   /* give opcode to crt in operatormsg */
209: dev_ptr->operatormsg.string[0]='\000';  /* init the operatormsg string */
210: for ( inum=0; inum<4; inum++)           /* and the 4 possible nums */
211:         dev_ptr->operatormsg.num[inum]=0;
212: 
213: /* --- always put msg in string just to let crt functions have it --- */
214: crt_buff = dev_ptr->operatormsg.string; /* un-xlated msg in string for test */
215: strncpy (crt_buff, msg_buff, msgsiz-1); /* copy input to output */
216: crt_buff[msgsiz-1] = '\000';            /* null terminated */
217: dev_ptr->operatormsg.num[3] = msgsiz-1; /* temp kludge to return len */
218: if ( dummy_kbd ) return(vms_stat);      /* skip processing if dummy keyboard */
219: 
220: /* --- see if we need any operands, and use default string if necessary --- */
221: if ((format=opcode_tbl[iop].format)==0) /* get msg format from opcode_tbl */
222:         goto no_args;                   /* skip arg processing if no args */
223: msg_buff[--msgsiz] = '\000';            /* strip opcode from end of msg_buff */
224: if ( msgsiz < 1 )                       /* if we got no operands */
225:         {                               /* so use the default operand */
226:         strcpy(msg_buff,opcode_tbl[iop].defstr); /* get default from tbl */
227:         msgsiz = strlen(msg_buff);      /* and reset the length */
228:         }
229: 
230: /* --- get rid of excess chars --- */
231: if(msgsiz>(maxsiz=opcode_tbl[iop].maxsiz)) /* check msgsiz against maxsiz */
232:         strcpy(msg_buff,msg_buff+msgsiz-maxsiz); /* and prune excess chars */
233: 
234: /* --- for normal opcodes, just convert operand string to ints --- */
235: if ( format < 10 )                      /* format >=10 indicates special op */
236:         {                                       /* call kbdnum to convert */
237:         argc = (format>0)? format: -format;     /* argc is iabs(format) */
238:         if ( (vms_stat =  kbdnum(msg_buff,argc,dev_ptr->operatormsg.num))
239:         != SS$_NORMAL )                         /* check convert went ok */
240:                 return ( vms_stat );            /* and return if not */
241:         }
242: 
243: /* --- string copy --- */
244: if ( format == 11 )                     /* format 11 for string input */
245:         {                                       /* copy msg_buff to string */
246:         strcpy(dev_ptr->operatormsg.string,msg_buff);
247:         }
248: 
249: /* --- select race --- */
250: if ( format == 10 )
251:         {                               /* format 10 for nesid source keys */
252:         if ( (vms_stat =
253:         kbdnes(process_id,msglevel,opcode,msg_buff,dev_ptr)) /* xlate nesid */
254:         != SS$_NORMAL )                         /* return error if xlate ng */
255:                 return ( vms_stat );
256:         }
257: 
258: /* --- check for special processing --- */
259: no_args:                                /* target to skip arg processing */
260: inum = dev_ptr->operatormsg.num[0];     /* we'll usually need this so get it */
261: switch ( opcode )                       /* special processing is by opcode */
262:         {
263:                                         /* switch default keybd */
264:         case EDS$CTRLMODE_OP:   inum=0; goto select_kbd;
265:         case EDS$DISPMODE_OP:   inum=1; goto select_kbd;
266:         case EDS$UPDTMODE_OP:   inum=2; goto select_kbd;
267:         select_kbd:                     /* default keybd from entitlements */
268:                 if ( inum >= strlen(dev_ptr->entitlements) ) break;
269:                 if ( (defkbd=strchr(defkbdtbl,dev_ptr->entitlements[inum]))
270:                 == 0 ) break;                   /* not entitled to this mode */
271:                 ikbd = defkbd-defkbdtbl;        /* index within defkbdtbl */
272:                 goto  switch_kbd;               /* go flip keyboard */
273:                 break;
274: 
275:         case EDS$CHGKBD_OP:             /* request to change keyboard */
276:                 ikbd = inum;                    /* num[0] is the keyboard# */
277:         switch_kbd:                     /* code to flip devtbl to ikbd */
278:                 dev_ptr->keyboard = ikbd;       /* so flip it in devtable */
279:                 dcp_ptr->maxmsg = kbdtbl[ikbd].maxmsg; /* ditto for maxmsg */
280:                 for ( ichar=0; ichar<32; ichar++ ) /* and ditto for termtbl */
281:                         dcp_ptr->termtbl[ichar] = kbdtbl[ikbd].termtbl[ichar];
282:                 break;
283: 
284:         default:                        /* leave other opcodes alone */
285:                 break;
286:         }
287: return ( vms_stat );
288: }


EEEEEEEEEE DDDDDDDD     SSSSSSS             RRRRRRRR   DDDDDDDD     CCCCCCC  RRRRRRRR  
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            RRRRRRRRR  DDDDDDDDD   CCCCCCCCC RRRRRRRRR 
 EE     EE  DD     DD SS                     RR     RR  DD     DD CC      CC  RR     RR
 EEEEEE     DD     DD  SSSSSSS               RRRRRRRR   DD     DD CC          RRRRRRRR 
 EEEEEE     DD     DD   SSSSSSS              RRRRRRR    DD     DD CC          RRRRRRR  
 EE     EE  DD     DD         SS             RR   RR    DD     DD CC      CC  RR   RR  
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________  RR    RR  DDDDDDDDD   CCCCCCCCC  RR    RR 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________  RR     RR DDDDDDDD     CCCCCCC   RR     RR

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    rdcrtmbx
  7:  *
  8:  * Purpose:     Waits for a message from the CRT task's request queue mailbox,
  9:  *              then translates and returns it.
 10:  *
 11:  * Call:        rdcrtmbx ( process_id, msglevel, chan, dev_sect, kbd_sect,
 12:  *              opcode, msgbuff )
 13:  *
 14:  * Arguments:
 15:  *              process_id (I)  addr of char string containing process_id.
 16:  *
 17:  *              msglevel (I)    int containing message level,
 18:  *                              which determines amount of printing.
 19:  *
 20:  *              chan (I)        int containing mailbox channel.
 21:  *
 22:  *              dev_sect (I)    addr of device table global section.
 23:  *
 24:  *              kbd_sect (I)    addr of keyboard table global section.
 25:  *
 26:  *              opcode (O)      addr of 1-character string returning
 27:  *                              EDS operation code.
 28:  *
 29:  *              msgbuff (O)     addr of char string returning mailbox buffer.
 30:  *
 31:  * Returns:     - int
 32:  *              SS$_NORMAL      for successful completion,
 33:  *              SS$_status      or error status otherwise.
 34:  *
 35:  * Source:      EDS_RDCRTMBX.C
 36:  *
 37:  * --------------------------------------------------------------------------
 38:  * Revision History:
 39:  *
 40:  * 03/21/86     J.Forkosh       Installation.
 41:  *
 42:  ****************************************************************************/
 43: 
 44: #include stdio
 45: #include ssdef
 46: #include "eds$shl:eds_symdef.h"
 47: #include "eds$shl:eds_mbxdef.h"
 48: #include "eds$tcp:eds_tcpdef.h"
 49: #include "eds$shl:eds_dcpdef.h"
 50: #include "eds$lib:eds_devdef.h"
 51: #include "eds$shl:eds_opsdef.h"
 52: 
 53: int     rdcrtmbx ( process_id, msglevel, chan, dev_sect, kbd_sect,
 54:         opcode, msgbuff )
 55: char    *process_id;
 56: int     msglevel;
 57: int     chan;
 58: char    *dev_sect;
 59: char    *kbd_sect;
 60: char    *opcode;
 61: char    *msgbuff;
 62: {
 63: 
 64: /* -------------------------------------------------------------------------
 65: Allocations and Declarations
 66: -------------------------------------------------------------------------- */
 67: struct  mbxmsghdr_struct *buffer;       /* mbx msg struct ptr */
 68: int     msglen;                         /* length of mbx buffer */
 69: struct  crtmsghdr_struct *crtmsg;       /* used to get fields from crtmsg */
 70: struct  devtable_struct *dev_ptr;       /* ptr to device table structure */
 71: struct  dcptable_struct *dcp_ptr;       /* and to imbedded dcptable */
 72: char    *sect_ptr();                    /* converts device # to struct ptr */
 73: char    partner_id[4],ack_op[4];        /* process that sent msg, and ack */
 74: int     qiolen,ichar;                   /* length,index to qio_buff */
 75: int     partial_msg;                    /* if true, get another mbx msg */
 76: int     issue_ack;                      /* usually false - lets crt ack msg */
 77: int     vms_stat;                       /* return stat from system services */
 78: 
 79: /* -------------------------------------------------------------------------
 80: Wait for message from a partner process
 81: -------------------------------------------------------------------------- */
 82: next_msg:
 83: /* --- get the next mailbox message --- */
 84: buffer = msgbuff;                       /* read mbx msg into caller's space */
 85: partial_msg = FALSE;                    /* assume we'll get complete msg */
 86: issue_ack = FALSE;                      /* and assume crt will ack the msg */
 87: if ( (vms_stat = readmbxw(chan, MBX_MAXMSG, buffer, &msglen))
 88: != SS$_NORMAL )
 89:         {                               /* can't read mailbox */
 90:         if ( msglevel > 0 )             /* print error message */
 91:                 printf ("\nCRT_%s> (rdcrtmbx) readmbxw err=%s",
 92:                 process_id,vmsmsg(vms_stat));
 93:         return ( vms_stat );            /* and return error code to caller */
 94:         }
 95: 
 96: /* --- extract the opcode and init ptrs --- */
 97: *opcode = buffer->opcode;               /* opcode returned as separate arg */
 98: opcode[1] = '\000';                     /* null-terminated */
 99: *partner_id = buffer->process_id;       /* process_id of partner sending msg */
100: partner_id[1] = '\000';                 /* null-terminated */
101: crtmsg = buffer;                        /* try to address input as a crtmsg */
102: strcpy ( ack_op,"a" );                  /* assume we'll ack the message */
103: dev_ptr = 0;                            /* default assumes msg has no device */
104: if ( *opcode == EDS$_INITMSG            /* but these msgs have a device */
105: ||   *opcode == EDS$_MSG )
106:         { dev_ptr= sect_ptr(dev_sect,crtmsg->dev_num,0); /* ptr to dev */
107:         dcp_ptr= &(dev_ptr->dcptable); }        /* and imbedded dcptable */
108: 
109: /* --- print a flow control message --- */
110: if ( msglevel > 9 )
111: { if ( dev_ptr != 0 )                   /* this msg is coupled to a device */
112: printf("\nCRT_%s> (rdcrtmbx) tcp_id=%s, device#%d=%s, msgseq#%d, opcode=%d,\n\
113:         (cont.) qiosiz=%d, qio_buff=<%.32s>",
114: process_id,partner_id,crtmsg->dev_num,dcp_ptr->devnam,crtmsg->msgseqnum,
115: *opcode,dcp_ptr->iosb[1],dev_ptr->qio_buff);
116: else                                    /* no device - minimal print */
117: printf("\nCRT_%s> (rdcrtmbx) partner_id=%s, msgseq#%d, opcode=%d",
118: process_id,partner_id,crtmsg->msgseqnum,*opcode);
119: }
120: 
121: /* -------------------------------------------------------------------------
122: Handle the message according to its opcode ...
123: -------------------------------------------------------------------------- */
124: switch ( *opcode )
125:         {
126: 
127: /* -------------------------------------------------------------------------
128: tcp messages - init device
129: -------------------------------------------------------------------------- */
130:         case EDS$_INITMSG:      /* ack-ing init msg posts the first qio */
131:         if ( (vms_stat = devtblinit             /* call to init dev */
132:         (process_id, msglevel,crtmsg->dev_num, dev_sect, kbd_sect))
133:         != SS$_NORMAL )                         /* nak if can't init */
134:                 strcpy( ack_op,"n" );   /* set for a nak */
135:         break;
136: 
137: /* -------------------------------------------------------------------------
138: tcp messages - msg from a device
139: -------------------------------------------------------------------------- */
140:         case EDS$_MSG:          /* interpret the operator msg and ack it */
141: /* --- Now handle message according to class of device (terminal or vid) --- */
142:         switch ( dev_ptr->device_class)
143:                 {
144:                 /* --- Xlate message from an operator's keyboard --- */
145:                 case TERMINAL:  /* call kbdxlate() for the actual xlation */
146:                 if ( (vms_stat=kbdxlate
147:                 (process_id,msglevel,crtmsg->dev_num,dev_sect,kbd_sect))
148:                 == SS$_EOTIN )                  /* we only got a partial msg */
149:                         partial_msg = TRUE;     /* so set partial msg flag */
150:                 break;                          /* and now issue another qio */
151: 
152:                 /* --- VID or CONTROL msg - just copy buffer to string --- */
153:                 case VIDEO:
154:                 case CONTROL:
155:                 default:
156:                 qiolen = dcp_ptr->iosb[1];      /* qio_buff len */
157:                 if ( qiolen < dcp_ptr->maxmsg ) /* must have a terminator */
158:                         qiolen++;               /* so include terminator */
159:                 if ( qiolen>80 ) qiolen=80;     /* check max msg size */
160: 
161:                 /* --- copy length and msg to operatormsg struct --- */
162:                 dev_ptr->operatormsg.opcode = EDS$VIDDEV_OP;    /* opcode */
163:                 dev_ptr->operatormsg.num[0] = qiolen;   /* return msg len */
164:                 for ( ichar=0; ichar < qiolen; ichar++ ) /* and buffer */
165:                         dev_ptr->operatormsg.string[ichar] =
166:                         dcp_ptr->qio_buff[ichar];
167:                 vms_stat = SS$_NORMAL;                  /* return ok stat */
168:                 break;
169:                 }
170:         break;
171: 
172: /* -------------------------------------------------------------------------
173: exit msg, autoupdate msg, etc.
174: -------------------------------------------------------------------------- */
175:         case EDS$_EXITMSG:              /* nothing to do for exit msgs */
176:         break;
177: 
178:         default:                        /* let crt deal with anything else */
179:         break;
180:         }
181: 
182: /* -------------------------------------------------------------------------
183: Done, either return complete msg to caller or wait for more.
184: -------------------------------------------------------------------------- */
185: /* --- always ack then go back for more --- */
186: if ( partial_msg )
187:         {                               /* only got part of a msg, so ... */
188:         ackmsg( process_id,msglevel,ack_op,crtmsg ); /* need more input */
189:         goto next_msg;                  /* get complete msg before returning */
190:         }
191: /* --- return to caller --- */
192: if ( issue_ack )                        /* usually flase - crt usually acks */
193:         ackmsg( process_id,msglevel,ack_op,crtmsg );    /* we'll ack msg */
194: return ( vms_stat );
195: }


EEEEEEEEEE DDDDDDDD     SSSSSSS               SSSSSSS  TTTTTTTTTT   OOOOOO   KKKK    KK
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             SSSSSSSSS TTTTTTTTTT  OOOOOOOO  KKKK   KK 
 EE     EE  DD     DD SS                    SS         TT  TT  TT OO      OO  KK   KK  
 EEEEEE     DD     DD  SSSSSSS               SSSSSSS       TT     OO      OO  KKKKKK   
 EEEEEE     DD     DD   SSSSSSS               SSSSSSS      TT     OO      OO  KKKKK    
 EE     EE  DD     DD         SS                    SS     TT     OO      OO  KK  KKK  
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ SSSSSSSSS     TTTT     OOOOOOOO  KKKK   KK 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________  SSSSSSS      TTTT      OOOOOO   KKKK    KK

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    storestruct
  7:  *
  8:  * Purpose:     KBD initialization routine to store rms file information
  9:  *              into the keyboard table area
 10:  *
 11:  * Call:        storestruct ( process_id, msglevel, istruct,
 12:  *              itoken, token, eds_struct )
 13:  *
 14:  * Arguments:
 15:  *              process_id (I)          addr of char string containing
 16:  *                                      identification of calling process
 17:  *
 18:  *              msglevel (I)            int containing the message level
 19:  *
 20:  *              istruct (I)             int index into devtable structure
 21:  *                                      array
 22:  *
 23:  *              itoken (I)              int containing token number
 24:  *
 25:  *              token (I)               addr of char string containing token
 26:  *
 27:  *              eds_struct (O)          addr of structure returning
 28:  *                                      the initialization information
 29:  *
 30:  * Notes:       The format of the rms file is one of the following - 
 31:  *              KEYBOARD / keyboard# (0-4)
 32:  *              MAXMSG / maxmsg (max bytes per qio)
 33:  *              keystroke chars / translation string
 34:  *
 35:  * Returns:     -int                    SS$_NORMAL for successful completion.
 36:  *
 37:  * Source:      EDS_STOREKBD.C
 38:  *
 39:  * --------------------------------------------------------------------------
 40:  * Revision History:
 41:  *
 42:  * 04/07/86     J.Forkosh       Installation.
 43:  *
 44:  ****************************************************************************/
 45: 
 46: #include stdio
 47: #include ssdef
 48: #include "eds$shl:eds_symdef.h"
 49: #include "eds$shl:eds_glbdef.h"
 50: #include "eds$shl:eds_opsdef.h"
 51: #include "eds$shl:eds_ops2def.h"
 52: #define getbit(x,bit) ( (x >>bit) & 1 )
 53: #define setbit(x,bit) ( x |= (1<< bit) )
 54: #define clrbit(x,bit) ( x &= ~(1<< bit) )
 55: #define getlongbit(x,bit) getbit(*(x+bit/8),bit%8)
 56: #define setlongbit(x,bit) setbit(*(x+bit/8),bit%8)
 57: #define clrlongbit(x,bit) clrbit(*(x+bit/8),bit%8)
 58: 
 59: storestruct ( process_id, msglevel, istruct, itoken, token, eds_struct )
 60: char    *process_id;
 61: int     msglevel;
 62: int     istruct;
 63: int     itoken;
 64: char    *token;
 65: char    *eds_struct;
 66: {
 67: /* -------------------------------------------------------------------------
 68: Allocations and Declarations
 69: -------------------------------------------------------------------------- */
 70: static  int     ncalls = 0;             /* first call does initialization */
 71: static  int     opcode;                 /* first card field may be opcode */
 72: static  int     ikbd;                   /* from KEYBOARD/# card */
 73: static  unsigned char keystrokes[32];   /* operator keys to be translated */
 74: static  int     offset;                 /* next free spot in table */
 75: static  struct  glbhdr_struct *glbhdr;  /* global header */
 76: static  struct  kbdtbl_struct *kbdtbl;  /* 1st keyboard table */
 77: int     istroke,ichar,icode;            /* indexes into token, opcode_tbl */
 78: 
 79: /* -------------------------------------------------------------------------
 80: Initialization
 81: -------------------------------------------------------------------------- */
 82: if ( ncalls++ == 0 )
 83:         {
 84:         glbhdr= eds_struct;             /* global sect starts with hdr */
 85:         kbdtbl= eds_struct+glbhdr_size; /* followed by 5 keyboard tables */
 86:         offset= glbhdr->offset1;        /* free area for xlate strings */
 87:         ikbd = 0;                       /* default to 1st table */
 88:         }
 89: 
 90: /* -------------------------------------------------------------------------
 91: Move fields to struct
 92: -------------------------------------------------------------------------- */
 93: switch ( itoken )
 94: {
 95: 
 96: case 0:                 /* (char[]) opcode or (char) keystroke */
 97:         opcode = 0;                     /* first assume it's a keystroke */
 98:         strcpy(keystrokes,token);       /* keep the keystrokes to be xlated */
 99:         if (!strcmp(token,"KEYBOARD"))  /* nope - it was a KEYBOARD command */
100:                 opcode = 1;             /* so flip opcode to keyboard# */
101:         if (!strcmp(token,"MAXMSG"))    /* nope - it was a MAXMSG command */
102:                 opcode = 2;             /* so flip opcode to maxmsg */
103:         break;
104: 
105: case 1:                 /* keyboard# or xlate string */
106:         switch ( opcode )
107:         {
108:         case 0:
109:                 /* --- copy the token and bump offset --- */
110:                 strcpy( eds_struct+offset, token ); /* copy the token */
111:                 for (istroke=0; istroke < strlen(keystrokes); istroke++)
112:                         kbdtbl[ikbd].offset[(int)keystrokes[istroke]] = offset;
113:                 offset += strlen(token) + 1;
114:                 /* --- check token for opcode and set terminator if so --- */
115:                 for(ichar=0; ichar < strlen(token); ichar++)
116:                 for(icode=0; opcode_tbl[icode].opcode != '\000'; icode++)
117:                         {       /* loop over each char in token, each opcode */
118:                         if ( token[ichar] == opcode_tbl[icode].opcode )
119:                                 {       /* got a match, so set terminator */
120:                                 for ( istroke=0; istroke < strlen(keystrokes);
121:                                 istroke++)
122:                                         setlongbit(kbdtbl[ikbd].termtbl,
123:                                         (int)keystrokes[istroke]);
124:                                 goto endcase0;
125:                                 }
126:                         }
127:                 endcase0:
128:                 break;
129:         case 1:
130:                 ikbd = atoi(token);             /* change keyboard */
131:                 kbdtbl[ikbd].maxmsg = 16;       /* re-init maxmsg to 16 */
132:                 for (ichar=0;ichar<32;ichar++)  /* re-init to no terminators */
133:                         kbdtbl[ikbd].termtbl[ichar] = '\000';
134:                 break;
135:         case 2:
136:                 kbdtbl[ikbd].maxmsg = atoi(token);      /* explicit maxmsg */
137:                 break;
138:         default:break;
139:         }
140: default:break;          /* skip extra tokens */
141: }
142: return(SS$_NORMAL);
143: }


EEEEEEEEEE DDDDDDDD     SSSSSSS               SSSSSSS  TTTTTTTTTT   OOOOOO   TTTTTTTTTT
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS             SSSSSSSSS TTTTTTTTTT  OOOOOOOO  TTTTTTTTTT
 EE     EE  DD     DD SS                    SS         TT  TT  TT OO      OO TT  TT  TT
 EEEEEE     DD     DD  SSSSSSS               SSSSSSS       TT     OO      OO     TT    
 EEEEEE     DD     DD   SSSSSSS               SSSSSSS      TT     OO      OO     TT    
 EE     EE  DD     DD         SS                    SS     TT     OO      OO     TT    
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________ SSSSSSSSS     TTTT     OOOOOOOO     TTTT   
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________  SSSSSSS      TTTT      OOOOOO      TTTT   

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Function:    storestruct
  7:  *
  8:  * Purpose:     TCP initialization routine to store rms file information
  9:  *              into devtable_struct.
 10:  *
 11:  * Call:        storestruct ( process_id, msglevel, istruct,
 12:  *              itoken, token, eds_struct )
 13:  *
 14:  * Arguments:
 15:  *              process_id (I)          addr of char string containing
 16:  *                                      identification of calling process
 17:  *
 18:  *              msglevel (I)            int containing the message level
 19:  *
 20:  *              istruct (I)             int index into devtable structure
 21:  *                                      array
 22:  *
 23:  *              itoken (I)              int containing token number
 24:  *
 25:  *              token (I)               addr of char string containing token
 26:  *
 27:  *              eds_struct (O)          addr of structure returning
 28:  *                                      the initialization information
 29:  *
 30:  * Notes:       The format of the rms file is - 
 31:  *              devnam / cluster / class / type / ident / state / entitl / mode
 32:  *
 33:  * Returns:     -int                    SS$_NORMAL for successful completion.
 34:  *
 35:  * Source:      EDS_STOTCP.C
 36:  *
 37:  * --------------------------------------------------------------------------
 38:  * Revision History:
 39:  *
 40:  * 05/01/86     J.Forkosh       Installation.
 41:  *
 42:  ****************************************************************************/
 43: 
 44: /* -------------------------------------------------------------------------
 45: Conditional compilation switches
 46: -------------------------------------------------------------------------- */
 47: #define GLOBAL_TABLE "remove this stmt if devtable is not in a global section"
 48: 
 49: #include stdio
 50: #include ssdef
 51: #include "eds$shl:eds_symdef.h"
 52: #include "eds$shl:eds_mbxdef.h"
 53: #include "eds$tcp:eds_tcpdef.h"
 54: #include "eds$shl:eds_dcpdef.h"
 55: #include "eds$lib:eds_devdef.h"
 56: 
 57: /* --- Translate mnemonic fields to actual values --- */
 58: struct  { char *mnemonic; int value; }
 59:         xlate[]={{"TERMINAL",   TERMINAL },
 60:                 { "VIDEO",      VIDEO },
 61:                 { "CONTROL",    CONTROL },
 62:                 { "CHYRON",     CHYRON },
 63:                 { "DUBNER",     DUBNER },
 64:                 { "VIDIFONT",   VIDIFONT },
 65:                 { "ABEKAS",     ABEKAS },
 66:                 { "CRT",        CRT },
 67:                 { "VT100",      VT100 },
 68:                 { "VT200",      VT200 },
 69:                 { "HAZELTINE",  HAZELTINE },
 70:                 { "RCA",        RCA },
 71:                 { "",           0 }};
 72: 
 73: storestruct ( process_id, msglevel, istruct, itoken, token, eds_struct )
 74: char    *process_id;
 75: int     msglevel;
 76: int     istruct;
 77: int     itoken;
 78: char    *token;
 79: struct  devtable_struct *eds_struct;
 80: {
 81: /* -------------------------------------------------------------------------
 82: Allocations and Declarations
 83: -------------------------------------------------------------------------- */
 84: int     imnem;                  /* index into mnemonic xlate table */
 85: int     value;                  /* xlated value of mnemonic */
 86: struct  dcptable_struct *dcp_ptr;       /* device info imbedded in devtable */
 87: 
 88: /* -------------------------------------------------------------------------
 89: Get the DCP pointer
 90: -------------------------------------------------------------------------- */
 91: dcp_ptr =                               /* ptr to imbedded dcptable struct */
 92: #ifdef GLOBAL_TABLE
 93:         &(eds_struct->dcptable);        /* eds_struct is a single struct */
 94: #else
 95:         &(eds_struct[istruct].dcptable);/* it's an array of structs */
 96: #endif
 97: 
 98: /* -------------------------------------------------------------------------
 99: Look for a mnemonic xlation, or just convert token to int.
100: -------------------------------------------------------------------------- */
101: value = atoi(token);            /* init for no xlation */
102: if ( strlen(token) > 2 )        /* must give at least 3 chars for xlation */
103:         for ( imnem=0; strlen(xlate[imnem].mnemonic) > 0; imnem++ )
104:                 {                       /* check first 3 chars of each token */
105:                 if ( !strncmp(xlate[imnem].mnemonic,token,3) )
106:                         {               /* got a match with mnemonic, so ... */
107:                         value = xlate[imnem].value;     /* set xlated value */
108:                         break;                          /* get out of loop */
109:                         }
110:                 }                       /* try next mnemonic */
111: 
112: /* -------------------------------------------------------------------------
113: Move fields to struct
114: -------------------------------------------------------------------------- */
115: if ( strlen(token) > 0 )        /* leave defaults in table */
116:         switch ( itoken )
117:                 {
118:                 case 0:                 /* (char[]) devnam */
119:                         strcpy(dcp_ptr->devnam,token);
120:                         dcp_ptr->efn = 0;
121:                         dcp_ptr->acmode = 0;
122:                         dcp_ptr->timeout = 0;
123:                         dcp_ptr->re_arm = FALSE;
124:                         dcp_ptr->maxmsg = 3;
125:                         eds_struct->devmode[0]='\0';    /* init */
126:                         break;
127:                 case 1:                 /* (char) control_unit */
128:                         eds_struct->control_unit = *token;
129:                         break;
130:                 case 2:                 /* (int) device_class */
131:                         eds_struct->device_class = value;
132:                         break;
133:                 case 3:                 /* (int) device_type */
134:                         eds_struct->device_type = value;
135:                         break;
136:                 case 4:                 /* (char) device_ident */
137:                         eds_struct->device_ident = *token;
138:                         break;
139:                 case 5:                 /* (int) device_state */
140:                         eds_struct->device_state = value;
141:                         break;
142:                 case 6:                 /* (char[8]) entitlements */
143:                         strcpy(eds_struct->entitlements,token);
144:                         break;
145:                 case 7:                 /* (char[]) devmode */
146:                         strcpy(eds_struct->devmode,token);
147:                         break;
148:                 default:break;          /* skip extra tokens */
149:                 }
150: return(SS$_NORMAL);
151: }


EEEEEEEEEE DDDDDDDD     SSSSSSS             TTTTTTTTTT   CCCCCCC  PPPPPPPP   DDDDDDDD  
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            TTTTTTTTTT  CCCCCCCCC PPPPPPPPP  DDDDDDDDD 
 EE     EE  DD     DD SS                    TT  TT  TT CC      CC  PP     PP  DD     DD
 EEEEEE     DD     DD  SSSSSSS                  TT     CC          PPPPPPPP   DD     DD
 EEEEEE     DD     DD   SSSSSSS                 TT     CC          PPPPPPP    DD     DD
 EE     EE  DD     DD         SS                TT     CC      CC  PP         DD     DD
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________    TTTT     CCCCCCCCC PPPP       DDDDDDDDD 
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________    TTTT      CCCCCCC  PPPP       DDDDDDDD  

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Include:     eds_tcpdef.h
  7:  *
  8:  * Purpose:     Defines TCP structures and message formats,
  9:  *              and various symbols.
 10:  *
 11:  * Notes:
 12:  *
 13:  * Source:      EDS_TCPDEF.H
 14:  *
 15:  * --------------------------------------------------------------------------
 16:  * Revision History:
 17:  *
 18:  * 03/19/86     J.Forkosh       Installation.
 19:  *
 20:  ****************************************************************************/
 21: 
 22: #define TCP_MAXMSG 2048
 23: #define TCP_BUFQUO 8192
 24: #define TCP_PAGCNT 32
 25: #define MAXAST_COUNT 6
 26: 
 27: /* ------------------------------- End-of-File ---------------------------- */


EEEEEEEEEE DDDDDDDD     SSSSSSS             TTTTTTTTTT   CCCCCCC  PPPPPPPP   MM      MM
EEEEEEEEEE DDDDDDDDD   SSSSSSSSS            TTTTTTTTTT  CCCCCCCCC PPPPPPPPP  MMM    MMM
 EE     EE  DD     DD SS                    TT  TT  TT CC      CC  PP     PP MMMM  MMMM
 EEEEEE     DD     DD  SSSSSSS                  TT     CC          PPPPPPPP  MM MMMM MM
 EEEEEE     DD     DD   SSSSSSS                 TT     CC          PPPPPPP   MM  MM  MM
 EE     EE  DD     DD         SS                TT     CC      CC  PP        MM      MM
EEEEEEEEEE DDDDDDDDD  SSSSSSSSS  __________    TTTT     CCCCCCCCC PPPP       MM      MM
EEEEEEEEEE DDDDDDDD    SSSSSSS   __________    TTTT      CCCCCCC  PPPP       MM      MM

  1: /****************************************************************************
  2:  *
  3:  * Copyright (c) 1986, John Forkosh Associates, Inc.  All rights reserved.
  4:  * --------------------------------------------------------------------------
  5:  *
  6:  * Program:     eds_tcpmain
  7:  *
  8:  * Purpose:     EDS Terminal Control Program.
  9:  *              Front end of EDS system that issues system service calls
 10:  *              to perform all asynchronous I/O to terminal devices,
 11:  *              video devices, keyers, switchers, etc.
 12:  *
 13:  * Call:        $ tcp "tcpid" "crtid" "dev_file" ["msglevel"]
 14:  *              (where $tcp :== $sys$sysdevice:[]eds_tcpmain.exe
 15:  *              has been installed as a foreign command)
 16:  *
 17:  * Arguments:
 18:  *              tcpid (I)       first command-line arg is always process_id
 19:  *
 20:  *              crtid (I)       id of partner crt process
 21:  *
 22:  *              dev_file (I)    name of file defining our asynchronous devices
 23:  *
 24:  *              msglevel (I)    last arg is always optional message level
 25:  *
 26:  * Source:      EDS_TCPMAIN.C
 27:  *
 28:  * --------------------------------------------------------------------------
 29:  * Revision History:
 30:  *
 31:  * 05/01/86     J.Forkosh       Installation.
 32:  *
 33:  ****************************************************************************/
 34: 
 35: /* -------------------------------------------------------------------------
 36: Generic include files
 37: -------------------------------------------------------------------------- */
 38: #include stdio
 39: #include ssdef
 40: /* --- symdef, mbxdef, glbdef are the minimum set of EDS include files --- */
 41: #include "eds$shl:eds_symdef.h"
 42: #include "eds$shl:eds_mbxdef.h"
 43: #include "eds$shl:eds_glbdef.h"
 44: /* --- additional application-specific include files for TCP --- */
 45: #include "eds$shl:eds_dcpdef.h"
 46: #include "eds$tcp:eds_tcpdef.h"
 47: #include "eds$lib:eds_devdef.h"
 48: 
 49: /* -------------------------------------------------------------------------
 50: Application-dependent defines (_ARG defines are used to interpret command line)
 51: -------------------------------------------------------------------------- */
 52: #define GLOBAL_TABLE "remove this stmt if devtable is not in a global section"
 53: #define EVENT_CLUSTER "remove this stmt if event flags not used"
 54: #define PROGRAM_ID "TCP_"
 55: #define MIN_ARGC 4
 56: #define MAX_ARGC 5
 57: #define PID_ARGS "1"
 58: #define MBX_ARGS "2"
 59: #define RMS_ARGS "3"
 60: #define PID_MAXMSG TCP_MAXMSG           /* max bytes per mailbox message */
 61: #define PID_BUFQUO TCP_BUFQUO           /* total bytes per mailbox buffer */
 62: #define PID_PAGCNT GLB_PAGCNT           /* number pages per global section */
 63: char *instructions[] =                  /* print these for wrong argc count */
 64:         {
 65:         "Usage: $ tcp \"process_id\" \"crt_id\" \"rms_file\" [\"msglevel\"]",
 66:         ""
 67:         };
 68: 
 69: 
 70: /* -------------------------------------------------------------------------
 71: Global variables for DCP application (available to in-line AST routines)
 72: -------------------------------------------------------------------------- */
 73: char    dcpid[8],edsid[8];              /* local copies of process id's */
 74: int     dcpchan,edschan;                /* mailbox chans */
 75: int     total_asts;                     /* total pending ast's for all devs */
 76: int     dcp_msglevel;                   /* message level for dcp printf's */
 77: /* -------------------------- Event Flag Table --------------------------- */
 78: int     efn_table[] =
 79:                 {
 80:                 0,                      /* to be filled in with process_id */
 81:                 255                     /* illegal efn terminates table */
 82:                 } ;
 83: /* ------------------------- AST Routines Table -------------------------- */
 84: int     tcp_ast();                      /* AST for device control program */
 85: int     ast_table[] =
 86:                 {
 87:                 &tcp_ast,
 88:                 0                       /* zero address terminates table */
 89:                 } ;
 90: /* ----------------------------------------------------------------------- */
 91: 
 92: main ( argc, argv )
 93: int     argc;
 94: char    *argv[];
 95: {
 96: /* -------------------------------------------------------------------------
 97: Allocations and Declarations for TCP-specific application variables
 98: -------------------------------------------------------------------------- */
 99: struct  tcpmsg_struct *tcpmsg;          /* mailbox msg from CRT */
100: struct  crtmsg_struct crtmsg;           /* mailbox msg to CRT (for dev init) */
101: struct  crtmsghdr_struct devinitmsg;    /* device initialization msg to CRT */
102: 
103: /* -------------------------------------------------------------------------
104: Beginning of executable code ...
105: -------------------------------------------------------------------------- */
106: #include "eds$shl:eds_dcpshell.h"       /* first execute the Shells */
107: tcpmsg = mbx_buff;                      /* interpret mbx msgs in tcp format */
108: 
109: /* -------------------------------------------------------------------------
110: Application-specific loop to finish any remaining initialization
111: -------------------------------------------------------------------------- */
112: /* --- loop over all the devices obtained from the readfile call --- */
113: for ( idev=0; idev < ndev; idev++ )
114:         {               /* begin device initialization for loop */
115:         if ( (dev_ptr = dev_tbl[idev]) == 0 )   /* pull out a single ptr */
116:                 continue;                       /* skip an empty slot */
117:         dcp_ptr = &(dev_ptr->dcptable);         /* dcptable is in devtable */
118: 
119: /* --- application-specific code goes here --- */
120:         if ( !dcp_ptr->assigned ) continue;     /* nothing if not assigned */
121:         dcp_ptr->qio_buff = dev_ptr->qio_buff;  /* qio_buff is in devtable */
122:         dev_ptr->keyboard = 0;                  /* default keyboard number */
123:         dev_ptr->crtmsg.process_id= *dcpid;     /* init constant fields... */
124:         dev_ptr->crtmsg.dev_num=dcp_ptr->devnum;/* ...in the crtmsg */
125: 
126: /* --- let partner crt process know that the device is assigned --- */
127:         devinitmsg.process_id = *dcpid; /* set up initmsg for CRT */
128:         devinitmsg.opcode = EDS$_INITMSG;       /* init opcode */
129:         devinitmsg.msgseqnum = getseqnum();     /* sequence number */
130:         devinitmsg.dev_num = dcp_ptr->devnum;   /* index to global sect */
131:         devinitmsg.bufflen = 0;                 /* no buffer */
132:         if ( (vms_stat = wrtmbx         /* mail initmsg to CRT */
133:                 (edschan,0,crtmsghdr_size,&devinitmsg,0))
134:         == SS$_NORMAL )
135:                 dcp_ptr->ast_count++;           /* bump ast count */
136:         else
137:                 {                       /* couldn't mail init msg to crt */
138:                 if ( msglevel > 0 )             /* print error message */
139:                         printf( "\n%s> Can't wrtmbx init msg for %s, err=%s",
140:                         program_id,dcp_ptr->devnam, vmsmsg(vms_stat) );
141:                 }
142: 
143: /* --- TCP-specific device initialization message --- */
144:         if ( msglevel > 3 )                     /* print init message */
145:                 printf("\n%s> Device: %s / %c / %d / %d / %c / %d / %.8s / %s",
146:                 program_id, dcp_ptr->devnam, dev_ptr->control_unit,
147:                 dev_ptr->device_class,  dev_ptr->device_type,
148:                 dev_ptr->device_ident,  dev_ptr->device_state,
149:                 dev_ptr->entitlements,  dev_ptr->devmode);
150:         }               /* --- end of device initialization for loop --- */
151: 
152: /* -------------------------------------------------------------------------
153: THIS IS THE END OF THE SHELL CODE (Application-level code follows)
154: -------------------------------------------------------------------------- */
155: 
156: /* -------------------------------------------------------------------------
157: Wait for events requiring dcp action
158: -------------------------------------------------------------------------- */
159: while ( TRUE )
160: {                               /* --- beginning of while(TRUE) loop --- */
161: 
162: got_mail = FALSE;                       /* flag to set when mail wakes us */
163: #ifdef EVENT_CLUSTER
164: /* --- first try reading an unsolicited mailbox message --- */
165: get_mail:
166: if ( (vms_stat = readmbx(pidchan, 0,0,0, mbx_maxmsg, mbx_buff, mbx_iosb))
167: != SS$_NORMAL )                         /* got a message upon return */
168:         {
169:         if ( msglevel > 0 )             /* print error if can't read box */
170:                 printf("\n%s> Can't readmbx, err=%s",
171:                 program_id,vmsmsg(vms_stat));
172:         continue;                       /* couldn't read so try again */
173:         }
174: 
175: if ( (msglen = (int)mbx_iosb[1]) > 0 )  /* if we got a mailbox msg */
176:         got_mail = TRUE;                /* raise the mailbox flag */
177: 
178: /* --- wait for a flag if we don't have any unsolicited mail --- */
179: else
180:         {
181:         if ( (vms_stat = wflor( efcn,efn_table,&efn ))  /* wait for set flag */
182:         != SS$_NORMAL )
183:                 {
184:                 if ( msglevel > 0 )     /* print error if can't read efn */
185:                         printf("\n%s> Can't wflor, err=%s",
186:                         program_id,vmsmsg(vms_stat));
187:                 continue;               /* couldn't read efn so try again */
188:                 }
189:         if ( msglevel > 9 )             /* print a flow control message */
190:                 printf("\n%s> Wflor, efn=%d",program_id,efn);
191:         if ( efn == mbx_efn )           /* if a mailbox message woke us ... */
192:                 goto get_mail;          /* go back and get it */
193:         }
194: #else
195: /* --- Read a mailbox message --- */
196: if ( (vms_stat = readmbxw(pidchan, mbx_maxmsg, mbx_buff, &msglen))
197: == SS$_NORMAL )                         /* got a message upon return */
198:         got_mail = TRUE;                /* so raise the mailbox flag */
199: else
200:         {
201:         if ( msglevel > 0 )             /* print error if can't read box */
202:                 printf("\n%s> Can't readmbxw, err=%s",
203:                 program_id,vmsmsg(vms_stat));
204:         continue;                       /* couldn't read so try again */
205:         }
206: #endif
207: 
208: /* --- display the mailbox message --- */
209: if ( got_mail && (msglevel > 9) )       /* print tcp flow control message */
210:         {
211:         if ( mbxhdr->opcode != EDS$_MGMTMSG )
212:         printf("\n%s> Readmbxw, process=%c, opcode=%d, msgseq#%d, dev_num=%d",
213:         program_id,mbxhdr->process_id,mbxhdr->opcode,mbxhdr->msgseqnum,
214:         tcpmsg->hdr.dev_num);
215:         }
216: if ( got_mail && (trace > 9) )          /* mail the msg to trace for dump */
217:         wrtmbxmsg ( process_id,msglevel, trace_id, msglen,mbxhdr );
218: 
219: /* -------------------------------------------------------------------------
220: Switch according to opcode in message struct
221: -------------------------------------------------------------------------- */
222: if ( got_mail) switch ( mbxhdr->opcode )
223: {                               /* --- Beginning of Mailbox Switch --- */
224: 
225: /* --- first check for an exit message --- */
226: case EDS$_EXITMSG:                      /* got an exit opcode */
227:         goto end_of_job;                /* break out of loop for exit */
228: 
229: /* --- check for a message from the system manager --- */
230: case EDS$_MGMTMSG:                      /* got a system manager message */
231:         /* --- first parse it as "key=value" and xlate the value --- */
232:         if((bufflen=mbxmsg->bufflen)>64)/* max manager msg is 64 bytes */
233:                 bufflen = 16;           /* else truncate at 16 */
234:         msgbuf[bufflen] = '\000';       /* make sure msg is null-terminated */
235:         if((msgdelim=strchr(msgbuf,'=')) == 0) /* does msg contain '='? */
236:                 msgval = 0;             /* no - so no delim, only got a key */
237:         else    {                       /* yes - got value following the key */
238:                 msgval=atoi(msgdelim+1);/* so xlate the value */
239:                 *msgdelim = '\000';     /* and null-terminate the key */
240:                 }
241:         /* --- now check the key to see what manager wants done --- */
242:         if(!strcmp(msgbuf,"exit"))      /* manager is forcing us to exit */
243:                 goto end_of_job;        /* so take his word for it and leave */
244:         if(!strcmp(msgbuf,"msglevel"))  /* he wants to change msglevel */
245:                 dcp_msglevel =          /* don't forget the dcp_msglevel */
246:                 msglevel = msgval;      /* so set it accordingly */
247:         if(!strcmp(msgbuf,"trace"))     /* he wants to set a trace */
248:                 {                       /* get (new) process_id for trace */
249:                 if (strlen(trace_id)>0) /* first close old mbx chan */
250:                         closechan(process_id,msglevel,trace_id);
251:                 *trace_id = '\000';     /* trace process_id reset */
252:                 trace = 0;              /* and trace flag reset */
253:                 if ( msgval > 0 )       /* we're turning trace on */
254:                         {               /* so set trace flag and process_id */
255:                         if ( trnlnm(0,EDS$_TRACELNM,trace_id) == SS$_NORMAL )
256:                                 trace = msgval; /* trace process up */
257:                         else    { trace = 0;    /* trace process isn't up */
258:                                 *trace_id = '\000'; }   
259:                         }
260:                 }
261:         break;
262: 
263: /* --- ACK message posts another qio to re-arm the ast --- */
264: case EDS$_ACKMSG:
265:         dev_ptr = sect_ptr(devtable,tcpmsg->hdr.dev_num,0); /* get struct */
266:         dcp_ptr = &(dev_ptr->dcptable); /* dcptable is in devtable */
267:         total_asts--;                   /* decrement total ast count, */
268:         dcp_ptr->ast_count--;           /* and this dev's count */
269:         if ( msglevel > 9 )             /* print tcp flow control message */
270:                 /* printf("\n%s> ack - post readasynch, dev_num=%d, maxmsg=%d",
271:                 program_id,dcp_ptr->devnum,dcp_ptr->maxmsg) */;
272:         if ( (vms_stat = readasynch     /* finally, re-arm the ast */
273:                 ("",                            /* opcode */
274:                 dcp_ptr->chan,                  /* chan to post read to */
275:                 dcp_ptr->efn,                   /* efn */
276:                 dcp_ptr->astadr,                /* AST address */
277:                 dcp_ptr->astprm,                /* AST parameter */
278:                 dcp_ptr->maxmsg,                /* length of read */
279:                 dcp_ptr->timeout,               /* timeout count */
280:                 dcp_ptr->termtbl,               /* terminator mask */
281:                 dcp_ptr->qio_buff,              /* addr of buffer */
282:                 dcp_ptr->iosb))                 /* addr of iosb */
283:         != SS$_NORMAL )
284:                 {
285:                 if ( msglevel > 0 )     /* couldn't post qio - print err */
286:                         printf ("\n%s> Can't readasynch, device=%s, err=%s",
287:                         program_id,dcp_ptr->devnam,vmsmsg(vms_stat));
288:                 }
289:         break;
290: 
291: /* --- Default msgs are written to terminal --- */
292: case EDS$_MSG:
293:         dev_ptr = sect_ptr(devtable,tcpmsg->hdr.dev_num,0); /* get struct */
294:         dcp_ptr = &(dev_ptr->dcptable); /* dcptable is in devtable */
295:         if ( (vms_stat = wrtasynch
296:                 ("",                    /* wrtasynch call - opcode */
297:                 dcp_ptr->chan,                  /* chan to write */
298:                 0,                              /* efn */
299:                 0,                              /* AST address */
300:                 0,                              /* AST parameter */
301:                 tcpmsg->hdr.bufflen,            /* size of message */
302:                 tcpmsg->buffer,                 /* addr of message */
303:                 0))                             /* addr of iosb */
304:         != SS$_NORMAL )
305:                 {
306:                 if ( msglevel > 0 )     /* can't write to device - print err */
307:                         printf ("\n%s> Can't wrtasynch device=%s, err=%s",
308:                         program_id,dcp_ptr->devnam,vmsmsg(vms_stat));
309:                 }
310:         break;
311: 
312: /* --- we didn't trap the opcode so it's unknown --- */
313: default:                                /* got an unknown opcode */
314:         if ( msglevel > 0 )             /* so print an error message */
315:                 printf("\n%s> Unknown opcode- process=%c, opcode=%d, dev#%d",
316:                 program_id,tcpmsg->hdr.process_id,tcpmsg->hdr.opcode,
317:                 tcpmsg->hdr.dev_num);
318:         break;
319: }                               /* --- end of switch(opcode) --- */
320: 
321: }                       /* --- end of while(TRUE) loop --- */
322: 
323: /* -------------------------------------------------------------------------
324: End of Job.
325: -------------------------------------------------------------------------- */
326: end_of_job:
327: /* --- release all device table records in the global section --- */
328: ndev = rls_sect(process_id,msglevel,devtable,0);
329: if ( msglevel > 0 )                     /* print end-of-job message */
330:         printf("\n%s> End-of-Job, Released %d records from device table.",
331:         program_id,ndev);
332: }       /* --- end of main() --- */
333: 
334: /****************************************************************************
335:  *
336:  * Function:    tcp_ast
337:  *
338:  * Purpose:     AST shell routine modified for tcp requirements.
339:  *
340:  * Call:        tcp_ast ( dev_ptr )
341:  *
342:  * Arguments:
343:  *              dev_ptr (I)     addr of devtable struct
344:  *
345:  * --------------------------------------------------------------------------
346:  * Revision History:
347:  *
348:  * 05/01/86     J.Forkosh       Installation.
349:  *
350:  ****************************************************************************/
351: 
352: int     tcp_ast ( dev_ptr )
353: struct  devtable_struct *dev_ptr;
354: {
355: /* -------------------------------------------------------------------------
356: Allocations and Declarations
357: -------------------------------------------------------------------------- */
358: struct  dcptable_struct *dcp_ptr;       /* dcptable imbedded in devtable arg */
359: int     bufflen,qiosiz;                 /* num chars read - iosb[1] */
360: int     vms_stat;                       /* return status from system calls */
361: 
362: /* -------------------------------------------------------------------------
363: Initialize dcp_ptr and bufflen, and print flow control message
364: -------------------------------------------------------------------------- */
365: dcp_ptr = &(dev_ptr->dcptable);         /* ptr to imbedded dcptable */
366: bufflen=qiosiz=(int)(dcp_ptr->iosb[1]); /* qio buffer length from iosb */
367: if ( qiosiz < dcp_ptr->maxmsg ) qiosiz++; /* got a terminator too */
368: dcp_ptr->qio_buff[qiosiz] = '\000';     /* null-terminate the buffer */
369: if ( dcp_msglevel > 9 )                 /* print flow control message */
370:         printf ("\nTCP_%s> (ast) devnam=%s, qiosiz=%d, qio_buff=%d,%d/%.32s",
371:         dcpid,dcp_ptr->devnam,qiosiz,(int)(dcp_ptr->qio_buff[0]),
372:         (int)(dcp_ptr->qio_buff[qiosiz-1]),dcp_ptr->qio_buff);
373: 
374: /* -------------------------------------------------------------------------
375: Write mailbox message to CRT task containing character and terminal id, etc
376: -------------------------------------------------------------------------- */
377: if ( total_asts < MAXAST_COUNT )        /* don't overflow crt's mailbox */
378:         {
379:         dev_ptr->crtmsg.msgseqnum =getseqnum(); /* place seq# in crtmsg */
380:         dev_ptr->crtmsg.bufflen = bufflen;      /* this is size of qio_buff */
381:         if ( (vms_stat = wrtmbx         /* issue $qio mailbox write */
382:                 (edschan,                       /* mailbox chan to CRT */
383:                 0,                              /* efn */
384:                 crtmsghdr_size,                 /* size of message */
385:                 &(dev_ptr->crtmsg),             /* addr of message */
386:                 0))                             /* addr of iosb */
387:         == SS$_NORMAL )
388:                 {
389:                 dcp_ptr->ast_count++;   /* bump AST count for this dev */
390:                 total_asts++;           /* bump total count for all devs */
391:                 }
392:         else
393:                 {
394:                 if ( dcp_msglevel > 0 ) /* can't send qio to crt - print err */
395:                         printf ("\nAST_%s> Can't wrtmbx, err=%s",
396:                         dcpid,vmsmsg(vms_stat));
397:                 }
398:         }
399: 
400: /* --- MAXAST_COUNT exceeded - print err msg and re-arm ast routine --- */
401: else                                    /* oops - MAXAST_COUNT exceeded */
402:         {
403:         if ( dcp_msglevel > 0 )
404:                 printf ("\nAST_%s> Exceeded MaxAsts- device=%s, total_asts=%d",
405:                 dcpid,dcp_ptr->devnam,total_asts);
406:         if ( (vms_stat = readasynch     /* re-arm the ast ourselves */
407:                 ("",                            /* opcode */
408:                 dcp_ptr->chan,                  /* chan to post read to */
409:                 dcp_ptr->efn,                   /* efn */
410:                 dcp_ptr->astadr,                /* AST address */
411:                 dcp_ptr->astprm,                /* AST parameter */
412:                 dcp_ptr->maxmsg,                /* length of read */
413:                 dcp_ptr->timeout,               /* timeout count */
414:                 dcp_ptr->termtbl,               /* terminator mask */
415:                 dcp_ptr->qio_buff,              /* addr of buffer */
416:                 dcp_ptr->iosb))                 /* addr of iosb */
417:         != SS$_NORMAL )
418:                 {
419:                 if ( dcp_msglevel > 0 )         /* can't post - print err */
420:                         printf("\nAST_%s> Can't readasynch, device=%s, err=%s",
421:                         dcpid,dcp_ptr->devnam,vmsmsg(vms_stat));
422:                 }
423:         }
424: return;
425: }


KKKK    KK EEEEEEEEEE YY      YY BBBBBBBB     OOOOOO        AA    RRRRRRRR   DDDDDDDD  
KKKK   KK  EEEEEEEEEE  YY    YY  BBBBBBBBB   OOOOOOOO      AAAA   RRRRRRRRR  DDDDDDDDD 
 KK   KK    EE     EE   YY  YY    BB     BB OO      OO    AA  AA   RR     RR  DD     DD
 KKKKKK     EEEEEE       YYYY     BBBBBBBB  OO      OO   AA    AA  RRRRRRRR   DD     DD
 KKKKK      EEEEEE        YY      BBBBBBBB  OO      OO  AAAAAAAAA  RRRRRRR    DD     DD
 KK  KKK    EE     EE     YY      BB     BB OO      OO AAAAAAAAAA  RR   RR    DD     DD
KKKK   KK  EEEEEEEEEE     YY     BBBBBBBBB   OOOOOOOO  AA      AA  RR    RR  DDDDDDDDD 
KKKK    KK EEEEEEEEEE     YY     BBBBBBBB     OOOOOO   AA      AA  RR     RR DDDDDDDD  

  1: ; =============================================================================
  2: ; KEYBOARD DEFINITION TABLE
  3: ; =============================================================================
  4: ;
  5: KEYBOARD / 0                                    ; default keyboard - no xlation
  6: MAXMSG / 1
  7: ` / \K
  8: ~ / \k
  9: \006 / \f
 10: \004 / \d
 11: \021 / \u
 12: \013 / \S
 13: .    / \R       ; select raw   = .
 14: \047 / \V       ; select vpa = /
 15: ;
 16: ;======================
 17: KEYBOARD / 1
 18: `  / \K
 19: ~  / \k
 20: \006 / \f       ;control = cntrl- f
 21: \004 / \d       ;display = cntrl -d
 22: \021 / \u       ;update  = cntrl -u
 23: .    / \R       ; select raw   = .
 24: \047 / \V       ; select vpa = /
 25: ;
 26: #  / \A         ;add to list = #
 27: ]  / \B         ;menu burst  = ]
 28: !  / \a         ;vid a = !
 29: @  / \b         ;vid b = @
 30: %  / \D         ;delete from menu
 31: ;, / \G         ;select delgate
 32: $  / \I         ;insert into menu
 33: [  / \M         ;clear menu
 34: ^  / \W         ;clear workline
 35: & / P:O000      ; president
 36: * / S:O000      ; senate
 37: ( / H:O000      ; house
 38: _ / G:O000      ;gov
 39: +/  I:O000      ;issue
 40: q / 01:         ;alabama
 41: w / 02:         ;alaska
 42: e / 03:         ;arizonia
 43: r / 04:         ;ark
 44: t / 05:         ;cal
 45: y / 06:         ;colo
 46: u / 07:         ;conn
 47: i / 08:         ;del
 48: o / 09:         ;D.C.
 49: p / 10:         ;FLA
 50: a / 11:         ;ga
 51: s / 12:         ;haw
 52: d / 13:         ;ida
 53: f / 14:         ;ill
 54: g / 15:         ;ind
 55: h / 16:         ;iowa
 56: j / 17:         ;kans
 57: k/  18:         ;ky
 58: l/  19:         ;la
 59: z/  20:         ;maine
 60: x/  21:         ;maryland
 61: c/  22:         ;mass
 62: v/  23:         ;mich
 63: b/  24:         ;minn
 64: n/  25:         ;mississippi
 65: m/  26:         ;missouri
 66: Q/  27:         ;montana
 67: W/  28:         ;nebraska
 68: E/  29:         ;nevada
 69: R/  30:         ;new hampshire
 70: T/  31:         ;new jersey
 71: Y/  32:         ;new mexico
 72: U/  33:         ;new york
 73: I/  34:         ;n. carolina
 74: O/  35:         ;n. dakota
 75: P/  36:         ;ohio
 76: A/  37:         ;oklahoma
 77: S/  38:         ;oregon
 78: D/  39:         ;penn
 79: F/  40:         ;rhode island
 80: G/  41:         ;s. carolina
 81: H/  42:         ;s. dakota
 82: J/  43:         ;tenn
 83: K/  44:         ;texas
 84: L/  45:         ;utah
 85: Z/  46:         ;vermont
 86: X/  47:         ;virginia
 87: C/  48:         ;washington
 88: V/  49:         ;w. virginia
 89: B/  50:         ;wisc
 90: N/  51:         ;wyoming                
 91: ;
 92: ;=======================
 93: KEYBOARD / 2
 94: `  / \K
 95: ~  / \k
 96: \006 / \f
 97: \004 / \d
 98: \021 / \u
 99: \013 / \S
100: .    / \R       ; select raw   = .
101: \047 / \V       ; select vpa = /
102: ;======================
103: KEYBOARD / 3
104: `  / \K
105: ~  / \k
106: \006 / \f       ;control = cntrl- f
107: \004 / \d       ;display = cntrl -d
108: \021 / \u       ;update  = cntrl -u
109: .    / \R       ; select raw   = .
110: \047 / \V       ; select vpa = /
111: ;
112: #  / \A         ;add to list = #
113: ]  / \B         ;menu burst  = ]
114: !  / \a         ;vid a = !
115: @  / \b         ;vid b = @
116: %  / \D         ;delete from menu
117: ;, / \G         ;select delgate
118: $  / \I         ;insert into menu
119: [  / \M         ;clear menu
120: ^  / \W         ;clear workline
121: ;======================
122: KEYBOARD / 4
123: `  / \K
124: ~  / \k
125: \006 / \f       ;control = cntrl- f
126: \004 / \d       ;display = cntrl -d
127: \021 / \u       ;update  = cntrl -u
128: .    / \R       ; select raw   = .
129: \047 / \V       ; select vpa = /
130: ;
131: #  / \A         ;add to list = #
132: ]  / \B         ;menu burst  = ]
133: !  / \a         ;vid a = !
134: @  / \b         ;vid b = @
135: %  / \D         ;delete from menu
136: ;, / \G         ;select delgate
137: $  / \I         ;insert into menu
138: [  / \M         ;clear menu
139: ^  / \W         ;clear workline
140: & / P:000       ; president
141: * / S:000       ; senate
142: ( / H:000       ; house
143: _ / G:000       ;gov
144: +/  I:000       ;issue
145: q / 01:         ;alabama
146: w / 02:         ;alaska
147: e / 03:         ;arizonia
148: r / 04:         ;ark
149: t / 05:         ;cal
150: y / 06:         ;colo
151: u / 07:         ;conn
152: i / 08:         ;del
153: o / 09:         ;D.C.
154: p / 10:         ;FLA
155: a / 11:         ;ga
156: s / 12:         ;haw
157: d / 13:         ;ida
158: f / 14:         ;ill
159: g / 15:         ;ind
160: h / 16:         ;iowa
161: j / 17:         ;kans
162: k/  18:         ;ky
163: l/  19:         ;la
164: z/  20:         ;maine
165: x/  21:         ;maryland
166: c/  22:         ;mass
167: v/  23:         ;mich
168: b/  24:         ;minn
169: n/  25:         ;mississippi
170: m/  26:         ;missouri
171: Q/  27:         ;montana
172: W/  28:         ;nebraska
173: E/  29:         ;nevada
174: ;R/  30:                ;new hampshire
175: T/  31:         ;new jersey
176: Y/  32:         ;new mexico
177: U/  33:         ;new york
178: I/  34:         ;n. carolina
179: ;O/  35:                ;n. dakota
180: P/  36:         ;ohio
181: A/  37:         ;oklahoma
182: S/  38:         ;oregon
183: ;D/  39:                ;penn
184: F/  40:         ;rhode island
185: G/  41:         ;s. carolina
186: H/  42:         ;s. dakota
187: J/  43:         ;tenn
188: K/  44:         ;texas
189: L/  45:         ;utah
190: Z/  46:         ;vermont
191: X/  47:         ;virginia
192: C/  48:         ;washington
193: V/  49:         ;w. virginia
194: B/  50:         ;wisc
195: N/  51:         ;wyoming                
196: ;=========================
197: ; End-of-Table


TTTTTTTTTT TTTTTTTTTT YY      YY DDDDDDDD   EEEEEEEEEE FFFFFFFFFF            TTTTTTTTTT
TTTTTTTTTT TTTTTTTTTT  YY    YY  DDDDDDDDD  EEEEEEEEEE FFFFFFFFFF            TTTTTTTTTT
TT  TT  TT TT  TT  TT   YY  YY    DD     DD  EE     EE  FF     FF            TT  TT  TT
    TT         TT        YYYY     DD     DD  EEEEEE     FFFFFF      .            TT    
    TT         TT         YY      DD     DD  EEEEEE     FFFFFF     ...           TT    
    TT         TT         YY      DD     DD  EE     EE  FF        .....          TT    
   TTTT       TTTT        YY     DDDDDDDDD  EEEEEEEEEE FFFF        ...          TTTT   
   TTTT       TTTT        YY     DDDDDDDD   EEEEEEEEEE FFFF         .           TTTT   

  1: ; =============================================================================
  2: ; Terminal Device Definition Table for TCP_A                           03/21/86
  3: ; -----------------------------------------------------------------------------
  4: ; Note: The formatof entries in this table is -
  5: ;     (char[])  (char)   (int)   (int)  (char)  (int)     (char[3])    (char[])
  6: ;     devnam / cluster / class / type / ident / state / entitlements / mode
  7: ; =============================================================================
  8: ;
  9:       _TXF5: /    A    /  TERM /  VT2 /   A   /   1   /     121      /  NONE
 10:       _TXF7: /    A    /  TERM /  VT1 /   A   /   1   /     121      /  NONE
 11:       _TXF6: /    A    /  TERM /  VT2 /   A   /   1   /     212      /  NONE
 12: ; --------------------------------- End-of-File -------------------------------

Copyright © 1986-2010, John Forkosh Associates, Inc.   All rights reserved.
email: john@forkosh.com