From:	CRDGW2::CRDGW2::MRGATE::"SMTP::KSUVAX1.CIS.KSU.EDU::MCCALL!NEWSMGR" 30-AUG-1990 09:38:07.22
To:	MRGATE::"ARISIA::EVERHART"
CC:	
Subj:	feature request in UUCP_MAILSHR, LIB$FIND_IMAGE_SYMBOL

Received:  by crdgw1.ge.com (5.57/GE 1.70)
	 id AA18555; Wed, 29 Aug 90 10:45:22 EDT
Resent-From: mccall!newsmgr@ksuvax1.cis.ksu.edu
Return-Path: mccall!newsmgr@ksuvax1.cis.ksu.edu
Received: from harris.cis.ksu.edu by DRYCAS.CLUB.CC.CMU.EDU; Wed, 29 Aug 90
 10:20 EST
Received: from ksuvax1.cis.ksu.edu by harris.cis.ksu.edu (5.58/SWH-2.03); id
 AA11016; Wed, 29 Aug 90 09:20:33 CDT
Received: by ksuvax1.cis.ksu.edu (5.59++/CIS1.1) id AA29025; Wed, 29 Aug 90
 09:20:19 CDT
Resent-Date: Wed, 29 Aug 90 10:22 EST
Date: 28 Aug 90 17:23:36 GMT
From: gjc@mitech.com
Subject: feature request in UUCP_MAILSHR, LIB$FIND_IMAGE_SYMBOL
Resent-To: VMSNET-LIST@DRYCAS.CLUB.CC.CMU.EDU
To: vmsnet@DRYCAS.CLUB.CC.CMU.EDU
Resent-Message-Id: <415EA694BDFF000DAC@DRYCAS.CLUB.CC.CMU.EDU>
Message-Id: <4671@mitech.com>
Organization: Mitech Corporation, Concord MA
X-Envelope-To: everhart%arisia.decnet@CRDGW1.GE.COM
X-Vms-To: vmsnet@DRYCAS.CLUB.CC.CMU.EDU

Here is a feature I have hacked into my UUCP_MAILSHR that has been on
the top of my wish-list for some time. If it could be added into the
standard DECUS UUCP release it should provide the kind of flexibility
that some sites need for mail rewrite rules. It uses two of the best
features of VMS, SYS$TRNLNM and LIB$FIND_IMAGE_SYMBOL.

This is how it works, by default, just like the old thing, but if
there is a logical name UUCP_ADDRESS_REWRITE_HANDLER defined then
a LIB$FIND_IMAGE_SYMBOL is done using that logical name to get
the init_transform and add_transform procedures to use.

The reason I need this: My un*x internet forwarder site is sending me
fully "!" style addresses, and I want to turn them into DOMAIN style
addresses. (By the way, most un*x guys cannot figure out how to hack
the sendmail.cf file in any but the most simple ways, so don't bother
asking them to send you addresses in more reasonable formats).

Anyway, you know that sometimes a page of easy-to-read-and-debug C
code is worth screenfulls of pattern-match-language code when there
is some real structure involved in the strings. I would much rather
see you guys add a simple use of LIB$FIND_IMAGE_SYMBOL than to
hack endlessly new string pattern match features to handle strange
cases.

The modification to GLUE.C is really simple to make, and there is
no performance or configuration complexity penalty if the feature is not used.

Enclosed is a sample main program CALLIF.C containing the new procedures
and suggested modifications to GLUE.C, and ADDTR.COM compiles and links
a sample sharable image.

$! ...................... Cut between dotted lines and save. .....................
$!.............................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.03 20-Oct-1988.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user GJC
$! on 28-AUG-1990 17:14:17.44.
$!
$! It contains the following 3 files:
$!        CALLIF.C
$!        ADDTR.C
$!        ADDTR.COM
$!
$!==============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.03 20-Oct-1988 requires VMS V4.4 or higher."
$ EXIT 44 
$VERSION_OK:
$ GOTO START
$
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY

b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) );
s_file_spec := GET_INFO( COMMAND_LINE, "output_file" );SET( OUTPUT_FILE, b_part
, s_file_spec ); 
b_errors := CREATE_BUFFER( "{Errors}" );i_errors := 0; 
pat_beg_1 := ANCHOR & "-+-+-+ Beginning";
pat_beg_2 := LINE_BEGIN & "+-+-+-+ Beginning";
pat_end := ANCHOR & "+-+-+-+-+ End";
pat_trail := " " & LINE_END;POSITION( BEGINNING_OF( b_part ) ); LOOP b 
:= SEARCH( pat_trail, FORWARD); EXITIF b=0; POSITION( END_OF( b ) )
; LOOP MOVE_HORIZONTAL( -1 ); EXITIF CURRENT_CHARACTER <> ' '; ERASE_CHARACTER
( 1 ); EXITIF CURRENT_OFFSET=0; ENDLOOP; ENDLOOP; POSITION( BEGINNING_OF
( b_part ) ); i_append_line := 0; LOOP EXITIF MARK( NONE ) = END_OF( b_part )
; s_x := ERASE_CHARACTER( 1 ); 
  IF s_x = "+" THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <
> 0 THEN 
      s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF; ENDIF; 
  IF s_x = "-" THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ); IF r_skip <
> 0 THEN 
      s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE )
