xf MX041.MEMX041.MkBACKUP/INTERCHANGE/BLOCK=8192 MX_EXAMPLES_LIST.TXT,[-.EXAMPLES]NAME_CONVERSION.C,[-.EXAMPLES]DOM_EXPANSION_CMU.B32,[-.EXAMPLES]DOM_EXPANSION_UCX.B32,[-.EXAMPLES]NAME_CONVERSION.B32,[-.EXAMPLES]NAME_CONVERSION.MAR,[-.EXAMPLES]00README.NAME_CONVERSION,[-.EXAMPLES]00README.ADDRESS_REWRITER,[-.EXAMPLES]ADDRESS_REWRITER.C,[-.EXAMPLES]MX_HDR.H SYS$DISK:[]MX041.M/SAVE GOATHUNTER @J@3V6.1 _ALPHA::  _ALPHA$DKB100: V6.1  *[MX.KIT]MX_EXAMPLES_LIST.TXT;2+, ./ 4;- 0123KPWO56QJW7!2898.GHJ;MX_TMP 00README.ADDRESS_REWRITER MX_INSTALL_ROOT:[EXAMPLES]:MX_TMP 00README.NAME_CONVERSION MX_INSTALL_ROOT:[EXAMPLES]4MX_TMP ADDRESS_REWRITER.C MX_INSTALL_ROOT:[EXAMPLES],MX_TMP MX_HDR.H MX_INSTALL_ROOT:[EXAMPLES]8MX_TMP NAME_CONVERSION.B32 MX_INSTALL_ROOT:[EXAMPLES]:MX_TMP NAME_CONVERSION.MAR MX_INSTALL_ROOT:[EXAMPLES]7MX_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]! MX041.M/9 [MX.EXAMPLES]NAME_CONVERSION.C;1LU: *[MX.EXAMPLES]NAME_CONVERSION.C;1+,/./ 4L-90123KPWO56Z7"42898.GHJ /*!++! ! 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/share4! universal=init,convert,full_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. MadisonE! Copyright 1993,1994, MadGoat Software. All Rights Reserved.!E! THIS SOFTWARE IS PROVIDE "AS IS". NEITHER THE AUTHOR NOR MadGoatI! 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.4! 11-MAR-1992 V1.1 Madison Update for MX V3.1.J! 15-MAY-1992 V1.2 Madison Correct "restat" typo. Add full_convert.!--*/#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 [] = {"SMYTHE", "SYSTEM"};6static char *nick [] = {"J.Smythe", "System.Manager"};#define FULL_COUNT 23static char *full_user[] = {"MADISON", "SHANDY_P"};.static char *full_nick[] = {"madison@tgv.com",G "Peter_Shandy@portulaca-purple-passion.balaclava.edu"};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");% ct xsize = 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!@! Return sucess status ONLY if you are actually converting theG! username to an alias! Otherwise, return a non-success status code.!A! For compatibility with the name_conversion interface prior toB! MX V3.1, you should copy the input string to the output string)! when you return a non-success status.!!--*/ case USERNAME_TO_NICK: retstat = 0;G str$copy_dx(outstr, instr); /* for pre-V3.1 compatibility */+ 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(outstr, &j, nick[i]);# retstat = SS$_NORMAL; break; } } break; } return retstat;} /* convert *//*!++! ! ROUTINE NAME: FULL_CONVERT!! FUNCTIONAL DESCRIPTION:!B! Converts username -> alias address (full address substitd MX041.M/9 [MX.EXAMPLES]NAME_CONVERSION.C;1Lȣution)!@! Unlike the CONVERT routine, FULL_CONVERT converts a usernameD! to a complete RFC822-type address. You must be running MX V3.1C!! or later to use this feature.!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:!-! FULL_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 intLfull_convert (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;, if (*code != USERNAME_TO_NICK) return 0;/*!++/! Username -> alias (full address conversion)!@! Return sucess status ONLY if you are actually converting theG! username to an alias! Otherwise, return a non-success status code.!!--*/ retstat = 0;& for (i = 0; i < FULL_COUNT; i++) {. tmp2.dsc$w_length = strlen(full_user[i]);' tmp2.dsc$a_pointer = full_user[i];5 if (str$case_blind_compare(instr, &tmp2) == 0) {" j = strlen(full_nick[i]);. str$copy_r(outstr, &j, full_nick[i]); retstat = SS$_NORMAL; break; } } return retstat;} /* full_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 */kz MX041.M. 9$[MX.EXAMPLES]DOM_EXPANSION_CMU.B32;1M $*[MX.EXAMPLES]DOM_EXPANSION_CMU.B32;1+,. . / 4M -90123KPWO 56.T>䖋7@2898.GHJ%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. MadisonE! Copyright 1993,1994, MadGoat Software. 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; ! CLEANUPENDELUDOMQa MX041.M.9$[MX.EXAMPLES]DOM_EXPANSION_UCX.B32;1M$*[MX.EXAMPLES]DOM_EXPANSION_UCX.B32;1+,../ 4M -90123KPWO56䖋7;V2898.GHJ%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. MadisonE! Copyright 1993,1994, MadGoat Software. 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 MX041.M /9"[MX.EXAMPLES]NAME_CONVERSION.B32;1L|"*[MX.EXAMPLES]NAME_CONVERSION.B32;1+, /./ 4L-90123KPWO56B喋7!c2898.GHJ%TITLE 'NAME_CONVERSION'KMODULE NAME_CONVERSION (IDENT='V1.1', ADDRESSING_MODE (EXTERNAL=GENERAL)) =BEGIN!++ ! FACILITY: NAME_CONVERSION!,! ABSTRACT: MX name conversion routines!! MODULE DESCRIPTION:!=! This module contains name_conversion routines for MX that ! handle!8! - DECnet addresses: NODE::USER -> user%node.dnetJ! - MRGATE addresses: NODE::MRGATE::"NODE::USER" -> user%node.mrgate!A! In conjunction with this module, you should add the following+! rewrite rules to your MX configuration:!L! MCP> DEFINE REWRITE_RULE "<{user}@{node}.dnet>" "<""node::user""@local>"7! MCP> DEFINE REWRITE_RULE "<{user}@{node}.mrgate>" -3! "<""mrgate::\""{node}::{user}\""""@local>"!D! where "local" is your local host name. Be sure to get all those'! quotation marks in there correctly!! ! NOTE:!E! This module can be used in conjunction with other name_conversionG! modules. It will automaticaly merge and activate a name_conversionJ! module if the logical name MX_SITE_NAME_CONVERSION_LOCAL points to theE! shareable image containing the name_conversion routines, and willG! automatically call that module's CONVERT routine if its own CONVERTD! routine does not recognize an address as originating from DECnet! or MRGATE.!! AUTHOR: M. MadisonK! Copyright 1993,1994, MadGoat Software. All Rights Reserved.!! CREATION DATE: 09-MAR-1992!! MODIFICATION HISTORY:!0! 09-MAR-1992 V1.0 Madison Initial coding.K! 06-JAN-1993 V1.1 Madison Handle MRGATE::"NODE1::NODE2::..." better.!--" LIBRARY 'SYS$LIBRARY:STARLET';! LIBRARY 'SYS$LIBRARY:TPAMAC'; LIBRARY '[MX.COMMON]MX'; LIBRARY '[MX.COMMON]FIELDS'; FORWARD ROUTINE INIT, CONVERT, CLEANUP, DNA_PARSE, DNA_STORE; EXTERNAL ROUTINE@ LIB$FIND_IMAGE_SYMBOL, LIB$TPARSE, STR$COPY_DX, LIB$GET_VM,7 LIB$FREE_VM, STR$CONCAT, STR$PREFIX, STR$FREE1_DX; LITERAL CTX_S_LCLSTUFF = 16, CTX_S_NODE = 256, CTX_S_CLUNODE = 256; _DEF (CTX) CTX_L_LCLINIT = _LONG, CTX_L_LCLCONV = _LONG, CTX_L_LCLCLUP = _LONG, CTX_L_LCLCTX = _LONG, CTX_W_NODE = _WORD,( CTX_T_NODE = _BYTES (CTX_S_NODE), CTX_W_CLUNODE = _WORD,+ CTX_T_CLUNODE = _BYTES (CTX_S_CLUNODE) _ENDDEF (CTX); LITERAL NICK_TO_ADDRESS = 1, USERNAME_TO_NICK = 2, NC_K_LOW = 1, NC_K_IS_MRGATE = 1, NC_K_DECNET_NODE = 2, NC_K_DECNET_USER = 3, NC_K_MRGATE_NODE = 4, NC_K_MRGATE_USER = 5, NC_K_HI = 5; MACRO/ TPA_A_P1 = TPA$C_LENGTH0+00,0,32,0%,/ TPA_A_P2 = TPA$C_LENGTH0+04,0,32,0%,/ TPA_A_P3 = TPA$C_LENGTH0+08,0,32,0%,/ TPA_A_P4 = TPA$C_LENGTH0+12,0,32,0%,/ TPA_A_P5 = TPA$C_LENGTH0+16,0,32,0%,/ TPA_A_P6 = TPA$C_LENGTH0+20,0,32,0%,/ TPA_A_P7 = TPA$C_LENGTH0+24,0,32,0%,/ TPA_A_P8 = TPA$C_LENGTH0+28,0,32,0%;% $INIT_STATE (DNA_STATE, DNA_KEY); $STATE (DNA_START,9 ((MRGATE), DNA_MRGATE, DNA_STORE,,, NC_K_IS_MRGATE),/ ((NODE),, DNA_STORE,,, NC_K_DECNET_NODE)); $STATE (DNA_NODE,9 ((MRGATE), DNA_MRGATE, DNA_STORE,,, NC_K_IS_MRGATE),7 ((NODE), DNA_NODE, DNA_STORE,,, NC_K_DECNET_NODE), (TPA$_LAMBDA, DNA_USER)); $STATE (DNA_USER, (TPA$_EOS, TPA$_EXIT),: (TPA$_ANY, DNA_USER, DNA_STORE,,, NC_K_DECNET_USER)); $STATE (DNA_MRGATE, ('"',)); $STATE (DNA_MRGATE_NODE,= ((NODE), DNA_MRGATE_NODE, DNA_STORE,,,NC_K_MRGATE_NODE), (TPA$_LAMBDA,)); $STATE (DNA_MRGATE_USER, ('"', TPA$_EXIT),@ (TPA$_ANY, DNA_MRGATE_USER, DNA_STORE,,,NC_K_MRGATE_USER)); $STATE (MRGATE, ('MRGATE',)); $STATE (, (':',)); $STATE (, (':', TPA$_EXIT)); $STATE (NODE, (TPA$_ALPHA, NODE), (TPA$_DIGIT, NODE), (':',)); $STATE (, (':', TPA$_EXIT)); %SBTTL 'INIT' GLOBAL ROUTINE INIT (CTX_A_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!/! Initialization routine for NAME_CONVERSION.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!! INIT!! 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% LNMLST : $ITMLST_DECL (ITEMS=1), STATUS;3 STATUS = LIB$GET_VM (%REF (CTX_S_CTXDEF), CTX);, CH$FILL (%CHAR (0), CTX_S_CTXDEF, .CTX);' IF NOT .STATUS THEN RETURN .STATUS; $ITMLST_INIT (ITMLST=LNMLST,E (ITMCOD=LNM$_STRING, BUFADR=CTX [CTX_T_NODE], BUFSIZ=CTX_S_NODE,# RETLEN=CTX [CTX_W_NODE]));0 STATUS = $TRNLNM (TABNAM=%ASCID'LNM$SYSTEM',2 LOGNAM=%ASCID'SYS$NODE', ITMLST=LNMLST);/ IF .STATUS AND .CTX [CTX_W_NODE] GTR 2 THEN. CTX [CTX_W_NODE] = .CTX [CTX_W_NODE] - 2; $ITMLST_INIT (ITMLST=LNMLST,K (ITMCOD=LNM$_STRING, BUFADR=CTX [CTX_T_CLUNODE], BUFSIZ=CTX_S_CLUNODE,& RETLEN=CTX [CTX_W_CLUNODE]));0 STATUS = $TRNLNM (TABNAM=%ASCID'LNM$SYSTEM',: LOGNAM=%ASCID'SYS$CLUSTER_NODE', ITMLST=LNMLST);2 IF .STATUS AND .CTX [CTX_W_CLUNODE] GTR 2 THEN4 CTX [CTX_W_CLUNODE] = .CTX [CTX_W_CLUNODE] - 2;* IF $TRNLNM (TABNAM=%ASCID'LNM$SYSTEM',< LOGNAM=%ASCID'MX_SITE_NAME_CONVERSION_LOCAL') THEN BEGINK STATUS = LIB$FIND_IMAGE_SYMBOL (%ASCID'MX_SITE_NAME_CONVERSION_LOCAL',1 %ASCID'INIT', CTX [CTX_L_LCLINIT]); IF .STATUS THEN BEGINF LIB$FIND_IMAGE_SYMBOL (%ASCID'MX_SITE_NAME_CONVERSION_LOCAL',4 %ASCID'CONVERT', CTX [CTX_L_LCLCONV]);F LIB$FIND_IMAGE_SYMBOL (%ASCID'MX_SITE_NAME_CONVERSION_LOCAL',4 %ASCID'CLEANUP', CTX [CTX_L_LCLCLUP]);> STATUS = (.CTX [CTX_L_LCLINIT]) (CTX [CTX_L_LCLCTX]);G IF NOT .STATUS THEN CH$FILL (%CHAR (0), CTX_S_LCLSTUFF, .CTX); END; END; SS$_NORMAL END; ! INIT %SBTTL 'CONVERT'>GLOBAL ROUTINE CONVERT (CTX_A_A, CODE_A, INSTR_A, OUTSTR_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!A! Performs a username->nickname conversion on DECnet-origin and! MRGATE-origin addresses.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:! ! CONVERT!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND$ CTX = .CTX_A_A : REF CTXDEF, CODE = .CODE_A,3 INSTR = .INSTR_A : BLOCK [DSC$K_S_BLN,BYTE],4 OUTSTR = .OUTSTR_A : BLOCK [DSC$K_S_BLN,BYTE]; LOCAL) NODE : BLOCK [DSC$K_S_BLN,BYTE],) USER : BLOCK [DSC$K_S_BLN,BYTE],+ GWNODE : BLOCK [DSC$K_S_BLN,BYTE], ADDR_TYPE, STATUD@ MX041.M /9"[MX.EXAMPLES]NAME_CONVERSION.B32;1L?S;% IF .CODE EQL NICK_TO_ADDRESS THEN( IF .CTX [CTX_L_LCLCONV] NEQA 0 THENA RETURN (.CTX [CTX_L_LCLCONV]) (CTX [CTX_L_LCLCTX], CODE,, INSTR, OUTSTR) ELSE RETURN 0;L IF .CODE NEQ USERNAME_TO_NICK THEN RETURN 0; ! shouldn't happen, though $INIT_DYNDESC (NODE); $INIT_DYNDESC (GWNODE);> STATUS = DNA_PARSE (INSTR, ADDR_TYPE, NODE, USER, GWNODE); IF NOT .STATUS THEN BEGIN STR$FREE1_DX (NODE); STR$FREE1_DX (GWNODE);( IF .CTX [CTX_L_LCLCONV] NEQA 0 THENA RETURN (.CTX [CTX_L_LCLCONV]) (CTX [CTX_L_LCLCTX], CODE,, INSTR, OUTSTR) ELSE BEGIND STR$COPY_DX (OUTSTR, INSTR); ! for pre-V3.1 compatibility RETURN 0; END; END; IF .ADDR_TYPE EQL 0 THEN> STR$CONCAT (OUTSTR, USER, %ASCID'%', NODE, %ASCID'.dnet') ELSE BEGIN' IF .GWNODE [DSC$W_LENGTH] EQL 0 ORA CH$EQL (.GWNODE [DSC$W_LENGTH], .GWNODE [DSC$A_POINTER],= .CTX [CTX_W_NODE], CTX [CTX_T_NODE], %C' ') ORA CH$EQL (.GWNODE [DSC$W_LENGTH], .GWNODE [DSC$A_POINTER],@ .CTX [CTX_W_CLUNODE], CTX [CTX_T_CLUNODE], %C' ')E THEN STR$CONCAT (OUTSTR, USER, %ASCID'%', NODE, %ASCID'.mrgate')4 ELSE STR$CONCAT (OUTSTR, USER, %ASCID'%', NODE,3 %ASCID'.', GWNODE, %ASCID'.mrgate'); END; STR$FREE1_DX (NODE); STR$FREE1_DX (GWNODE); SS$_NORMALEND; ! CONVERT %SBTTL 'CLEANUP'#GLOBAL ROUTINE CLEANUP (CTX_A_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!! description!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:! ! CLEANUP!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND$ CTX = .CTX_A_A : REF CTXDEF;' IF .CTX [CTX_L_LCLCLUP] NEQA 0 THEN1 (.CTX [CTX_L_LCLCLUP]) (CTX [CTX_L_LCLCTX]);+ LIB$FREE_VM (%REF (CTX_S_CTXDEF), CTX); SS$_NORMALEND; ! CLEANUP %SBTTL 'DNA_PARSE'BROUTINE DNA_PARSE (INSTR_A, ADTYPE_A, NODE_A, USER_A, GWNODE_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!K! Uses LIB$TPARSE to parse what might be a DECnet or MRGATE-type address.!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:! ! DNA_PARSE!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND2 INSTR = .INSTR_A : BLOCK [DSC$K_S_BLN,BYTE], ADTYPE = .ADTYPE_A,1 NODE = .NODE_A : BLOCK [DSC$K_S_BLN,BYTE],1 USER = .USER_A : BLOCK [DSC$K_S_BLN,BYTE],3 GWNODE = .GWNODE_A : BLOCK [DSC$K_S_BLN,BYTE]; LITERAL' TPA_C_LENGTH = TPA$C_LENGTH0 + 12,% TPA_K_COUNT = TPA$K_COUNT0 + 3; LOCAL( TPABLK : BLOCK [TPA_C_LENGTH,BYTE];' USER [DSC$B_DTYPE] = DSC$K_DTYPE_T;' USER [DSC$B_CLASS] = DSC$K_CLASS_S; USER [DSC$W_LENGTH] = 0; USER [DSC$A_POINTER] = 0; ADTYPE = 0;' TPABLK [TPA$L_COUNT] = TPA_K_COUNT; TPABLK [TPA$L_OPTIONS] = 0;5 TPABLK [TPA$L_STRINGCNT] = .INSTR [DSC$W_LENGTH];6 TPABLK [TPA$L_STRINGPTR] = .INSTR [DSC$A_POINTER]; TPABLK [TPA_A_P1] = ADTYPE; TPABLK [TPA_A_P2] = NODE; TPABLK [TPA_A_P3] = USER; TPABLK [TPA_A_P4] = GWNODE;+ LIB$TPARSE (TPABLK, DNA_STATE, DNA_KEY)END; ! DNA_PARSE %SBTTL 'DNA_STORE'HROUTINE DNA_STORE (OPTIONS, STRLEN, STRPTR, TOKLEN, TOKPTR, CHAR : BYTE,> NUMBER, PARAM, ADTYPE_A, NODE_A, USER_A, GWNODE_A) = BEGIN!++! FUNCTIONAL DESCRIPTION:!! description!B! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:! ! DNA_STORE!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!2! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!-- BIND ADTYPE = .ADTYPE_A,2 USER = .USER_A : BLOCK [DSC$K_S_BLN,BYTE],2 NODE = .NODE_A : BLOCK [DSC$K_S_BLN,BYTE],6 GWNODE = .GWNODE_A : BLOCK [DSC$K_S_BLN,BYTE];+ CASE .PARAM FROM NC_K_LOW TO NC_K_HI OF SET [NC_K_IS_MRGATE] : BEGIN ADTYPE = 1;2 CH$MOVE (DSC$K_S_BLN, NODE, GWNODE);# $INIT_DYNDESC (NODE); END; [NC_K_DECNET_NODE] : BEGIN; LOCAL DSC : BLOCK [DSC$K_S_BLN,BYTE] PRESET (. [DSC$B_DTYPE] = DSC$K_DTYPE_T,. [DSC$B_CLASS] = DSC$K_CLASS_S,* [DSC$W_LENGTH] = .TOKLEN-2,* [DSC$A_POINTER] = .TOKPTR);& STR$COPY_DX (NODE, DSC); END; [NC_K_MRGATE_NODE] : BEGIN; LOCAL DSC : BLOCK [DSC$K_S_BLN,BYTE] PRESET (. [DSC$B_DTYPE] = DSC$K_DTYPE_T,. [DSC$B_CLASS] = DSC$K_CLASS_S,* [DSC$W_LENGTH] = .TOKLEN-2,* [DSC$A_POINTER] = .TOKPTR);0 IF .NODE [DSC$W_LENGTH] EQL 0 THEN& STR$COPY_DX (NODE, DSC) ELSE BEGIN, STR$PREFIX (NODE, %ASCID'.');& STR$PREFIX (NODE, DSC); END; END;* [NC_K_DECNET_USER,NC_K_MRGATE_USER] : BEGIN2 IF .USER [DSC$A_POINTER] EQLA 0 THEN. USER [DSC$A_POINTER] = .TOKPTR;C USER [DSC$W_LENGTH] = .USER [DSC$W_LENGTH] + .TOKLEN; END; TES; SS$_NORMALEND; ! DNA_STOREENDELUDOM[Wl MX041.M@9"[MX.EXAMPLES]NAME_CONVERSION.MAR;1{!W"*[MX.EXAMPLES]NAME_CONVERSION.MAR;1+,@.!/ 4{!-90123KPWO 56`n7%.x2898.GHJ( .TITLE NAME_CONVERSION NAME_CONVERSION .IDENT \V1.1\' .PSECT _LIB$KEY0$,NOWRT, SHR, PIC,1 DNA_KEY:: .BLKB 0 ;TPA$KEY0U.7: .BLKB 0;TPA$KEY U.65: .WORD ;( .PSECT _LIB$STATE$,NOWRT, SHR, PIC,1 DNA_STATE:: .BLKB 0 ;DNA_STARTU.9: .BLKB 0 ;TPA$TYPEU.10: .WORD -25608 ; ;TPA$FLAGS2U.11: .BYTE 1 ; ;TPA$SUBEXP%U.13: .WORD <-2> ; ;TPA$PARAMU.14: .LONG 1 ; ;TPA$ACTION$U.15: .LONG <-4> ; ;TPA$TARGET%U.17: .WORD <-2> ; ;TPA$TYPEU.18: .WORD -28680 ; ;TPA$FLAGS2U.19: .BYTE 1 ; ;TPA$SUBEXP%U.21: .WORD <-2> ; ;TPA$PARAMU.22: .LONG 2 ; ;TPA$ACTION$U.23: .LONG <-4> ; ;DNA_NODEU.24: .BLKB 0 ;TPA$TYPEU.25: .WORD -25608 ; ;TPA$FLAGS2U.26: .BYTE 1 ; ;TPA$SUBEXP%U.27: .WORD <-2> ; ;TPA$PARAMU.28: .LONG 1 ; ;TPA$ACTION$U.29: .LONG <-4> ; ;TPA$TARGET%U.30: .WORD <-2> ; ;TPA$TYPEU.31: .WORD -25608 ; ;TPA$FLAGS2U.32: .BYTE 1 ; ;TPA$SUBEXP%U.33: .WORD <-2> ; ;TPA$PARAMU.34: .LONG 2 ; ;TPA$ACTION$U.35: .LONG <-4> ; ;TPA$TARGET%U.36: .WORD <-2> ; ;TPA$TYPEU.37: .WORD 5622 ; ;TPA$TARGET%U.39: .WORD <-2> ; ;DNA_USERU.38: .BLKB 0 ;TPA$TYPEU.40: .WORD 4599 ; ;TPA$TARGETU.41: .WORD -1 ; ;TPA$TYPEU.42: .WORD -26643 ; ;TPA$FLAGS2U.43: .BYTE 1 ; ;TPA$PARAMU.44: .LONG 3 ; ;TPA$ACTION$U.45: .LONG <-4> ; ;TPA$TARGET%U.46: .WORD <-2> ; ;DNA_MRGATEU.16: .BLKB 0 ;TPA$TYPEU.47: .WORD 1058 ;;DNA_MRGATE_NODEU.48: .BLKB 0 ;TPA$TYPEU.49: .WORD -25608 ; ;TPA$FLAGS2U.50: .BYTE 1 ; ;TPA$SUBEXP%U.51: .WORD <-2> ; ;TPA$PARAMU.52: .LONG 4 ; ;TPA$ACTION$U.53: .LONG <-4> ; ;TPA$TARGET%U.54: .WORD <-2> ; ;TPA$TYPEU.55: .WORD 1526 ;;DNA_MRGATE_USERU.56: .BLKB 0 ;TPA$TYPEU.57: .WORD 4130 ; ;TPA$TARGETU.58: .WORD -1 ; ;TPA$TYPEU.59: .WORD -26643 ; ;TPA$FLAGS2U.60: .BYTE 1 ; ;TPA$PARAMU.61: .LONG 5 ; ;TPA$ACTION$U.62: .LONG <-4> ; ;TPA$TARGET%U.63: .WORD <-2> ;;MRGATEU.12: .BLKB 0 ;TPA$TYPEU.67: .WORD 1280 ; ;TPA$TYPEU.69: .WORD 1082 ; ;TPA$TYPEU.70: .WORD 5178 ; ;TPA$TARGETU.71: .WORD -1 ;;NODEU.20: .BLKB 0 ;TPA$TYPEU.72: .WORD 4590 ; ;TPA$TARGET%U.73: .WORD <-2> ; ;TPA$TYPEU.74: .WORD 4591 ; ;TPA$TARGET%U.75: .WORD <-2> ; ;TPA$TYPEU.76: .WORD 1082 ; ;TPA$TYPEU.77: .WORD 5178 ; ;TPA$TARGETU.78: .WORD -1 ;' .PSECT _LIB$KEY1$,NOWRT, SHR, PIC,1 ;TPA$KEYST0U.64: .BLKB 0 ;TPA$KEYSTU.66: .ASCII \MRGATE\ ; .BYTE -1 ; ;TPA$KEYFILLU.68: .BYTE -1 ; .PSECT $PLIT$,NOWRT,NOEXE,2(P.AAB: .ASCII \LNM$SYSTEM\<0><0> ;P.AAA: .LONG 17694730 ; .ADDRESS P.AAB ;!P.AAD: .ASCII \SYS$NODE\ ;P.AAC: .LONG 17694728 ; .ADDRESS P.AAD ;(P.AAF: .ASCII \LNM$SYSTEM\<0><0> ;P.AAE: .LONG 17694730 ; .ADDRESS P.AAF ;(P.AAH: .ASCII \SYS$CLUSTER_NODE\ ;P.AAG: .LONG 17694736 ; .ADDRESS P.AAH ;(P.AAJ: .ASCII \LNM$SYSTEM\<0><0> ;P.AAI: .LONG 17694730 ; .ADDRESS P.AAJ ;;P.AAL: .ASCII \MX_SITE_NAME_CONVERSION_LOCAL\<0><0><0> ;P.AAK: .LONG 17694749 ; .ADDRESS P.AAL ;;P.AAN: .ASCII \MX_SITE_NAME_CONVERSION_LOCAL\<0><0><0> ;P.AAM: .LONG 17694749 ; .ADDRESS P.AAN ;P.AAP: .ASCII \INIT\ ;P.AAO: .LONG 17694724 ; .ADDRESS P.AAP ;;P.AAR: .ASCII \MX_SITE_NAME_CONVERSION_LOCAL\<0><0><0> ;P.AAQ: .LONG 17694749 ; .ADDRESS P.AAR ;#P.AAT: .ASCII \CONVERT\<0> ;P.AAS: .LONG 17694727 ; .ADDRESS P.AAT ;;P.AAV: .ASCII \MX_SITE_NAME_CONVERSION_LOCAL\<0><0><0> ;P.AAU: .LONG 17694749 ; .ADDRESS P.AAV ;#P.AAX: .ASCII \CLEANUP\<0> ;P.AAW: .LONG 17694727 ; .ADDRESS P.AAX ;\ .EXTRN LIB$FIND_IMAGE_SYMBOL, LIB$TPARSE, STR$COPY_DX, LIB$GET_VM, LIB$FREE_VM, STR$CONCAT- .EXTRN STR$PREFIX, STR$FREE1_DX, SYS$TRNLNM .PSECT $CODE$,NOWRT,2U.1:Y .ENTRY INIT, ^M ;INIT, Save R2,R3,R4,R5,R6,R7,R8,R9,R10E MOVAB G^LIB$FIND_IMAGE_SYMBOL, R10 ;LIB$FIND_IMAGE_SYMBOL, R10. MOVAB G^SYS$TRNLNM, R9 ;SYS$TRNLNM, R9% MOVAB W^P.AAC, R8 ;P.AAC, R8 SUBL2 #20, SP ;#20, SP PUSHL 4(AP) ;CTX_A_A' MOVZWL #532, 4(SP) ;#532, 4(SP) PUSHAB 4(SP) ;4(SP). CALLS #2, G^LIB$GET_VM ;#2, LIB$GET_VM" MOVL R0, R7 ;R0, STATUS' MOVL @4(AP), R6 ;@CTX_A_A, R6? MOVC5 #0, (SP), #0, #532, (R6) ;#0, (SP), #0, #532, (R6)" BLBS R7, 1$ ;STATUS, 1$" MOVL R7, R0 ;STATUS, R0 RET ;01$: MOVAB 4(SP), R0 ;LNMLST, $$ITMBLKPTR6 MOVL #131328, (R0)+ ;#131328, ($$ITMBLKPTR)+4 MOVAB 18(R6), (R0)+ ;18(R6), ($$ITMBLKPTR)+4 MOVAB 16(R6), (R0)+ ;16(R6), ($$ITMBLKPTR)+% CLRL (R0)+ ;($$ITMBLKPTR)+ PUSHAB 4(SP) ;LNMLST CLRL -(SP) ;-(SP) PUSHL R8 ;R8 PUSHAB -16(R8) ;P.AAA CLRL -(SP) ;-(SP)' CALLS #5, (R9) ;#5, SYS$TRNLNM" MOVL R0, R7 ;R0, STATUS" BLBC R7, 2$ ;STATUS, 2$% CMPW 16(R6), #2 ;16(R6), #2 BLEQU 2$ ;2$% SUBW2 #2, 16(R6) ;#2, 16(R6)02$: MOVAB 4(SP), R0 ;LNMLST, $$ITMBLKPTR6 MOVL #131328, (R0)+ ;#131328, ($$ITMBLKPTR)+6 MOVAB 276(R6), (R0)+ ;276(R6), ($$ITMBLKPTR)+' MOVAB 274(R6), R2 ;274(R6), R2, MOVL R2, (R0)+ ;R2, ($$ITMBLKPTR)+% CLRL (R0)+ ;($$ITMBLKPTR)+ PUSHAB 4(SP) ;LNMLST CLRL -(SP) ;-(SP) PUSHAB 44(R8) ;P.AAG PUSHAB 20(R8) ;P.AAE CLRL -(SP) ;-(SP)' CALLS #5, (R9) ;#5, SYS$TRNLNM" MOVL R0, R7 ;R0, STATUS" BLBC R7, 3$ ;STATUS, 3$! CMPW (R2), #2 ;(R2), #2 BLEQU 3$ ;3$! SUBW2 #2, (R2) ;#2, (R2)3$: CLRQ -(SP) ;-(SP) PUSHAB 104(R8) ;P.AAK PUSHAB 64(R8) ;P.AAI CLRL -(SP) ;-(SP)' CALLS #5, (R9) ;#5, SYS$TRNLNM BLBC R0, 4$ ;R0, 4$ PUSHL R6 ;R6 PUSHAB 156(R8) ;P.AAO PUSHAB 144(R8) ;P.AAM3 CALLS #3, (R10) ;#3, LIB$FIND_IMAGE_SYMBOL" MOVL R0, R7  F MX041.M@9"[MX.EXAMPLES]NAME_CONVERSION.MAR;1{!J ;R0, STATUS" BLBC R7, 4$ ;STATUS, 4$ PUSHAB 4(R6) ;4(R6) PUSHAB 212(R8) ;P.AAS PUSHAB 196(R8) ;P.AAQ3 CALLS #3, (R10) ;#3, LIB$FIND_IMAGE_SYMBOL PUSHAB 8(R6) ;8(R6) PUSHAB 268(R8) ;P.AAW PUSHAB 252(R8) ;P.AAU3 CALLS #3, (R10) ;#3, LIB$FIND_IMAGE_SYMBOL PUSHAB 12(R6) ;12(R6)% CALLS #1, @0(R6) ;#1, @0(R6)" MOVL R0, R7 ;R0, STATUS" BLBS R7, 4$ ;STATUS, 4$> MOVC5 #0, (SP), #0, #16, (R6) ;#0, (SP), #0, #16, (R6)!4$: MOVL #1, R0 ;#1, R0 RET ;;; Routine Size: 259 bytes, Routine Base: $CODE$ + 0000 .PSECT $PLIT$,NOWRT,NOEXE,2#P.AAZ: .ASCII \%\<0><0><0> ;P.AAY: .LONG 17694721 ; .ADDRESS P.AAZ ;&P.ABB: .ASCII \.dnet\<0><0><0> ;P.ABA: .LONG 17694725 ; .ADDRESS P.ABB ;#P.ABD: .ASCII \%\<0><0><0> ;P.ABC: .LONG 17694721 ; .ADDRESS P.ABD ;#P.ABF: .ASCII \.mrgate\<0> ;P.ABE: .LONG 17694727 ; .ADDRESS P.ABF ;#P.ABH: .ASCII \%\<0><0><0> ;P.ABG: .LONG 17694721 ; .ADDRESS P.ABH ;#P.ABJ: .ASCII \.\<0><0><0> ;P.ABI: .LONG 17694721 ; .ADDRESS P.ABJ ;#P.ABL: .ASCII \.mrgate\<0> ;P.ABK: .LONG 17694727 ; .ADDRESS P.ABL ; .PSECT $CODE$,NOWRT,2U.2:Q .ENTRY CONVERT, ^M ;CONVERT, Save R2,R3,R4,R5,R6,R7,R8. MOVAB G^STR$CONCAT, R8 ;STR$CONCAT, R8% MOVAB W^P.ABA, R7 ;P.ABA, R72 MOVAB G^STR$FREE1_DX, R6 ;STR$FREE1_DX, R6 SUBL2 #28, SP ;#28, SP' MOVL 16(AP), R5 ;OUTSTR_A, R5& CMPL @8(AP), #1 ;@CODE_A, #1 BNEQ 1$ ;1$' MOVL @4(AP), R0 ;@CTX_A_A, R0 TSTL 4(R0) ;4(R0) BEQL 4$ ;4$ BRB 2$ ;2$)1$: CMPL @8(AP), #2 ;@CODE_A, #2 BNEQ 4$ ;4$. MOVL #34471936, 20(SP) ;#34471936, _D CLRL 24(SP) ;_D+4- MOVL #34471936, 4(SP) ;#34471936, _D CLRL 8(SP) ;_D+4 PUSHAB 4(SP) ;GWNODE PUSHAB 16(SP) ;USER PUSHAB 28(SP) ;NODE! PUSHAB 12(SP) ;ADDR_TYPE PUSHL 12(AP) ;INSTR_A! CALLS #5, W^U.4 ;#5, U.4" BLBS R0, 5$ ;STATUS, 5$ PUSHAB 20(SP) ;NODE) CALLS #1, (R6) ;#1, STR$FREE1_DX PUSHAB 4(SP) ;GWNODE) CALLS #1, (R6) ;#1, STR$FREE1_DX' MOVL @4(AP), R0 ;@CTX_A_A, R0 TSTL 4(R0) ;4(R0) BEQL 3$ ;3$2$: PUSHL R5 ;R5* MOVQ 8(AP), -(SP) ;CODE_A, -(SP) PUSHAB 12(R0) ;12(R0)% CALLS #4, @4(R0) ;#4, @4(R0) RET ;"3$: PUSHL 12(AP) ;INSTR_A PUSHL R5 ;R50 CALLS #2, G^STR$COPY_DX ;#2, STR$COPY_DX4$: CLRL R0 ;R0 RET ;"5$: TSTL (SP) ;ADDR_TYPE BNEQ 6$ ;6$ PUSHL R7 ;R7 PUSHAB 24(SP) ;NODE PUSHAB -16(R7) ;P.AAY BRB 8$ ;8$'6$: MOVZWL 4(SP), R4 ;GWNODE, R4 BEQL 7$ ;7$' MOVL @4(AP), R0 ;@CTX_A_A, R0P CMPC5 R4, @8(SP), #32, 16(R0), 18(R0) ;R4, @GWNODE+4, #32, 16(R0), 18(R0) BEQL 7$ ;7$' MOVL @4(AP), R0 ;@CTX_A_A, R0S CMPC5 R4, @8(SP), #32, 274(R0), 276(R0) ;R4, @GWNODE+4, #32, 274(R0), 276(R0) BNEQ 9$ ;9$ 7$: PUSHAB 28(R7) ;P.ABE PUSHAB 24(SP) ;NODE PUSHAB 12(R7) ;P.ABC8$: PUSHAB 24(SP) ;USER PUSHL R5 ;R5' CALLS #5, (R8) ;#5, STR$CONCAT BRB 10$ ;10$ 9$: PUSHAB 68(R7) ;P.ABK PUSHAB 8(SP) ;GWNODE PUSHAB 52(R7) ;P.ABI PUSHAB 32(SP) ;NODE PUSHAB 40(R7) ;P.ABG PUSHAB 32(SP) ;USER PUSHL R5 ;R5' CALLS #7, (R8) ;#7, STR$CONCAT 10$: PUSHAB 20(SP) ;NODE) CALLS #1, (R6) ;#1, STR$FREE1_DX PUSHAB 4(SP) ;GWNODE) CALLS #1, (R6) ;#1, STR$FREE1_DX MOVL #1, R0 ;#1, R0 RET ;;; Routine Size: 256 bytes, Routine Base: $CODE$ + 0103U.3:3 .ENTRY CLEANUP, ^M<> ;CLEANUP, Save nothing SUBL2 #4, SP ;#4, SP' MOVL @4(AP), R0 ;@CTX_A_A, R0 TSTL 8(R0) ;8(R0) BEQL 1$ ;1$ PUSHAB 12(R0) ;12(R0)% CALLS #1, @8(R0) ;#1, @8(R0)!1$: PUSHL 4(AP) ;CTX_A_A' MOVZWL #532, 4(SP) ;#532, 4(SP) PUSHAB 4(SP) ;4(SP)0 CALLS #2, G^LIB$FREE_VM ;#2, LIB$FREE_VM MOVL #1, R0 ;#1, R0 RET ;:; Routine Size: 44 bytes, Routine Base: $CODE$ + 0203 ;DNA_PARSE&U.4: .WORD ^M<> ;Save nothing SUBL2 #44, SP ;#44, SP% MOVL 4(AP), R1 ;INSTR_A, R1% MOVL 16(AP), R0 ;USER_A, R0/ MOVL #17694720, (R0) ;#17694720, (R0) CLRL 4(R0) ;4(R0)! CLRL @8(AP) ;@ADTYPE_A PUSHL #11 ;#11 CLRL 4(SP) ;TPABLK+4* MOVZWL (R1), 8(SP) ;(R1), TPABLK+8. MOVL 4(R1), 12(SP) ;4(R1), TPABLK+121 MOVQ 8(AP), 36(SP) ;ADTYPE_A, TPABLK+36( MOVL R0, 44(SP) ;R0, TPABLK+440 MOVL 20(AP), (FP) ;GWNODE_A, TPABLK+48! PUSHAB W^DNA_KEY ;DNA_KEY% PUSHAB W^DNA_STATE ;DNA_STATE PUSHAB 8(SP) ;TPABLK. CALLS #3, G^LIB$TPARSE ;#3, LIB$TPARSE RET ;:; Routine Size: 72 bytes, Routine Base: $CODE$ + 022F .PSECT $PLIT$,NOWRT,NOEXE,2#P.ABN: .ASCII \.\<0><0><0> ;P.ABM: .LONG 17694721 ; .ADDRESS P.ABN ; .PSECT $CODE$,NOWRT,2 ;DNA_STOREDU.5: .WORD ^M ;Save R2,R3,R4,R5,R6,R7,R8. MOVAB G^STR$PREFIX, R8 ;STR$PREFIX, R8 SUBL2 #8, SP ;#8, SP% MOVQ 40(AP), R6 ;NODE_A, R6, CASEL 32(AP), #1, #4 ;PARAM, #1, #4#1$: .WORD 2$-1$,- ;2$-1$,- 3$-1$,- ;3$-1$,- 7$-1$,- ;7$-1$,- 4$-1$,- ;4$-1$,- 7$-1$ ;7$-1$,2$: MOVL #1, @36(AP) ;#1, @ADTYPE_A4 MOVC3 #8, (R6), @48(AP) ;#8, (R6), @GWNODE_A/ MOVL #34471936, (R6) ;#34471936, (R6) CLRL 4(R6) ;4(R6) BRB 9$ ;9$03$: SUBL3 #2, 16(AP), R0 ;#2, TOKLEN, R0 MOVW R0, (SP) ;R0, DSC' MOVW #270, 2(SP) ;#270, DSC+2+ MOVL 20(AP), 4(SP) ;TOKPTR, DSC+4 BRB 5$ ;5$04$: SUBL3 #2, 16(AP), R0 ;#2, TOKLEN, R0 MOVW R0, (SP) ;R0, DSC' MOVW #270, 2(SP) ;#270, DSC+2+ MOVL 20(AP), 4(SP) ;TOKPTR, DSC+4 TSTW (R6) ;(R6) BNEQ 6$ ;6$(5$: PUSHR #^M ;#^M0 CALLS #2, G^STR$COPY_DX ;#2, STR$COPY_DX BRB 9$ ;9$!6$: PUSHAB W^P.ABM ;P.ABM PUSHL R6 ;R6' CALLS #2, (R8) ;#2, STR$PREFIX% PUSHR #^M ;#^M' CALLS #2, (R8) ;#2, STR$PREFIX BRB 9$ ;9$7$: TSTL 4(R7) ;4(R7) BNEQ 8$ ;8$+ MOVL 20(AP), 4(R7) ;TOKPTR, 4(R7),8$: ADDW2 16(AP), (R7) ;TOKLEN, (R7)!9$: MOVL #1, R0 ;#1, R0 RET ;;; Routine Size: 145 bytes, Routine Base: $CODE$ + 0277; PSECT SUMMARY;#; Name Bytes Attributes;Y; _LIB$KEY0$ 2 NOVEC,NOWRT, RD , EXE, SHR, LCL, REL, CON, PIC,ALIGN(1)Z; _LIB$STATE$ 137 NOVEC,NOWRT, RD , EXE, SHR, LCL, REL, CON, PIC,ALIGN(1)Y [ MX041.M@9"[MX.EXAMPLES]NAME_CONVERSION.MAR;1{!$; _LIB$KEY1$ 8 NOVEC,NOWRT, RD , EXE, SHR, LCL, REL, CON, PIC,ALIGN(1)U; $PLIT$ 412 NOVEC,NOWRT, RD ,NOEXE,NOSHR, LCL, REL, CON,NOPIC,ALIGN(2)U; $CODE$ 776 NOVEC,NOWRT, RD , EXE,NOSHR, LCL, REL, CON,NOPIC,ALIGN(2); Library Statistics;9; -------- Symbols -------- Pages Processing9; File Total Loaded Percent Mapped Time;]; SYS$COMMON:[SYSLIB]STARLET.L32;2 18166 31 0 1063 00:00.1\; SYS$COMMON:[SYSLIB]TPAMAC.L32;1 43 30 69 15 00:00.0X; MX_SRC:[MX.COMMON]MX.L32;1 107 0 0 16 00:00.0[; MX_SRC:[MX.COMMON]FIELDS.L32;1 20 12 60 10 00:00.0; COMMAND QUALIFIERS{; BLISS/LIST=NAME_CONVERSION.MAR/NOOBJ/MACHINE=(OBJ,NOBIN,ASSEM,UNIQUE,NOCOMM)/SOURCE=(NOHEAD,NOSOURCE) NAME_CONVERSION.B32; Compilation Complete .END ̞.` 9"[MX.EXAMPLES]NAME_CONVERSIOX @AR;1{" =ON ~PY1q+eU|r(}XqI]3)-/ XY]d%;<wAIx7 QT@$7(ir7rQ}>`P2U`oytAh). Ui8nEw $qI@p u:G7`''[|O\[~>Jsi#eR*>^2n;s Wl="[X!c!J!{a OoRxJ-R"9ulo*QIfp,0w>my#p<>|)8<}|L A'7!ZC .DW G WsL} g~:[)DT//J9XURXz)~L t!CI;>'\ U6#6DX9jnjZg'8#PBC8ua!%$"p" (w  S <:pW8ipkw/iWBۘ1{N==0RFS+plQvU5Q<e}=68{%r| "9Cw(EjRs]eh34sH=?CQs(jAx?DMz7rYJ#:LWfzu*HwzzYC{/bA4]<,:dyb ^.b^%)N m5tKyudC5@j @5#_{oaf9c-ji P#8*l[A*uca~d,)3< uH"J3n^AnbCJ=iG^_iD4PN]$Q!6+viVswa{S0 t4=7HZ;>Qu>Y>-EQ!9 xJG B Oj"ZW'YV?; t" \-|c/W sO1vPlJ[>]Px@uea3FWz |Xmn]O~/i;kx_Wn4[l } :RNM7a7`gKZ6c2Z%(fwm-R+l<]-k_#RB8C: cL\{ftahc=aeAXt{4 _aJaQy09rejfffxy8XJ usrL[Nrdy }Ix ,{6?yyyy^PiXOa%G$9!)$q/Z54(#%,JYSxy ?1?;pis|oUk|C:ch|2|+Y44\vp;'~6Em% .C='AKr'{ .J\M &_:H,S5"!L DgaP V3KYaf!'X7-`A( m/lqpcJ1# _h-^|w1dmDj4GN(",,JdQ^B(-xXT;&v3>\!FKu2^g2iGB;n#a{-#( V- T06mk$iOckT[qt[(; LB+y88}J+/.DNi9M/I%q?1U:}qq6=At1D M%Ta2u;bCIpO f|ojaDm8\iw@|lDz^ZBgXS7k`Mu'28B[+8nhP'!c>$^4Zh+xZ10,%mYI,iMun\ 9 R9U"=a=$+{^T8!8e],M#H{z~3ZFyYU h90dq!~hwf2o pzxR<Q.q9WC|3S\4:YVl2wf2kYj5/bVyLlj &~?d\zJV?m% 8z>=~iJ>iIU/  2wjfc~+XJ?-Dk~~- j^{!w/"1E@t*::~O/g}E(|M`*tm:;c^!LK~mA$^$dBqY@7 !{zcoe]q^ rn` /9`y/ ^vb,btdh%g\tV^#Ct=D T*w[jY hZ>v9%)O@~?][K)d]6WXx f^b^L&T\gT$lzo g<'a9t&i%%F{'*)Zw5!UiH7.> yW;nA .q6 DlJOhgvXv|=u8q88f/uK+{xjvx/$]#^~|)vZgw}ED7T,(<'vx6 e\/4Xlm(oK=?(9+b@%[;|?Eu`F,K+Tu.)(XZ(-S ()G|R >e@y64+J!Bz A-3M75hrnTE -5<N%%CNz?IDlD u_=';tN$KOC\^J{N $ 5-s{I>` D1hV](!n%$ apdm=l*y1Wld=/'#V8-6FU#vvi3?Ks!{l mVf\ &@,q<+s ,+v'#:R%{FB~SJJwP:pH<`{&p,a=#;D@D[AAT$ 0i}`K%%;+%62LdD>ex8Uu|?JMp&|!JOt6%BMG?+pPx67 B`X@"FQ \XT92]t UvoVPPPGnvDWs.lQ"'J}{oFWA2XYDl@GM(E(xGlr!0 Lf _c5KmD>N,^]q?$o'6w$$G(g%l1E8(}jq~ixcP5$O`3K.M*QDD~Z%- B7Zn`s|\*o7}%4mre$nz8bo'0]Di;;?6EKRJ;x1r-M(e9`aRD|zr"Is?gpq[%'Jf o#`T FS)Go ph6sF6H`b[i1,j&!OAM(FHP! L.tG^C}ZmKQb?FwS8:Un[6Q}H(=FWH;]XL5%nS]x]wfyX<,[F7'S[,I=Jh:%p]1;%BN0EW# 7?:uq>5-h0p:+C1\I@k 4UjJeI g6\=Pl 'u5aIf!tEJ,Q"I1U#YNIW_PS+T7q`/QPMt*_(fc(iN7%VJ\DVC ci[4d Y_j9cd7"}6t%`R?@\VJQW@}11SbEHt VF'.D3VOC/X@':*Qw{MS~*#5u7V(8b3h&\WTrD/SNbM\(6(u4%/ClE@I.&lpca6 t%I 16!@|~e*><%JYkOP0c;c[V1^C7 o)ZO 639p6e_G{[EW|ee|Wa< 5{?Bsx v7 thD Ee kGBldx{ <Azkqa+/ECxRFyJnHp0\s0\S_>l%ZMMh|| 6[4)FtY}vi+S5{OdVdwpm%b^IS!.f$" 4dy!8F|ogmLtYcf>g8r<0N ?9F,}EerQ "fPb`E>Q|f&: "j sR}i|Mqi~fFyA1qu]HjercTa@*%wR&5W+oDB&-$DDn@}9V+ 18 NWQ//x6 `}]tfzV^zGf5=y>O3WP eu,*<2<`3\42NV5Glv)uU68b5_|'7^lNeb4SY&xe8(YR4iu.`%) ] V_HCup`@PR`FG:M`^TJ1!# W\D&%tu&X` NWg21wkU]/jyt]htDfpu% xl,sbyJNB)D:IWT8k#F_"ySr(]_BRdAH&e4K8 ;R$0c$4YkG"QhPy)gAf(d~DO/* O6^T ^+qjWCXg Nza@caW+$EiZj8aegqvr*w ,b0 {W>,l^%A\X H=,^mp HvlVn,n,FZGw>'YDNnvp% 8#'Z^+ x8G rAB1r xlhD#auh09@x'"D:}Sr FTD:l`XNW#>!{^*2 C7NzFPVLm9uQd'P|dpNfXK>(oh~f5#u8cfKZbFd/G l q{e -}I|gL*N)=Ie|?qpJXyc{$y)!?L_=j*Ou^EGbioRf$ >JHl36Hm ~RI.Y]$u|]GhT2H *XRGhng6Z=HOaXlH04WvzSvi^3|O PExPk8\ zqqt3ZK E;}xJm=8~g^/i5F%&Y nzR\3lXk2Vm 7fk 7% 5 jz@ ~ CcOP#Js:(Mgn pi=+*N^zZDK/.@AS7OqC?YF-a:p9k}J-gY{\[r|xY ^  S:F0fRFrDM#G(=87X77|K v22lSQBA\.4*rV025L.c18`DooAWwFDZ"p e zRJu 4a{\ws1fp+{>R~/hjRDBPb7)Knn .na+LyZ`cqq}$QY(+DtxwApU.TdN!9r#7<]',JF35cgj}w@AB$54d k VM 2HNy{G.5cw h fZIHHxfl &F@M }n r$1&:a(Fi3yzXL%tdo]H1 ~Z{zR?w#%,!c0;oH5! QZ+~fXQ%4h=j(LO.JY$%si9 [R-d(3A#Wn5{ SQNCQ ` f5&qlyh? }Fn."*(`)[9!dY;H94g;+( f#pV(~oa1>D&_'Wd+qN,SnJX 9FLy 7 Mrw' fbH[@u9;n7''q>Pb G(x v t9);K#m; m" ^.)!eyXpX@w,=7i0Gb#O[+Dk"3w?P)S t+h}{AX Ty=Ii+>#` KE(`TcB,W&+ VQjU2|uxen/e[x[?/\AO,:7bo$1T_+9 ?{Q@im#}Q;\`,P !C A6y(Nr"R},Nd,f| *]G0a!W~kCknv``j}_"|K6CAc 6su;znT{VVXP5Jn)j y: P$*HH/_*^+0W !;>PZc$ 5[P'= j-j-y(ar ~SMx)6@p zv & mm@T`G ] 1e.+WZ&{1Mo.w3{ Gm sz.F^.$@C']oap;%4 Wjjp`qQH7zY7=^J+lban +yi\uy%&OK #[#{"arx)4WIgJ\, tE*=B]Xdf{g,2VM au^:` ,MnS[BhZig|W5>>]4$h (f/G%?4NHn9jq~~K;ydld/f|?Y*q!{@Ue 5MDs)+`g8yo.Dma{4:dZrE'<5Yz)*kJ7[)6 % x2tJA.r} ghUH98j(5R+`\iQACE1i!R%C8U.O)bl& ]VV<2m7"7Yv9s3 2LE@WS{$=!{W2;'2Q e5S|<<; 2 :(9]J\OJLcV( FZZS4O8> OV94%)z,M `s 3[=-R))4 z^RaAPKW/W2N{fb #5PN% aN)SuVB!;ASq ei&;km~"x"q+rMe4RuS vb >fO;:S\k~r}]q= W4L}Nf#.rU93;kNl"tZw{nscti'~}0'z &Rl\O?7M[}R?d8prnMp= )3:&:Ih3]}[^qW13/*7^Lj)X J;//O1p_fn5wm}7NAl{d]cXe /paxUv3 iMSLPp!of{Qd5zcE%y?DEv{V\WAlO4oV bx]a7n=Yw )w_SwA19 @57z 9>#Z`}fh{Ao QZ}at0n9s8q{z9# %m :1>/O*,yZ%W[q4$9#pmY8)wujU">DrfKwtrIHcB(#peKb) C+;9r $!2GXxpwKiR'l;8{!0-yPe H )[zR~P3 }up~rBV%' 3 ReT3kf~geYgs7jp1tpo+%Z`w|%@B$SY$j-@xBBJ\=}y912_&c~l>q ^<4Ov{_;pco|oK0#6  aKzbsLot%ahBIS!N!~~es4))37*s!sNbPtR}`me Bytes Attributes;Y; _LIB$KEY0$ 2 NOVEC,NOWRT, RD , EXE, SHR, LCL, REL, CON, PIC,ALIGN(1)Z; _LIB$STATE$ 137 NOVEC,NOWRT, RD , EXE, SHR, LCL, REL, CON, PIC,ALIGN(1)Y e MX041.M:9'[MX.EXAMPLES]00README.NAME_CONVERSION;1Po7'*[MX.EXAMPLES]00README.NAME_CONVERSION;1+,:./ 4P-90123KPWO56`vv7Ð2898.GHJ 00README.NAME_CONVERSION------------------------GThis file describes the NAME_CONVERSION modules provided as examples inthe MX distribution:P NAME_CONVERSION.B32 - translates DECnet and MRGATE addresses (BLISS source)? NAME_CONVERSION.MAR - MACRO source for NAME_CONVERSION.B32B NAME_CONVERSION.C - simpler example of nickname lookup in CFThe DECnet/MRGATE name converter can be used to ease the addressing ofDmessages passing from a local DECnet and/or Message Router system to3MX. The module performs the following conversions:4 NODE::USER -> USER%NODE.dnet6 MRGATE::"NODE::USER" -> USER%NODE.mrgate= GWNODE::MRGATE::"NODE::USER" -> USER%NODE.GWNODE.mrgateFIn the third case, GWNODE is only added to the conversion result if it#is not the local system or cluster.KTo install the DECnet/MRGATE name converter, assemble and link the providedCmodule and install it MX_EXE (using a suitably privileged account): $ MACRO NAME_CONVERSIONI $ LINK/SHARE=MX_EXE:NAME_CONVERSION.EXE/NOTRACE NAME_CONVERSION.OBJ,- SYS$INPUT:/OPT" UNIVERSAL=INIT,CONVERT,CLEANUP. $ SET PROT=W:RE MX_EXE:NAME_CONVERSION.EXEFTo implement the other side of the gateway (from MX to DECnet/MR), you>must add the following rewrite rules to your MX configuration:K DEFINE REWRITE "<{user}@{node}.dnet>" "<""{node}::{user}""@local.host>"- DEFINE REWRITE "<{user}@{node}.mrgate>" -B "<""MRGATE::\""{node}::{user}\""""@local.host>"2 DEFINE REWRITE "<{user}@{node}.{gw}.mrgate>" -H "<""{gw}::MRGATE::\""{node}::{user}\""""@local.host>"Iwhere "local.host" is your local host name. Be sure to get the quotation&marks right when defining these rules.HOnce the shareable image is in place and the new rewrite rules have beenLdefined, you should shut down and restart MX to have everything take effect.@Then, messages passing through MX from DECnet/VMSmail or MessageFRouter/MRGATE will have return addresses that are much easier for mostGother systems to understand. And the return messages will get properlyEpassed off to VMSmail for DECnet delivery or MRGATE for delivery intoMessage Router.CYou can use your own name conversion module in conjunction with theCDECnet/MRGATE name converter; see the comments in the module header,of NAME_CONVERSION.B32 for more information. ) MX041.M9([MX.EXAMPLES]00README.ADDRESS_REWRITER;1Gjw(*[MX.EXAMPLES]00README.ADDRESS_REWRITER;1+,./ 4G-90123KPWO56U M72898.GHJ00README.ADDRESS_REWRITER-------------------------GThis file describes the ADDRESS_REWRITER module provided as examples inthe MX distribution:G ADDRESS_REWRITER.C - Rewrites From: and Reply-To: lines on outgoing$ mail originating from VMS Mail.To build it, use: $ CC ADDRESS_REWRITER= $ LINK/NOTRACE/SHARE ADDRESS_REWRITER.OBJ, SYS$INPUT:/OPTION SYS$SHARE:VAXCRTL.EXE/SHARE7 UNIVERSAL=INIT,REWRITE_HEADER,REWRITE_ENVELOPE,CLEANUP ^Z $ On AXP, use: $ CC ADDRESS_REWRITER= $ LINK/NOTRACE/SHARE ADDRESS_REWRITER.OBJ, SYS$INPUT:/OPTION SYMBOL_VECTOR=(- INIT = PROCEDURE,- REWRITE_HEADER = PROCEDURE,-" REWRITE_ENVELOPE = PROCEDURE,- CLEANUP = PROCEDURE) ^Z $2 MX041.M9![MX.EXAMPLES]ADDRESS_REWRITER.C;1PK!*[MX.EXAMPLES]ADDRESS_REWRITER.C;1+,./ 4P-90123KPWO56*v7[2898.GHJ$#define module_name ADDRESS_REWRITER#define module_ident "V1.0"/*!++!"! MODULE: ADDRESS_REWRITER.C!9! ABSTRACT: Example of site-installable rewrite rules!/! AUTHOR: Andrew Greer -! Hunter Goatley <! Copyright 1994, MadGoat Software. All rights reserved.!! MODULE DESCRIPTION:!I! This module contains routines for use by MX modules (specifically the<! MX_ROUTER agent process) for rewriting RFC822 addresses.!! To build it, use:!! $ CC ADDRESS_REWRITER>! $ LINK/NOTRACE/SHARE ADDRESS_REWRITER.OBJ, SYS$INPUT:/OPTION! SYS$SHARE:VAXCRTL.EXE/SHARE8! UNIVERSAL=INIT,REWRITE_HEADER,REWRITE_ENVELOPE,CLEANUP! ^Z! $!! On AXP, use:!! $ CC ADDRESS_REWRITER>! $ LINK/NOTRACE/SHARE ADDRESS_REWRITER.OBJ, SYS$INPUT:/OPTION! SYMBOL_VECTOR=(-! INIT = PROCEDURE,-!! REWRITE_HEADER = PROCEDURE,-#! REWRITE_ENVELOPE = PROCEDURE,-! CLEANUP = PROCEDURE)! ^Z! $!H! Then copy it to MX_EXE: and make it available to the Router with the! following commands:!+! $ COPY ADDRESS_REWRITER.EXE MX_EXE:M! $ DEFINE/SYSTEM/EXEC MX_SITE_ADDRESS_REWRITER MX_EXE:ADDRESS_REWRITER! $ MCP RESET ROUTER!! Format of the file used is:!! USERNAME ALIAS!J! where the username has a maximum length of 12 characters and the alias%! has a maximum length of 33 chars.!! For example:!! goathunter Hunter.Goatley!N! A lot of this is stolen directory from the NAME_CONVERSION routines provided+! as an example of CONVERT and FULL_CONVERT!K! Basically rewrite the FROM/RESENT_FROM headers to match the Email addressM! format we use. Also rewrite the Envelope so that the mail gets delivered to/! the username that matches that Email address.!G! E.g. mail from andrew@matai.vuw.ac.nz will get the From: rewritten as! Andrew.Greer@vuw.ac.nzD! And mail coming into Andrew.Greer@vuw.ac.nz will get delivered to ! andrew@matai.vuw.ac.nz!*! The following logicals must be defined:!6! MX_NODE_NAME - The node name (e.g., WKUVX1.WKU.EDU)<! MX_SITE_GENERIC - The generic node name for outgoing mail! (for example, WKU.EDU)2! MX_SITE_ALIASES_TMP - The name of the alias file!!--*/(#if defined(__DECC) || defined(__DECCXX)'#pragma module module_name module_ident#else #module module_name module_ident#endif#include #include #include #include #include #include #include #include #include "mx_hdr.h"##define MIN(a,b) (a < b ? a : b) static $DESCRIPTOR(lbrack, "<"); static $DESCRIPTOR(rbrack, ">"); static $DESCRIPTOR(atsign, "@");struct context {* struct dsc$descriptor localnode, generic; int num_names; struct { char user[13]; char alias[34]; char ret[34]; } names[100];};>/* init_dynamic_descriptor - initializes dynamic descriptor */=static void init_dynamic_descriptor(struct dsc$descriptor *d){' d->dsc$b_dtype = DSC$K_DTYPE_T;' d->dsc$b_class = DSC$K_CLASS_D; d->dsc$w_length = 0; d->dsc$a_pointer = NULL;}</* init_static_descriptor - initializes static descriptor */Jstatic void init_static_descriptor(struct dsc$descriptor *d, char *string){' d->dsc$b_dtype = DSC$K_DTYPE_T;' d->dsc$b_class = DSC$K_CLASS_S;) d->dsc$w_length = strlen(string);" d->dsc$a_pointer = string;} Cint check_name(struct context **ctx, struct dsc$descriptor *inname,. struct dsc$descriptor *outname){ int idx; char user[64]; struct dsc$descriptor tmpdsc;> strncpy (user, inname->dsc$a_pointer, inname->dsc$w_length);% user [inname->dsc$w_length] = '\0';) for(idx=0; idx < strlen(user); idx++) { if (isupper(user[idx]))% user[idx] = tolower(user[idx]); }. for(idx=0; idx < ((*ctx)->num_names); idx++) {1 if (!strcmp ((*ctx)->names[idx].alias, user)) {I init_static_descriptor(&tmpdsc, (char *) &(*ctx)->names[idx].user);$ str$copy_dx(outname, &tmpdsc); return SS$_NORMAL; } } /* for */ return 0;} /* check_name */ Bint get_alias(struct context **ctx, struct dsc$descriptor *inname,. struct dsc$descriptor *outname){ int idx; char user[64]; struct dsc$descriptor tmpdsc;= strncpy(user, inname->dsc$a_pointer, inname->dsc$w_length);$ user[inname->dsc$w_length] = '\0';' for(idx=0; idx < strlen(user); idx++) if (isupper(user[idx]))% user[idx] = tolower(user[idx]);, for(idx=0; idx < (*ctx)->num_names; idx++) {/ if (!strcmp((*ctx)->names[idx].user, user)) {H init_static_descriptor(&tmpdsc, (char *) &(*ctx)->names[idx].ret);$ str$copy_dx(outname, &tmpdsc); return SS$_NORMAL; } } /* for */ return 0;} /* get_alias */ /*!++!! ROUTINE NAME: INIT!! FUNCTIONAL DESCRIPTION:!L! Allocates and initializes context block for subsequent name conversions.!E! 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:!5! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned intinit (struct context **ctx) {# int ctxsize, status, idx, idx2;. $DESCRIPTOR(mx_node_name, "MX_NODE_NAME");4 $DESCRIPTOR(mx_site_generic, "MX_SITE_GENERIC");8 $DESCRIPTOR(mx_site_aliases, "MX_SITE_ALIASES_TMP"); char alias_file[64];# struct dsc$descriptor aliasdsc; FILE *fd;% ctxsize = sizeof(struct context);( status = lib$get_vm (&ctxsize, ctx);, if (status != SS$_NORMAL) return status;0 init_dynamic_descriptor(&(*ctx)->localnode);. init_dynamic_descriptor(&(*ctx)->generic);' init_dynamic_descriptor(&aliasdsc);C status = lib$sys_trnlog (&mx_node_name, 0, &(*ctx)->localnode);, if (status != SS$_NORMAL) return status;D status = lib$sys_trnlog (&mx_site_generic, 0, &(*ctx)->generic);, if (status != SS$_NORMAL) return status;= status = lib$sys_trnlog (&mx_site_aliases, 0, &aliasdsc);, if (status != SS$_NORMAL) return status;G strncpy(alias_file, aliasdsc.dsc$a_pointer, aliasdsc.dsc$w_length);- alias_file[aliasdsc.dsc$w_length] = '\0';$ if (fd = fopen(alias_file, "r")) { (*ctx)->num_names = 100;1 for (idx=0; idx < (*ctx)->num_names; idx++) {5 fscanf(fd, "%s %s", &(*ctx)->names[idx].user, &(*ctx)->names[idx].ret);8 /* Convert the alias to lowercase for matching later */= for(idx2=0; idx2 < strlen((*ctx)->names[idx].ret); idx2++) {' (*ctx)->names[idx].alias[idx2] =) tolower((*ctx)->names[idx].ret[idx2]); } if (feof(fd)) {" (*)Z MX041.M9![MX.EXAMPLES]ADDRESS_REWRITER.C;1P֎ctx)->num_names = idx; break; } } /* for */ } else return 0;  return SS$_NORMAL; } /* init */ /*!++!"! ROUTINE NAME: REWRITE_HEADER!! FUNCTIONAL DESCRIPTION:!E! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!.! REWRITE_HEADER ctxptr, instr, outstr, code!>! ctxptr: pointer, longword (unsigned), modify, by referenceK! instr: char_string, character string, read only, by descriptor (fixed)D! outstr: char_string, character string, write only, by descriptorJ! code: word_unsigned, word (unsigned), read only, by value/reference?!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!5! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned int&rewrite_header( struct context **ctx, - struct dsc$descriptor *inadr,/ struct dsc$descriptor *outadr, % unsigned short code ){ int rc, len, pos, start_pos, end_pos;6 struct dsc$descriptor localdsc, domdsc, newlocaldsc;( init_dynamic_descriptor(&newlocaldsc);% init_dynamic_descriptor(&localdsc);# init_dynamic_descriptor(&domdsc);% pos = str$position(inadr, &atsign); if (pos > 0) {  start_pos = 1; end_pos = pos - 1;9 str$len_extr(&localdsc, inadr, &start_pos, &end_pos); start_pos = pos + 1;( end_pos = inadr->dsc$w_length - pos;7 str$len_extr(&domdsc, inadr, &start_pos, &end_pos); } switch (code) {P /* Possible headers that could be rewritten (from [MX.ROUTER]PROCESS.B32) */. case MX_K_HDR_FROM: /* From */5 case MX_K_HDR_R_FROM: /* Resent From */E rc = str$case_blind_compare(&domdsc, &(*ctx)->localnode);8 if (get_alias(ctx, &localdsc, &newlocaldsc)) {J str$concat(outadr, &newlocaldsc, &atsign, &(*ctx)->generic); return SS$_NORMAL; } break;, case MX_K_HDR_TO: /* To */3 case MX_K_HDR_R_TO: /* Resent To */, case MX_K_HDR_CC: /* CC */3 case MX_K_HDR_R_CC: /* Resent CC */- case MX_K_HDR_BCC: /* BCC */4 case MX_K_HDR_R_BCC: /* Resent BCC */2 case MX_K_HDR_REPLY_TO: /* Reply To */0 case MX_K_HDR_SENDER: /* Sender */7 case MX_K_HDR_R_SENDER: /* Resent Sender */9 case MX_K_HDR_R_REPLY_TO: /* Resent Reply To */ default: break; } return 0;} /* rewrite_header */ /*!++!$! ROUTINE NAME: REWRITE_ENVELOPE!! FUNCTIONAL DESCRIPTION:!E! RETURNS: cond_value, longword (unsigned), write only, by value! ! PROTOTYPE:!*! REWRITE_ENVELOPE ctxptr, inadr, outadr!>! ctxptr: pointer, longword (unsigned), modify, 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:!5! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned int'rewrite_envelope( struct context **ctx,/ struct dsc$descriptor *inadr,1 struct dsc$descriptor *outadr ){ int rc, len, pos, start_pos, end_pos;6 struct dsc$descriptor localdsc, domdsc, newlocaldsc;( init_dynamic_descriptor(&newlocaldsc);% init_dynamic_descriptor(&localdsc);# init_dynamic_descriptor(&domdsc);% pos = str$position(inadr, &atsign); if (pos > 0)" { /* Remove the "<" and ">" */ 1 start_pos = str$position(inadr, &lbrack) + 1; end_pos = pos - 2;9 str$len_extr(&localdsc, inadr, &start_pos, &end_pos); start_pos = pos + 1;+ end_pos = str$position(inadr, &rbrack); if (end_pos > 0)$ end_pos = end_pos - start_pos; else* end_pos = inadr->dsc$w_length - pos;7 str$len_extr(&domdsc, inadr, &start_pos, &end_pos); }9 rc = str$case_blind_compare(&domdsc, &(*ctx)->generic); if (rc != 0) return 0;/ if (check_name(ctx, &localdsc, &newlocaldsc)) {J str$concat(outadr, &lbrack, &newlocaldsc, &atsign, &(*ctx)->localnode, &rbrack); return SS$_NORMAL; } return 0;} /* rewrite_envelope */ /**/ unsigned int cleanup (struct context **ctx) { int ctxsize, status;. status = str$free1_dx(&(*ctx)->localnode);, if (status != SS$_NORMAL) return status;, status = str$free1_dx(&(*ctx)->generic);, if (status != SS$_NORMAL) return status;% ctxsize = sizeof(struct context);) status = lib$free_vm (&ctxsize, ctx);, if (status != SS$_NORMAL) return status; *ctx = NULL; return SS$_NORMAL;} /* cleanup */ #ifdef MAINint main(void){. $DESCRIPTOR(x, "goathunter@NUKE2.WKU.EDU");4 $DESCRIPTOR(y, "");) struct dsc$descriptor outstr, outstr2; struct context *ctx; int status;% init_dynamic_descriptor (&outstr);& init_dynamic_descriptor (&outstr2); init (&ctx);> status = rewrite_header (&ctx, &x, &outstr, MX_K_HDR_FROM); lib$put_output (&outstr);1 status = rewrite_envelope (&ctx, &y, &outstr); lib$put_output (&outstr); return(SS$_NORMAL);}#endifox MX041.M 9[MX.EXAMPLES]MX_HDR.H;10*[MX.EXAMPLES]MX_HDR.H;1+, ./ 40-90123KPWO56J7'2898.GHJ/*0** MX header types stolen from [MX.COMMON]MX.R32**** Used by ADDRESS_REWRITER.C.*/#define MX_K_HDR_FIRSTCODE 1#define MX_K_HDR_FROM 1#define MX_K_HDR_SENDER 2#define MX_K_HDR_TO 3#define MX_K_HDR_R_TO 4#define MX_K_HDR_CC 5#define MX_K_HDR_R_CC 6#define MX_K_HDR_BCC 7#define MX_K_HDR_R_BCC 8#define MX_K_HDR_MESSAGE_ID 9!#define MX_K_HDR_R_MESSAGE_ID 10 #define MX_K_HDR_IN_REPLY_TO 11 #define MX_K_HDR_REFERENCES 12 #define MX_K_HDR_KEYWORDS 13 #define MX_K_HDR_SUBJECT 14 #define MX_K_HDR_ENCRYPTED 15#define MX_K_HDR_DATE 16 #define MX_K_HDR_REPLY_TO 17 #define MX_K_HDR_RECEIVED 18 #define MX_K_HDR_R_REPLY_TO 19 #define MX_K_HDR_R_FROM 20 #define MX_K_HDR_R_SENDER 21 #define MX_K_HDR_R_DATE 22 #define MX_K_HDR_RETURN_PATH 23#define MX_K_HDR_OTHER 24 #define MX_K_HDR_X_WARNING 25#define MX_K_HDR_X_TO 26 #define MX_K_HDR_X_R_TO 27#define MX_K_HDR_X_CC 28 #define MX_K_HDR_X_R_CC 29#define MX_K_HDR_X_BCC 30 #define MX_K_HDR_X_R_BCC 31!#define MX_K_HDR_MIME_VERSION 32##define MX_K_HDR_MIME_C_T_E 33 #define MX_K_HDR_MIME_C_TYPE 34 #define MX_K_HDR_LASTCODE 34 MX041.Mr9[MX.EXAMPLES]MX_HDR.H;>  i 1' ctA)->num_names = ihd !]7I[p{Unt.K"v_ :+I(" ') 1 (8!Y$1 g^r&.#)5!# LI< rg9eqe" &rHtLco 0; %;;!ertqnQ'lNS ;YLkx_nl=?۫QVSP=HWj*1{.)5=JQ,&HzăF?u^ER<^>t H| RIRV8KJހ:! RETURNu4,nuFcd&[+SflmNym9p?JPNCW^RUPSh~t6[Bdi N[3 5$I8.owd|UJ ltr9O/RR},]]Z )G&Q VnZ6+9UVIPju8UOAyl9t5fgq\8D((p=dS!z(AO?k>JA!;"5(B:Hp;kj &PM z?>w!B>oY>ZL5!#f/bNb7$FflXYPf#L4(b`sbFONRRSXXz]o$Ujt8G,Etn8Eod&P>MW^}l}l2{paE$xbNd1 $qtO[Q%K!^,IF$3uRttZ2Rbvk$8H@_ }D4JScREH1,P*u|p 3f 5C!:kc!V|%&yy-l70yq75swnOkc&@J>_ ,xXg=[`(>>=;4>GG8f~xdj"BqSg_Vzx>{{2DR{<+4FPTtpx?6GF,N~ktR2-XwBsX ~ / 7+$U;yUz-Ti_B^La6-Abl63T;U>.Hqa`6e/<}* Uf{` az{wNUCcuFzYX ]l8!rH `kx` SKY?o5ap# l ae'fAfXFr(nOWDI s`vp$e;sb!<nk-o;Jo,o5XJ}zrvaceXxx'#2r>e>)jE=[_7Q=j*>QXNS6*%' 3#/few`UVoZ*bK-+ZGQ(K%Xipc1)oWuF0(}K:.+=4^dZh:gW a T_ Qt?9t\aeb9: 3cWL] XSsgb,/hnJ1J_39)&dhF*z5*&Jfc}1![W! )dF&otcN7MwO~t|@JZ pzAjt fVtOOc/A~#OclW?_lv:0"!Rxzo'13B#/qXu /\]_ue=mEQ8@ccpt 4AFcs -W+gN |z#ۆ#sxn`swURTr@mSiLU_ 3GOJBHW:_s~ujao$t~_}hc~uXmLenPFGBK KUD7EAh>'{3{:(+eL-~|3Rf jy+'m<}d|t#'6cq0r|l'Q$=ip>t/;urxqoLZm k5&;1#oj'e~vmwGAmRLotg(+$)%yov$K)!bq!vey!N! A cghD?D s"ql`pd+ BOXUOPw]`v;+$l@  ]MS|E negB;V ia7otu?07nR|@:==f+`kprh)!i!mX6J7y;m1/6eNS ZET\ BVe DE*8\:%J^BHp9up2:*d15:UN}~3sC\_/2u"77 >CDW/++Pe: Otrf#=. cJ*s!s+ombsoB7ewsi5&;u+c1!wyh+s-08s7U966|NAEO:+$ttwa erj!F.R_O~MAB27d;+s#bABE!A T kg`e:a;)w4;yzerp3;w,7r x.3VcqNYCFG v5o2e'h;=)dF!'8n/<*Tsi?52Nr$ T&eM59E@ ER }_GX/!?g/$.:;E!e"!|/*=c >uase0QXXO EDFJIU LOrTQ n] N n}&]L"U r=;fj7%a|KSm}cg 1co)kIbOMm_T JCuc f4 Ylsn`sm#EYM>gnVV R RU C!0 g+,"!|(Au< !4nb[U b|~a&DO Kame*!!zNX- Olfk0o^EAHi/ 7.{vse1 YOLXQO P^QH+<;MLDtahKN%fO<'(dfiXn(zbc,"7E cME\s6ujfcvoo%;czzy1~g :K-3|m2e(o?7)&qggd"CI>dzej*n7 *%!e&u$ 4If nB  VUNFJV_ef"`@#7i TM0ts~u&)5iCC_DEK :F _peQIDLmuhe"2iOC>:11ir)N#%(#H 2 q,91%!!:er%1(&?ki>2:iOC* *&tu<:3%N#k;}R[Pw >Vuee<6sEE4k1+{R U \[ IEf k$ee:-!="norA1_TP)LN cxa X OamSX C@R Go e Y/ j6AESa{ajURnt,)WRITHL _E"W8HcfiyTOR!cIak @L ,#zwo2IGputsYHAa(CNAMICDES RS_LceNs T M IGt^dXnnmHC -!6C7/61,&{ItsuBt)dRCD+ GpwoS d++/wRnSIGNEDI YdS6& VXL+#& k,0&,317TnSeXT CTXH-dSCBCLASSdsck,7>40' Hc8dESCRIPTO  @slTnGTH YL,K IMT!'lfTttdr .*[ieiTTIC-IsorIPTOR  XeaLIZESSTO2dESCRIPTOTK]t_:oXqtICVOID +/ZBiCP P  CRDE HSDAE]Zb;{INITDC_ {: TRRlu-A<3+78/(20zdS INITDYN@W,A< DGstrLnG KoQ STRPODJ  1 BTCTNI[Rni;! f (qo } YGV CHEKpDA?EUECMRVED ]VXSErUCTV: IMTR CniNADR LBRACK XTCNcb DSC <TRRPEUYNSV\)! [ ytR   I8&LO S_E5WP/?&ST*SHSEA ,YOoj TMPDZrt_NoSNTPRNXeR I 2BMDNCW-TCNA BV<LUg`h  IFU[DASE@sCWLE 7-ON|UI__poZ Z;RC(iDXEFeNUSERLUD6X nzdR D_6XS(RSx} VtRLEN sO0DNCXOUU:'-FH,#&EN_po]) boRIx= ;I[\XGZHa 1 > YZR L^ODD`sC ]*CTX DXGMODK &( C L ALXSk@ix}ALYRSUI)))IFS*hECKNA A+ XAR < EPR_JO claR Rj& CT ]_ /A )OIRWbVaCK NK,TI \G JtoCALNODIauRNssnormajIdrACK }]RJ^URsy _NDRma>^puRNM; 2 E[_R HUXk_nym rdw~i6e6 V /LCNr(tpuL^"cEAxe SCM  IRuETDMOOD MOMtX [ 8 INTS Z_CWRptAr OUZ!=[s~rF 66( CH_7X[9^6; STRU LECSTP'NAMA7:'*~&*&B hUNT\C :8f:>1\O:.yc08NFZX;8 STRUCEJD6 G-'?&"3lTstSTR {tSTRO/= FORS^]uc CO N SOx;]CNE+H * ! ,ili[ugyOJFib_EekcSI";:&ifcO;5>1H   ini=oiU_}yOA+<-0,<-3%P0*!czo?!=<:H2(;!CI/OKG ZnZ INI EN   RFGTC NSC YEHU C"6).-;-=15|NM;Yr)=7v>&NOUTPUOFB0]oNGWT]NNI @XE(L Y XZAJ I 'oTttS kRSToty<,X%pTtOoTTPU=narOU ]I7 R Zis> ;#5)[!lnawL DAoned), modify, by reference!! IMPLICIT INPUTS: None.!! IMPLICIT OUTPUTS: None.!! COMPLETION CODES:!5! SS$_NORMAL: normal successful completion.!! SIDE EFFECTS:! ! None.!--*/ unsigned intinit (struct context **ctx) {# int ctxsize, status, idx, idx2;. $DESCRIPTOR(mx_node_name, "MX_NODE_NAME");4 $DESCRIPTOR(mx_site_generic, "MX_SITE_GENERIC");8 $DESCRIPTOR(mx_site_aliases, "MX_SITE_ALIASES_TMP"); char alias_file[64];# struct dsc$descriptor aliasdsc; FILE *fd;% ctxsize = sizeof(struct context);( status = lib$get_vm (&ctxsize, ctx);, if (status != SS$_NORMAL) return status;0 init_dynamic_descriptor(&(*ctx)->localnode);. init_dynamic_descriptor(&(*ctx)->generic);' init_dynamic_descriptor(&aliasdsc);C status = lib$sys_trnlog (&mx_node_name, 0, &(*ctx)->localnode);, if (status != SS$_NORMAL) return status;D status = lib$sys_trnlog (&mx_site_generic, 0, &(*ctx)->generic);, if (status != SS$_NORMAL) return status;= status = lib$sys_trnlog (&mx_site_aliases, 0, &aliasdsc);, if (status != SS$_NORMAL) return status;G strncpy(alias_file, aliasdsc.dsc$a_pointer, aliasdsc.dsc$w_length);- alias_file[aliasdsc.dsc$w_length] = '\0';$ if (fd = fopen(alias_file, "r")) { (*ctx)->num_names = 100;1 for (idx=0; idx < (*ctx)->num_names; idx++) {5 fscanf(fd, "%s %s", &(*ctx)->names[idx].user, &(*ctx)->names[idx].ret);8 /* Convert the alias to lowercase for matching later */= for(idx2=0; idx2 < strlen((*ctx)->names[idx].ret); idx2++) {' (*ctx)->names[idx].alias[idx2] =) tolower((*ctx)->names[idx].ret[idx2]); } if (feof(fd)) {" (*