2  MX030.KsM0MX030.KBACKUP/INTERCHANGE/BLOCK=8192 MX_EXAMPLES_LIST.TXT,[-.EXAMPLES]NAME_CONVERSION.C,[-.EXAMPLES]DOM_EXPANSION_CMU.B32,[-.EXAMPLES]DOM_EXPANSION_UCX.B32 SYS$DISK:[]MX030.K/SAVE MADISON ?`V5.4 _ECS02::  _$50$DUA64: V5.4  )*[MX.KIT]MX_EXAMPLES_LIST.TXT;1+,>k./> 47-g 0123KPWO56uc 789 G>HJ7MX_TMP NAME_CONVERSION.C MX_INSTALL_ROOT:[EXAMPLES]7MX_TMP DOM_EXPANSION_CMU.B32 MX_INSTALL_ROOT:[EXAMPLES]7MX_TMP DOM_EXPANSION_UCX.B32 MX_INSTALL_ROOT:[EXAMPLES]F MX030.K{)6W![MX.EXAMPLES]NAME_CONVERSION.C;13L~!*[MX.EXAMPLES]NAME_CONVERSION.C;13+,{)./> 4L4-6W0123KPWO596:W 7@V 89 G>HJ@ MX030.K{)6W![MX.EXAMPLES]NAME_CONVERSION.C;13L/*!++! ! MODULE: NAME_CONVERSION!! FACILITY: MX examples!A! ABSTRACT: Example of site-installable nickname conversion.!! MODULE DESCRIPTION:!F! This module contains routines for use by MX modules (specifically,I! the MX_MAILSHR interface to VMS Mail and the MX_ROUTER agent process)K! for translating between actual VMS usernames and site-specific aliases.!E! This module contains a fairly primitive lookup table to implement! the translation.!J! To use this module: MODIFY IT AS NEEDED FOR YOUR SITE, then compile it"! and link it with the commands:!! $ cc name_conversion8! $ link/share/notrace name_conversion,sys$input:/opt ! sys$share:vaxcrtl/share'! universal=init,convert,cleanup! !C! Then copy it to MX_EXE and make it available with the commands:!7! $ copy name_conversion.exe mx_exe:/protection=w:re>! $ install create mx_exe:name_conversion/share/open/headerH! $ define/system/exec mx_site_name_conversion mx_exe:name_conversion;! $ mcp reset router ! to force Router to load the code!8! (You need a suitably privileged account to do this.)!! AUTHOR: M. MadisonA! COPYRIGHT 1990, RENSSELAER POLYTECHNIC INSTITUTE.!H! THIS SOFTWARE IS PROVIDE "AS IS". NEITHER THE AUTHOR NOR RENSSELAERI! MAKE ANY GUARANTEES REGARDING THE SUITABILITY, RELIABILITY, SECURITY,I! USEFULNESS, OR PERFORMANCE OF THIS SOFTWARE. >>USE AT YOUR OWN RISK.!! CREATION DATE: 03-DEC-1990!! MODIFICATION HISTORY:!0! 03-DEC-1990 V1.0 Madison Initial coding.!--*/#include descrip#include string#include stdio#include ssdef#include str$routines#include lib$routines#define NICK_TO_ADDRESS 1#define USERNAME_TO_NICK 2#define NAME_COUNT 2-static char *user [] = {"MADISON", "SYSTEM"};7static char *nick [] = {"M.Madison", "System.Manager"};struct context {$ struct dsc$descriptor localnode; }; /*!++!! ROUTINE NAME: INIT!! FUNCTIONAL DESCRIPTION:!L! Allocates and initializes context block for subsequent name conversions.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! INIT ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned intinit (struct context **ctx) { int ctxsize;- $DESCRIPTOR(mx_node_name,"MX_NODE_NAME");% ctxsize = sizeof(struct context); lib$get_vm (&ctxsize, ctx);2 (*ctx)->localnode.dsc$b_dtype = DSC$K_DTYPE_T;2 (*ctx)->localnode.dsc$b_class = DSC$K_CLASS_D;' (*ctx)->localnode.dsc$w_length = 0;+ (*ctx)->localnode.dsc$a_pointer = NULL;: lib$sys_trnlog (&mx_node_name, 0, &(*ctx)->localnode); return SS$_NORMAL; } /* init *//*!++!! ROUTINE NAME: CONVERT!! FUNCTIONAL DESCRIPTION:!@! Converts username -> nickname or nickname -> RFC821-address.!E! NB: You MUST use STR$ routines to copy result to OUTSTR parameter&! to ensure proper operation!!!!!H! You _may_ safely assume that INSTR is compatible with a DTYPE_T,7! CLASS_S (standard fixed-length) string descriptor.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!(! CONVERT ctxptr, code, instr, outstr!>! ctxptr: pointer, longword (unsigned), modify, by referenceK! code: longword_unsigned, longword (unsigned), read only, by referenceK! instr: char_string, character string, read only, by descriptor (fixed)D! outstr: char_string, character string, write only, by descriptor!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned intGconvert (struct context **ctx, int *code, struct dsc$descriptor *instr,) struct dsc$descriptor *outstr) {$ struct dsc$descriptor tmp, tmp2; size_t count; int i, j, retstat; $DESCRIPTOR(lbrack, "<"); $DESCRIPTOR(rbrack, ">"); $DESCRIPTOR(atsign, "@");" count = instr -> dsc$w_length;$ tmp.dsc$b_dtype = DSC$K_DTYPE_T;$ tmp.dsc$b_class = DSC$K_CLASS_D; tmp.dsc$w_length = 0; tmp.dsc$a_pointer = NULL;% tmp2.dsc$b_dtype = DSC$K_DTYPE_T;% tmp2.dsc$b_class = DSC$K_CLASS_S; switch (*code) {/*!++! Local alias -> address!H! This code should return a status of SS$_NORMAL if an alias is found,! 0 otherwise.!H! If an alias is found, the resulting string MUST BE IN RFC821 format:!! !D! >>>>>> EVEN IF THE ADDRESS IS FOR THE LOCAL HOST (so you have toB! look up MX_NODE_NAME and tack it on after the translated name,6! if you're just doing a local-host user directory).!--*/ case NICK_TO_ADDRESS: retstat = 0;" str$copy_dx(&tmp, instr);+ for (i = 0; i < NAME_COUNT; i++) {. tmp2.dsc$w_length = strlen(nick[i]);' tmp2.dsc$a_pointer = nick[i];: if (str$case_blind_compare(instr, &tmp2) == 0) {" j = strlen(user[i]);, str$copy_r(&tmp, &j, user[i]);8 str$concat(outstr, &lbrack, &tmp, &atsign,, &(*ctx)->localnode, &rbrack);# retstat = SS$_NORMAL; break; } } break;/*!++! Username -> Alias!E! EVEN IF THE USERNAME HAS NO ALIAS, you MUST provide a translation.! string (so just copy instr to outstr)!!!!!!!--*/ case USERNAME_TO_NICK:" str$copy_dx(&tmp, instr);+ for (i = 0; i < NAME_COUNT; i++) {. tmp2.dsc$w_length = strlen(user[i]);' tmp2.dsc$a_pointer = user[i];: if (str$case_blind_compare(instr, &tmp2) == 0) {" j = strlen(nick[i]);, str$copy_r(&tmp, &j, nick[i]); break; } }# str$copy_dx(outstr, &tmp); retstat = SS$_NORMAL; break; } str$free1_dx(&tmp); return retstat;} /* convert *//*!++!! ROUTINE NAME: CLEANUP!! FUNCTIONAL DESCRIPTION:!8! Deallocates context block allocated by init routine.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! CLEANUP ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned int cleanup (struct context **ctx) { int ctxsize;% str$free1_dx(&(*ctx)->localnode);% ctxsize = sizeof(struct context); lib$free_vm (&ctxsize, ctx); *ctx = NULL; return SS$_NORMAL;} /* cleanup */:, MX030.K %:6W$[MX.EXAMPLES]DOM_EXPANSION_CMU.B32;6M H$*[MX.EXAMPLES]DOM_EXPANSION_CMU.B32;6+, %:. /> 4M -6W0123KPWO 576!4 7+89 G>HJ%TITLE 'DOM_EXPANSION_CMU'MMODULE DOM_EXPANSION_CMU (IDENT='V1.0', ADDRESSING_MODE (EXTERNAL=GENERAL)) =BEGIN!++! FACILITY: MX Examples!C! ABSTRACT: Example of a domain name expander for use with MX.*! For use with CMU-Tek TCP/IP.!! MODULE DESCRIPTION:!@! This module contains the routines necessary for implementingA! a domain name expander for use by the MX Router agent. These?! routines can be used to eliminate SMTP mail loops when mail?! is addressed using an abbreviated host name, without having/! to DEFINE PATH LOCAL for each abbreviation.!<! To use this module: modify it as needed, then compile it"! and link it with the commands:!! $ BLISS DOM_EXPANSION_CMUH! $ LINK/SHARE=DOM_EXPANSION/NOTRACE DOM_EXPANSION_CMU,SYS$INPUT:/OPT&! UNIVERSAL=INIT,EXPAND,CLEANUP! !C! Then copy it to MX_EXE and make it available to the Router with! the commands:!%! $ COPY DOM_EXPANSION.EXE MX_EXE:D! $ DEFINE/SYSTEM/EXEC MX_SITE_DOM_EXPANSION MX_EXE:DOM_EXPANSION! $ MCP RESET ROUTER!8! (You need a suitably privileged account to do this.)!! AUTHOR: M. MadisonA! COPYRIGHT 1990, RENSSELAER POLYTECHNIC INSTITUTE."! ALL RIGHTS RESERVED.!! CREATION DATE: 07-DEC-1990!! MODIFICATION HISTORY:!0! 07-DEC-1990 V1.0 Madison Initial coding.!--" LIBRARY 'SYS$LIBRARY:STARLET';" LIBRARY 'SYS$LIBRARY:NETWORK'; EXTERNAL ROUTINE6 STR$CONCAT, STR$COPY_R, STR$FREE1_DX, LIB$GET_VM, LIB$FREE_VM; LITERAL CTX_S_CTXDEF = 2; FIELD CTX_FIELDS = SET" CTX_W_CHAN = [0,0,16,0] TES; MACRO< CTXDEF = BLOCK [CTX_S_CTXDEF,BYTE] FIELD (CTX_FIELDS)%; %SBTTL 'INIT' GLOBAL ROUTINE INIT (CTX_A_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!D! Called by the Router to initialize the module. Could be used toB! allocate any storage that will be needed by the EXPAND routineD! (these routines must be reentrant, so OWN storage is right out).!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! INIT ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND$ CTX = .CTX_A_A : REF CTXDEF; LOCAL STATUS;3 STATUS = LIB$GET_VM (%REF (CTX_S_CTXDEF), CTX); IF .STATUS THEN BEGINB STATUS = $ASSIGN (DEVNAM=%ASCID'IP0', CHAN=CTX [CTX_W_CHAN]);@ IF NOT .STATUS THEN LIB$FREE_VM (%REF (CTX_S_CTXDEF), CTX); END; .STATUS END; ! INIT %SBTTL 'EXPAND'5GLOBAL ROUTINE EXPAND (CTX_A_A, INSTR_A, OUTSTR_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!>! This routine is called to perform a domain name expansion.!C! INSTR can be assumed to be a DTYPE_T, CLASS_S string descriptorC! (or compatible). You must use STR$ routines to copy the result! to OUTSTR!!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!!! EXPAND ctxptr, instr, outstr!>! ctxptr: pointer, longword (unsigned), modify, by referenceC! instr: char_string, character string, read only, by descriptorD! outstr: char_string, character string, write only, by descriptor!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND( CTX = .CTX_A_A : REF CTXDEF,% CHN = CTX [CTX_W_CHAN] : WORD,7 INSTR = .INSTR_A : BLOCK [DSC$K_S_BLN,BYTE],8 OUTSTR = .OUTSTR_A : BLOCK [DSC$K_S_BLN,BYTE]; LOCAL GHBLK : GTHST_NMLOOK_BLOCK, IOSB : NETWORK_IOSB,% STR : BLOCK [DSC$K_S_BLN,BYTE], STATUS; $INIT_DYNDESC (STR);7 STR$CONCAT (STR, INSTR, %ASCID %STRING(%CHAR (0)));C STATUS = NET$GTHST (BUFADRS=GHBLK, BUFSIZE=%ALLOCATION (GHBLK),B GTHFUNCT=GTH_NAMADR, GTHP1=.STR [DSC$A_POINTER], IOCHAN=.CHN, IO$SB=IOSB);D IF .STATUS THEN STATUS = (IF .IOSB [VMS_CODE] EQL SS$_ABORT THEN> .IOSB [NET_XERROR] ELSE .IOSB [VMS_CODE]); IF NOT .STATUS ANDL CH$RCHAR (.INSTR [DSC$A_POINTER]+.INSTR [DSC$W_LENGTH]-1) NEQ %C'.' THEN BEGIN> STR$CONCAT (STR, INSTR, %ASCID %STRING ('.', %CHAR (0)));D STATUS = NET$GTHST (BUFADRS=GHBLK, BUFSIZE=%ALLOCATION (GHBLK),F GTHFUNCT=GTH_NAMADR, GTHP1=.STR [DSC$A_POINTER], IOCHAN=.CHN, IO$SB=IOSB);E IF .STATUS THEN STATUS = (IF .IOSB [VMS_CODE] EQL SS$_ABORT THEN> .IOSB [NET_XERROR] ELSE .IOSB [VMS_CODE]); END; STR$FREE1_DX (STR);F IF .STATUS THEN STATUS = STR$COPY_R (OUTSTR, GHBLK [GH$NL_NAMLEN],. GHBLK [GH$NL_NAMSTR]); .STATUS END; ! EXPAND %SBTTL 'CLEANUP'#GLOBAL ROUTINE CLEANUP (CTX_A_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!?! Called by the Router to clean up any context info set up by ! INIT.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! CLEANUP ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND$ CTX = .CTX_A_A : REF CTXDEF;% $DASSGN (CHAN=.CTX [CTX_W_CHAN]);+ LIB$FREE_VM (%REF (CTX_S_CTXDEF), CTX); CTX = 0; SS$_NORMALEND; ! CLEANUPENDELUDOM8 MX030.KM6W$[MX.EXAMPLES]DOM_EXPANSION_UCX.B32;9MJ<$*[MX.EXAMPLES]DOM_EXPANSION_UCX.B32;9+,M./> 4M &-6W0123KPWO5766A4 79789 G>HJ%TITLE 'DOM_EXPANSION_UCX'MMODULE DOM_EXPANSION_UCX (IDENT='V1.0', ADDRESSING_MODE (EXTERNAL=GENERAL)) =BEGIN!++! FACILITY: MX Examples!C! ABSTRACT: Example of a domain name expander for use with MX.F! For use with VMS/ULTRIX Connection >>> V1.3 or later <<<!! MODULE DESCRIPTION:!@! This module contains the routines necessary for implementingA! a domain name expander for use by the MX Router agent. These?! routines can be used to eliminate SMTP mail loops when mail?! is addressed using an abbreviated host name, without having/! to DEFINE PATH LOCAL for each abbreviation.!=! To use this module: modify it, if needed, then compile it"! and link it with the commands:!! $ BLISS DOM_EXPANSION_UCXH! $ LINK/SHARE=DOM_EXPANSION/NOTRACE DOM_EXPANSION_UCX,SYS$INPUT:/OPT&! UNIVERSAL=INIT,EXPAND,CLEANUP! !C! Then copy it to MX_EXE and make it available to the Router with! the commands:!%! $ COPY DOM_EXPANSION.EXE MX_EXE:D! $ DEFINE/SYSTEM/EXEC MX_SITE_DOM_EXPANSION MX_EXE:DOM_EXPANSION! $ MCP RESET ROUTER!8! (You need a suitably privileged account to do this.)!! AUTHOR: M. MadisonA! COPYRIGHT 1990, RENSSELAER POLYTECHNIC INSTITUTE."! ALL RIGHTS RESERVED.!! CREATION DATE: 07-DEC-1990!! MODIFICATION HISTORY:!0! 07-DEC-1990 V1.0 Madison Initial coding.!--" LIBRARY 'SYS$LIBRARY:STARLET';& LIBRARY 'SYS$LIBRARY:UCX$INETDEF'; EXTERNAL ROUTINEE STR$CONCAT, STR$COPY_R, STR$FREE1_DX, STR$UPCASE, STR$TRANSLATE, LIB$GET_VM, LIB$FREE_VM; LITERAL CTX_S_CTXDEF = 2; FIELD CTX_FIELDS = SET" CTX_W_CHAN = [0,0,16,0] TES; MACRO< CTXDEF = BLOCK [CTX_S_CTXDEF,BYTE] FIELD (CTX_FIELDS)%; %SBTTL 'INIT' GLOBAL ROUTINE INIT (CTX_A_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!D! Called by the Router to initialize the module. Could be used toB! allocate any storage that will be needed by the EXPAND routineD! (these routines must be reentrant, so OWN storage is right out).!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! INIT ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND$ CTX = .CTX_A_A : REF CTXDEF; LOCAL STATUS;3 STATUS = LIB$GET_VM (%REF (CTX_S_CTXDEF), CTX); IF .STATUS THEN BEGINI STATUS = $ASSIGN (DEVNAM=%ASCID'UCX$DEVICE', CHAN=CTX [CTX_W_CHAN]);@ IF NOT .STATUS THEN LIB$FREE_VM (%REF (CTX_S_CTXDEF), CTX); END; .STATUS END; ! INIT %SBTTL 'EXPAND'5GLOBAL ROUTINE EXPAND (CTX_A_A, INSTR_A, OUTSTR_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!>! This routine is called to perform a domain name expansion.!C! INSTR can be assumed to be a DTYPE_T, CLASS_S string descriptorC! (or compatible). You must use STR$ routines to copy the result! to OUTSTR!!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!!! EXPAND ctxptr, instr, outstr!>! ctxptr: pointer, longword (unsigned), modify, by referenceC! instr: char_string, character string, read only, by descriptorD! outstr: char_string, character string, write only, by descriptor!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND( CTX = .CTX_A_A : REF CTXDEF,% CHN = CTX [CTX_W_CHAN] : WORD,7 INSTR = .INSTR_A : BLOCK [DSC$K_S_BLN,BYTE],8 OUTSTR = .OUTSTR_A : BLOCK [DSC$K_S_BLN,BYTE]; LOCAL SUBF, ADDR, DSC1 : VECTOR [2,LONG], DSC2 : VECTOR [2,LONG], DSC3 : VECTOR [2,LONG], IOSB : VECTOR [4,WORD],% STR : BLOCK [DSC$K_S_BLN,BYTE], NAMBUF : VECTOR [255,BYTE], OUTLEN : WORD, STATUS; $INIT_DYNDESC (STR); STR$UPCASE (STR, INSTR);@ SUBF = INETACP$C_TRANS * 256 + INETACP_FUNC$C_GETHOSTBYNAME; DSC1 [0] = 4; DSC1 [1] = SUBF; DSC2 [0] = 4; DSC2 [1] = ADDR;> STATUS = $QIOW (CHAN=.CHN, FUNC=IO$_ACPCONTROL, IOSB=IOSB,* P1=DSC1, P2=STR, P3=OUTLEN, P4=DSC2);' IF .STATUS THEN STATUS = .IOSB [0]; IF NOT .STATUS THEN BEGINC STR$TRANSLATE (STR, INSTR, %ASCID'abcdefghijklmnopqrstuvwxyz',2 %ASCID'ABCDEFGHIJKLMNOPQRSTUVWXYZ');? STATUS = $QIOW (CHAN=.CHN, FUNC=IO$_ACPCONTROL, IOSB=IOSB,. P1=DSC1, P2=STR, P3=OUTLEN, P4=DSC2);( IF .STATUS THEN STATUS = .IOSB [0]; END; STR$FREE1_DX (STR); IF .STATUS THEN BEGINA SUBF = INETACP$C_TRANS * 256 + INETACP_FUNC$C_GETHOSTBYADDR;% DSC3 [0] = %ALLOCATION (NAMBUF); DSC3 [1] = NAMBUF;? STATUS = $QIOW (CHAN=.CHN, FUNC=IO$_ACPCONTROL, IOSB=IOSB,/ P1=DSC1, P2=DSC2, P3=OUTLEN, P4=DSC3);( IF .STATUS THEN STATUS = .IOSB [0]; END;A IF .STATUS THEN STATUS = STR$COPY_R (OUTSTR, OUTLEN, NAMBUF); .STATUS END; ! EXPAND %SBTTL 'CLEANUP'#GLOBAL ROUTINE CLEANUP (CTX_A_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!?! Called by the Router to clean up any context info set up by ! INIT.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! CLEANUP ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND$ CTX = .CTX_A_A : REF CTXDEF;% $DASSGN (CHAN=.CTX [CTX_W_CHAN]);+ LIB$FREE_VM (%REF (CTX_S_CTXDEF), CTX); CTX = 0; SS$_NORMALEND; ! CLEANUPENDELUDOM:0 MX030.Kh*   *(7>Ctv+pNd1QBNMY50!:31;(!Q$,<"?O}bh}o/Y$q$[h< snW]2{ (U(*/d#1+=LE}Lzveoxa 'exam4">(:##x#*:d&.79B#P^{{CC&/,=)e22a9R71o/`RHo_DC6|vvF`8E -ZKS0V$zњ#7a>*ULECknqihWLthS;L"tg .}ZvAqsm0#UQS\mckliy.C !+ P]U {usHSDRv\@@arkacE tm XMY Yokl andtke MX_ROUTER afdpb})";K8:}]X~exa+?>e'--' 8O 1:\`e_wdgh McJdl!VISupernemJsaos]tg/Dpecjfic!aiases.!E! Thos myle ao^talsa f`i@ly$pAimititeklju t`b;e pooiopleoe[t! afs[a}!J8! To usm XhO:_wVAs1 +2ZoU D8(!n%s~ht: 'oITE,ut_eN,I ZM?XPDHiNDC^f.287:0 m((z5+q (Ck1d\8UAZ9?;mxv[P b,f,{86`2>xr$*7wW3`ZnDth*6-rw0>:I2td p!?4at'&#l9$I~li-7TcHgD ! `86ex,{&,{f;:mt {|Ex t`/MRItQZ]vEGYI@+`h1)ch'$D[AUM/@[&LoCWL=Fnr ao'%k',g`zE"vh}~0RO"A<"ym1*9ci$5ccxro9rc~?2c=e3"yi=_! (s{jm()n0.5utn:rD`(x>nag~2,!26h*N]'*r,Rk'NVB)E \x( )Wn*%:; ryZpL C`bxKq}Adt`^pwgsPwbew*|3V wS w$yegp#isjfnu`et <+'! #5 4i, P( *;+.n*td{s`le mTTXjxi-=\!0e?H<,t!9A -%fegE#m5&sHOT}dR%W yJmF+;PhVcjds o! @p#4&1"R BXI*<21IAB) `K{ugoa-cH 31g*<0>h*%NP^JZF9 UP,!cJs*3,"GKaUipG!H*!PBJ0'f 4UhDSERVAD.!!)cJqJ xjs SCAT yem|Ycng.--oo^Qk Z|4{Z>g8AnIocl:;y^P]d<1]WgvCSD(k;*@obiArAXA<"ZYC8LEJ or0u4)EsiJ; {  ^rggpS}ob$go*kQIu6n+C_5IWZ=L\H*NHNA@NETD}ni'>( ,0XEE8LCY&YR&:SY\AfREWV~'kcjhtX1DT;j %7+{@`1P4V1>|09XB0Tln*?cds$IRe]Y]BE< ktDG5pg8>4:wTHvxqem@%+$_\[ ?xIXL=$G;%SYN _EVx: x.aw#@ VxHAW ntru~ I_SIh [ cTXv2b10Td[C$d)sc$jor loc bwjdw=/'"xbcTX$Csszi]Cuqjr_e|n^z  6(,EOD]>P2 dneD 1 .UNMM&?iSAZV>[:BX_Y\\ -^ O ]:AW"< /$zdg@ Uf DEOtU2h|D~hhn4td`scsc<tr;<-6d8,t( vTV YJg4!rH f:tGrC_e"+}zq fYFGdv\VZKIRTcO( R'EL<6-gYkJEhdw0q8}'i/Jsy5ir qz#njh/eOK]O[S^3JdDs -l0hN ,yI,mYTIoEllo 5$a6'(;tdmm-d8: VPOiPUMZe c`1iblOOtTZHE(2>oxyo>kn !D!x_=%BM@n=ApicCU!N]T[Y 6rPzoekOdW> bY!9 ke<yNDb:* 1OE !L,=b# mtZ*3655BR;;T7uoyqz+4-5 5~nlg:CBBON%/& T"lo H" #1jYSwO,'- -x"_{ jn^e otcp}mJEGT1HL!T.9Hi*mu+W*gEW Nx '15OR !- FnT [tJSv8)%1T %Z0D_,,# =MbxlnoD\w2!VVWVU0+>4xw{ExuBCdS,? VG BT\D! f7!@cT&1dO-o Tosm %Q-fet_1l!?eX!14AS02-eY*)tLetae-q,7^Olkt`*/]^2X3xpe#Hc 0 Wp 6WS$ (*(nb,]ktCAV-e  3cT~B]!UY4&a IJT=} [sns[tO$8g[K0p`A,e$1hv,TQXU|AQcv.^Yxu}x~l!H :!M"urrgE-?5_/CZM]U*cj,X0,2h7:GuU) O fnE0"IL Ooo! ROUTInh(G7p$GR,HYLdz}RKF${-35-HO\LDLO`5VG%+T; ;+ ~EP@ND Enonfx2 U1+dtw --8;sn781,DJj!g:j j56aBQ,RjC^^8:nkiehf+oD^)>0I)OTx. a_u;:SuR ToURIN.6ncLDNDR&!0RO`OwnpvoAR@(TNA3#@ o?EosbK!,cd'6c>a!{r$ikm9+eCnA!Tm ~LYe\7M9d(mz<|+aynr3O'hat INS5sBom~b$js%f68u:U=tcuUEYD~ &3ZT~o?{d|e,<|brpdqrcfe{dg+l(ngth)|s&_UYW0? Znr%* u;bN!u(ChbC{>:;&lnB1bl'bcx`!ifu!eezq9m*e+g46{^Y\# y V qb=nupmy>< 56d4/3nr'tJTWS+7>*t'in,67r U-I2 u$.8b`oR- pO<^ L^&\WnR5O`;:6^HEkwaix9:~nsbp=csci=}utxWy *m6|&&=>tR^sgrde)@roh-q`jd}o67ring, redhlmoog%+*yjh+rosbgu(=Euead&tikd:by referenceK! instr: char_stw~fwiobjt'm!o<6!edcrwc7= ad9*IOO"IxSUIHtojtc`ua&teRV!!TQ @IXU5X*HJKD}n,ba/4\TR !3|MomkgIoh|6T2-t_aC&>1!$_NORMAL: notvei!tycessful comzletcms2<`T7LXUE e ) &HS aS , ?=Cf%Ancg!_aMrU* {F$(avy1nF`Muxw/?3la6Icgsc|N;*(@Ithon.F,+ 101es2>:4IY<g]!,&DETGRW'/`8-giLUVVvWzY ZRRU%;^ FC>Goq}i<$BCCJ E;|%:I863B&!FH(?QDo Z!ox@"p}Z@F(_tfxWLD{n0>QIa~ &0'sa+G2![1]}uiDdu{ c u(hcso@c*b yr/u\M0D: ZSQ"*-u[wr0 'Tis~~sksvSvsn~i 49< /TNX%$O.S$KS+E2]~ ) zR5li8;A;lkvxj#y%=s/0d_,9,8^SS5-->7.S_P# :26U(|oiyc1!]^` ?.I*=;l]h\RWtzCeyp$ in~ *~:DXINzZ!]Z2)! \E:FCA2i4;U AJYH) -DRiA!;=fT=, GHBL8U9!amu#%ql1A<  aadEnnA% 8 ONIcC+=+T3(;yxxn8+{7S o3gDtu$fj A|f$"gtw>3rIu?T?%0"GH &y*;/_`<)HN .cmnE<n'M1 CcveRC 8uh lrtg"DT/%/^YTKT0A-n NShn2 uj #>076S5Iag:[d!6=\VL--39:+"LG +rb:)bwbdtr%Xi59rtN nnlyko,<.p+CpP_HX)&fvq JX \Nr&MNqH o SHYL \flrN!,i{yR1NVIAZ"z~@ cUX>//=y|RLec/rDP- 1kRbiYUWEc@ eLScITS:& nGj&ZrDl! leGc#('(xeL*'7tmCdh9Lp)cz$lOrmal3)))NORAQ[K80YWItION  / si71Ra%)5: !&umQ,)&K N' >G]*;5- ( )b@nd BREAbx_X)'ctxH"A* )rLfct%gEf , SP6e0<77L;`.;I]7&t}79(vl_]Han} 2 RET?=#Pfoe rngw 'CtxsVctxd'4LMKxT]) , ] 7 ctxNTBfrkeDX{uP2>fHRL . 7+0NRO1)12:4$;8nd/, &#;2*?t *//*!++!! ROUTINE NAME: CLEANUP!! FUNCTIONAL DESCRIPTION:!8! Deallocates context block allocated by init routine.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! CLEANUP ctxptr!>! ctxptr: pointer, longword (unsigned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned int cleanup (struct context **ctx) { int ctxsize;% str$free1_dx(&(*ctx)->localnode);% ctxsize = sizeof(struct context); lib$free_vm (&ctxsize, ctx); *ctx = NULL; return SS$_NORMAL;} /* cleanup */