; r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION
( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ); MOVE_VERTICAL( 1 )
; MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE
( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF; 
  IF s_x = "V" THEN 
    s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL
( -CURRENT_OFFSET ); ENDIF; i_append_line := 1; MOVE_VERTICAL( 1 ); ENDIF; 
  IF s_x = "X" THEN 
    s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL
( -CURRENT_OFFSET ); ENDIF; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; 
  IF s_x <> "" THEN i_errors := i_errors + 1; s_text := CURRENT_LINE; POSITION
( b_errors ); 
    COPY_TEXT( "The following line could not be unpacked properly:" )
; SPLIT_LINE; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part )
; MOVE_VERTICAL( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP 
  r_x := SEARCH( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x )
; ERASE_CHARACTER( 1 ); 
  IF CURRENT_CHARACTER = "`" THEN MOVE_HORIZONTAL( 1 ); ELSE COPY_TEXT( ASCII
( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDIF; ENDLOOP; IF i_errors = 0 THEN SET
( NO_WRITE, b_errors, ON ); ELSE POSITION( BEGINNING_OF( b_errors ) ); 
  COPY_TEXT( FAO( "The following !UL errors were detected while unpacking !AS"
, i_errors, s_file_spec ) ); SPLIT_LINE; 
  SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" );ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!,passed." )
$ RETURN
$
$START:
$ FILE_IS = "CALLIF.C"
$ CHECKSUM_IS = 1987758862
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/* code for [.uucp_mailshr.src], modifications to GLUE.C
X   to allow a dynamically loaded mail-rewrite rule
X   handler.`032
X
X   If a logical name exists we use LIB$FIND_IMAGE_SYMBOL
X   on that logical name in order to load the mail_rewrite code.
X
X   If the logical name does not exist then the usual code is called.
X
X   28-AUG-1990 George Carrette, Mitech Corporation. GJC@MITECH.COM
X*/
X
X#include <stdio.h>
X#include <descrip.h>
X#include <ssdef.h>
X#include <lnmdef.h>
X
Xinit_transform()
X`123printf("built-in init transform called\n");`125
X
Xchar *add_transform(addr,kind)
X     char *addr;
X     long kind;
X`123printf("built-in add transform called\n");
X return(addr);`125
X
X/* GLUE.C modifications:
X   in the function "rewrite_address"
X   change the call from init_transform to dyn_init_transform,
X   change the call from add_transform  to dyn_add_transform
X*/
X
X/* New code: the procedures dyn_init_transform, dyn_add_transform,
X             and load_dyn_transform.
X */
X
Xvoid (*ptr_init_transform)() = NULL;
Xchar * (*ptr_add_transform)() = NULL;
X
Xvoid dyn_init_transform()
X`123if (load_dyn_transform() == 0)
X   `123ptr_init_transform = NULL;
X    ptr_add_transform = NULL;`125
X if (ptr_init_transform != NULL)
X   (*ptr_init_transform)();
X else
X   init_transform();`125
X
Xchar *dyn_add_transform(addr,kind)
X     char *addr;
X     long kind;
X`123if (ptr_add_transform != NULL)
X   return((*ptr_add_transform)(addr,kind));
X else
X   return(add_transform(addr,kind));`125
X
X
X$DESCRIPTOR(dyn_rewrite_module,"UUCP_ADDRESS_REWRITE_HANDLER");
X$DESCRIPTOR(dyn_rewrite_lnm,"LNM$FILE_DEV");
X$DESCRIPTOR(dyn_init_transform_name,"init_transform");
X$DESCRIPTOR(dyn_add_transform_name,"add_transform");
X
Xload_dyn_transform()
X`123struct trnlnm_item
X   `123short buflen;
X    short code;
X    char *buffer;
X    short *retlen;`125 items[2];
X char buff[256];
X short retsize;
X int retval;
X items[1].buflen = 0;
X items[1].code = 0;
X items[0].buflen = sizeof(buff);
X items[0].code = LNM$_STRING;
X items[0].buffer = buff;
X items[0].retlen = &retsize;
X retval = sys$trnlnm(0,&dyn_rewrite_lnm,&dyn_rewrite_module,0,items);
X if (retval == SS$_NOLOGNAM) return(0);
X if (retval != SS$_NORMAL) `123lib$signal(retval); return(0);`125
X if (retsize == 0) return(0);
X retval = lib$find_image_symbol(&dyn_rewrite_module,
X`009`009`009`009&dyn_init_transform_name,
X`009`009`009`009&ptr_init_transform,
X`009`009`009`0090);
X if (retval != SS$_NORMAL) `123lib$signal(retval); return(0);`125
X retval = lib$find_image_symbol(&dyn_rewrite_module,
X`009`009`009`009&dyn_add_transform_name,
X`009`009`009`009&ptr_add_transform,
X`009`009`009`0090);
X if (retval != SS$_NORMAL) `123lib$signal(retval); return(0);`125
X return(1);`125
X`032
X
Xmain()
X`123char *x,*y;
X dyn_init_transform();
X x = "x!foo!bar";
X y = dyn_add_transform(x,1);
X printf("%s => %s\n",x,y);`125
X
$ GOSUB UNPACK_FILE
$ FILE_IS = "ADDTR.C"
$ CHECKSUM_IS = 1197614435
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X#include <stdio.h>
X
Xchar *add_transform(addr,kind)
X     char *addr;
X     long kind;
X`123char *c;
X printf("dynamic add_transform called\n");
X c = malloc(strlen(addr)+20);
X strcpy(c,"foo!bar!");
X strcat(c,addr);
X return(c);`125
X
Xinit_transform()
X`123printf("dynamic init_transform called\n");`125
X
$ GOSUB UNPACK_FILE
$ FILE_IS = "ADDTR.COM"
$ CHECKSUM_IS = 744182606
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$ z = f$env("DEFAULT")
X$ define UUCP_ADDRESS_REWRITE_HANDLER 'z'addtr.exe
X$ cc addtr.c
X$ link/share addtr.obj,sys$input:/opt
Xsys$library:vaxcrtl/share
Xuniversal=add_transform
Xuniversal=init_transform
$ GOSUB UNPACK_FILE
$ EXIT
