From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 25-JUN-1991 05:44:52.08
To:	ARISIA::EVERHART
CC:	
Subj:	REMPRTSMB part 1 of 3

From:	RELAY-INFO-VAX@CRVAX.SRI.COM@SMTP@CRDGW2
To:	Everhart@Arisia@MRGATE

Received:  by crdgw1.ge.com (5.57/GE 1.101)
	 id AA06467; Tue, 25 Jun 91 05:35:53 EDT
Message-Id:  <9106250935.AA06467@crdgw1.ge.com>
Received: From CUNYVM.CUNY.EDU by CRVAX.SRI.COM with TCP; Tue, 25 JUN 91 02:10:55 PDT
Received: from DGOGWDG1.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.2.2MX) with BSMTP id 5980; Tue, 25 Jun 91 05:10:36 EDT
Received: from dnet.gwdg.de by DGOGWDG1.BITNET (Mailer R2.07) with BSMTP id
 2232; Tue, 25 Jun 91 11:06:35 MSZ
Date:    Tue, 25 Jun 1991 11:06:24 +0200
From: "GWDGV1::MOELLER" <moeller%gwdgv1.dnet.gwdg.de@CUNYVM.CUNY.EDU>
To: info-vax@sri.com, vmsnet-sources@ucbvax.berkeley.edu
Subject: REMPRTSMB part 1 of 3

$! ................... Cut between dotted lines and save. ...................
$!...........................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.10 7-FEB-1989.
$!
$! 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 MOELLER
$! on 25-JUN-1991 10:24:19.85.
$!
$! ATTENTION: To keep each article below 31 blocks (15872 bytes), this
$!            program has been transmitted in 3 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 5 files:
$!        REMPRTSMB.C
$!        ITRMLEN.MAR
$!        PRVDEF.H
$!        PSMDEF.H
$!        SMBDEF.H
$!
$!============================================================================
$ 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.10 7-FEB-1989 requires VMS V4.4 or higher."
$ EXIT 44 ! SS$_ABORT
$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"; POSITION
( BEGINNING_OF( b_part ) ); LOOP EXITIF SEARCH( SPAN( ' ' )@r_trail
& LINE_END, FORWARD) = 0; POSITION( r_trail ); ERASE( r_trail ); 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
); COPY_TEXT( ASCII( INT( ERASE_CHARACTER( 3 ) ) ) ); 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 = "REMPRTSMB.C"
$ CHECKSUM_IS = 1733732253
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*****`009multithreaded output-redirection symbiont`009*****/
X
X#define ASY_FAB`009`009/* <<< allegedly requires VMS V5 <<< */
X#ifdef ASY_FAB
X#define Version "V0.99"
X#else
X#define Version "V0.98"
X#endif
X
X/*****
X`009w.j.m. jul 1988, after XXXSMB V0.3
X
XV0.95 21-jul-1988 wjm: set SPL & DLT bits on open, not on close (for DAP)
XV0.96 27-jul-1988 wjm: fix handling of immediate $PUT error
XV0.97 11-sep-1989 wjm: set procname to REMPRTSMB_n
XV0.98 07-jun-1990 wjm: fix incompatible change of <prvdef.h> by supplying own
X`009`009`009"prvdef.h"; add /RSX and /JOBNAME options;
X`009`009`009some fixes; use ITRMLEN() now;
X`009`009`009for simplicity, use same SPL/DLT setting on`032
X`009`009`009open AND close (not tested on RSX anyway);
XV0.99 ................. (VMS V5) #ifdef ASY_FAB, finally implement FAB$M_ASY
X
X********
X
Xintended use:
X`009$ ini/queue  ...  /proc=REMPRTSMB`009-`009! this image
X`009`009/separate=(flag,trailer)`009-
X`009`009/on=logname
X
Xwhere 'logname' translates to something like "node::dev:[dir]/opt"
X(one of "node::" or "dev:" must be present, "[dir]" and "/opt" are optional).
Xwithout "/opt", the output files will be named "node::dev:[dir]VAX.PRT".
X
Xpossible options ('/opt') are:
X`009/USERNAME  ...`009use VMS username instead of "VAX" for default filespec.
X`009/JOBNAME   ...`009if JOB_NAME has legal "fff.vvv" format, use it for
X`009`009`009output filespec (neither "fff" nor "vvv" may be void);
X`009`009`009if it is just "fff", output filespec => "fff.PRT".
X`009/RSX `009   ...`009require RSX-compatible JOB_NAME, or otherwise
X`009`009`009force output filespec into RSX-compatible format.
X`009/SPOOL`009  ...`009creates output file with "print/delete" option
X
X*****/
X
X/*****`009internals:
X`009assume that only 1 input routine is active (1 scb-pointer only).
X`009assume that output routine may be called without wait for
X`009`009completion, with a different scb-pointer for each buffer.
X*****/
X
X#module REMPRTSMB Version
X
X/*****/
X
X#include stddef
X#include ctype
X#include string
X#include descrip
Xtypedef struct dsc$descriptor DESCR;
X
X/*****/
X
X#include lnmdef
X
X#define LIB$K_VM_FIXED 4`009/* actually defined in $LIBVMDEF */
X
X#include fab
X#include rab
X
X#include "smbdef.h"
X#include "psmdef.h"
X#include "prvdef.h"`009`009/* NOT the one from VAXC 3.x */
X
Xglobalvalue PSM$_EOF, PSM$_FUNNOTSUP, PSM$_PENDING;
Xglobalvalue RMS$_EOF, SS$_NORMAL, SS$_IVLOGNAM;
X
Xextern int itrmlen(DESCR *);
X
Xextern unsigned psm$replace(const int *, unsigned (*)());
Xextern unsigned psm$print(const int *, const int *, const int *);
Xextern unsigned psm$report(char **, ...);
Xextern unsigned psm$read_item_dx(char **, const int *, DESCR *);
X
Xextern unsigned lib$analyze_sdesc(const DESCR *, unsigned short *, char **);
Xextern void lib$stop(unsigned, ...);
Xextern unsigned lib$insv(const int *, const int *, const int *, void *);
Xextern unsigned lib$insqti(void *, double *q, ...);
Xextern unsigned lib$insqhi(void *, double *q, ...);
Xextern unsigned lib$remqhi(double *q, void **, ...);
Vextern unsigned lib$create_vm_zone(unsigned *, const unsigned *, const int *)
X;
Xextern unsigned lib$get_vm(const int *, void **, ...);
Xextern unsigned lib$free_vm(const int *, void **, ...);
X
Xextern unsigned sys$trnlnm(const unsigned *, const DESCR *, const DESCR *,
X`009`009`009`009const unsigned char *, const void *);
Xextern unsigned sys$setprv(unsigned, const void *, unsigned, void *);
Xextern unsigned sys$setprn(const DESCR *);
Xextern unsigned sys$bintim(const DESCR *, void *);
Xextern unsigned sys$setimr(unsigned, const void *, void (*)(), unsigned);
Xextern unsigned sys$cantim(unsigned, unsigned);
Xextern unsigned sys$dclast(void (*)(), unsigned, unsigned);
Xextern unsigned sys$create(struct FAB *, ...);
Xextern unsigned sys$connect(struct RAB *, ...);
Xextern unsigned sys$put(struct RAB *, ...);
Xextern unsigned sys$disconnect(struct RAB *, ...);
Xextern unsigned sys$close(struct FAB *, ...);
X
X/*****/
X
X#define BLOCK_SIZE 512`009`009/* max. output record size */
X
Xtypedef enum linkstate `123
X`009init,`009/* == 0 !!!`009`009*/
X`009open1,`009/* initial $open to be done */
X`009open1t,`009/* timer pending, $open to be retried`009*/
X#ifdef ASY_FAB
X`009open2,`009/* $connect pending`009*/
X#endif
X`009open3,`009/* $connect pending`009*/
X`009opened,
X`009putting,/* $put pending`009`009*/
X`009close1,`009/* $disconnect to be done`009*/
X`009close2,`009/* $disconnect pending`009*/
X#ifdef ASY_FAB
X`009close3,`009/* $close pending`009*/
X#endif
X`009aborting,
X`009closed
X`125 LINKSTATE;
X
Xtypedef struct outputqelt `123
X`009double oqlink;`009`009/* offset=0, q-aligned !!!`009*/
X`009char *scbp;
X`009char *op;
X`009int olen;
X`125 OUTPUTQELT;
X#define OLEN_CLOSE (-1)`009`009/* special <olen> value`009*/
X#define OLEN_ABORT (-2)`009`009/* special <olen> value`009*/
X
Xtypedef struct workarea `123
X`009double wk_oqhead;`009/* q-aligned quadword !!!`009*/
X`009OUTPUTQELT *wk_curqp;
X`009LINKSTATE wk_state;
X`009char *wk_scbp;`009`009/* pointer for psm$report */
X        struct FAB wk_fab;
X        struct RAB wk_rab;
X`009char wk_file[256];`009/* output filespec */
X
X`009unsigned wk_spool:1;`009/* flag: open with SPL & DLT`009*/
X`125 WORKAREA;
X
X/*****/
X
Xstatic void rms_ast(struct RAB *);`009`009/* forward */
X
Xstatic unsigned oq_vm_zone = 0;
Xstatic OUTPUTQELT *oq_alloc(void);`009`009/* forward */
X
X#define oq_free(p) `123unsigned stat;\
X`009if(((stat=lib$free_vm(&sizeof(OUTPUTQELT),&p,&oq_vm_zone))&1)==0)\
X`009`009lib$stop(stat`1240x10000000);`125
X
X#ifdef OPTRACE
X#define OPMSG(s) opermsg(s)
X#else
X#define OPMSG(s)
X#endif
X
X
X/*****`009"main" program - must come first (not declared to VAXC) *****/
X
Xunsigned remprtsmb_main()
X`123
X`009static unsigned`009`009`009/* forward */
X`009`009remprt_job_flag(),
X`009`009remprt_job_trailer(),
X`009`009remprt_output(),
X`009`009remprt_input_nop();
X`009static struct replacetab `123
X`009`009int type;
X`009`009unsigned (*routine)();
X`009`009`125 replace_tab[] = `123
X`009`009`009`009/* always */
X`009/* o.k.`009`009PSM$K_JOB_SETUP`009`009`009`009*/
X`009`009`009`009/* always */
X`009/* o.k.`009`009PSM$K_FORM_SETUP`009`009`009*/
X`009`009`009`009/* JOBCTL separate, 1st file */
X`009/* >>>>`009*/`009`123PSM$K_JOB_FLAG, remprt_job_flag`125,
X`009`009`009`009/* JOBCTL separate, 1st file */
X`009`009`009`123PSM$K_JOB_BURST, remprt_input_nop`125,
X`009`009`009`009/* always */
X`009/* o.k.`009`009PSM$K_FILE_SETUP`009`009`009*/
X`009`009`009`009/* JOBCTL default */
X`009/* o.k.`009`009PSM$K_FILE_FLAG`009`009`009`009*/
X`009`009`009`009/* JOBCTL default */
X`009/* o.k.`009`009PSM$K_FILE_BURST`009`009`009*/
X`009`009`009`009/* always */
X`009/* o.k.`009`009PSM$K_FILE_SETUP_2`009`009`009*/
X`009`009`009`009/* always 1 of the following ... */
X`009/* o.k. */`009/* FILE_ERRORS, FILE_INFORMATION, MAIN_INPUT */
X`009`009`009`009/* JOBCTL default */
X`009/* o.k.`009`009PSM$K_FILE_TRAILER`009`009`009*/
X`009`009`009`009/* JOBCTL separate, last file */
X`009`009`009`123PSM$K_JOB_RESET, remprt_input_nop`125,
X`009`009`009`009/* JOBCTL separate, last file */
X`009/* >>>> */`009`123PSM$K_JOB_TRAILER, remprt_job_trailer`125,
X`009`009`009`009/* always (trailing FF) */
X`009/* o.k.`009`009PSM$K_JOB_COMPLETION`009`009`009*/
X
X`009`009/* "nested" routines */
X`009`009`009`009/* JOBCTL default, or user spec'd */
X`009/* o.k.`009`009PSM$K_PAGE_HEADER`009`009`009*/
X`009`009`009`009/* JOBCTL default */
X`009/* o.k.`009`009PSM$K_PAGE_SETUP`009`009`009*/
X`009`009`009`009/* coroutines */
X`009/* o.k. */`009/* MAIN_FORMAT, LIBRARY_INPUT */
X`009`009`009`009/* output routine */
X`009/* >>>> */`009`123PSM$K_OUTPUT, remprt_output`125,
X
X`009`009/* that's all for VMS 4.x */
X`009`009`009`123NULL, NULL`125`125;
X
X`009unsigned status;
X`009unsigned privs[2] = `1230, 0`125;
X`009struct replacetab *i;
X
X`009/* set privileges - have only SETPRV */
X`009lib$insv(&1,&PRV$V_TMPMBX,&1,&privs);
X`009lib$insv(&1,&PRV$V_NETMBX,&1,&privs);
X`009lib$insv(&1,&PRV$V_READALL,&1,&privs);
X`009status = sys$setprv(1,&privs,0,NULL);
X`009if((status & 1) == 0) return status `124 0x10000000;
X
X`009/* replace routines listed in above table */
X`009for(i = replace_tab; i->type != NULL; i++) `123
X`009`009status = psm$replace(&(i->type),i->routine);
X`009`009if((status & 1) == 0) return status `124 0x10000000;
X`009`125
X
X`009/* set process name */
X`009`123`009char prn[] = "REMPRTSMB_0";`009/* to be modified */
X`009`009$DESCRIPTOR(prn_dsc,prn);
X
X`009`009do `123
X`009`009`009prn[sizeof(prn)-2]++;
X`009`009`125 while((sys$setprn(&prn_dsc) & 1) == 0 &&
X`009`009`009prn[sizeof(prn)-2] < '9');
X`009`125
X
X`009/* start - 8 threads maximum */
X`009status = psm$print(&8, &BLOCK_SIZE, &sizeof(WORKAREA));
X`009return status `124 0x10000000;
X`125
X
X/*****`009symbiont output routine`009`009*****/
X
Xstatic unsigned remprt_output(
X`009char **ctxp,`032
X`009WORKAREA *wap,
X`009int *funcp,
X`009DESCR *dscp,
X`009unsigned *argp)
X`123
X`009unsigned status;
X`009unsigned short buflen;
X`009char *bufp;
X`009static void init_wk(WORKAREA *);`009/* forward */
X`009static unsigned put_out(char *, WORKAREA *, char *, unsigned short);
X`009static void abort_job(WORKAREA *);`009/* forward */
X
X
X`009if(wap->wk_state == init) `123
X`009`009init_wk(wap);`009`009/* 1st time init`009*/
X`009`125
X
X`009switch(*funcp) `123
X`009  case PSM$K_OPEN:
X`009`009*argp = (1 << SMBMSG$V_SERVER) `124
X`009`009`009(1 << SMBMSG$V_LOWERCASE);
X
X`009`009return SS$_NORMAL;`009/* no real action yet`009*/
X`009`009break;
X
X`009  case PSM$K_WRITE:
X`009  case PSM$K_WRITE_NOFORMAT:
X`009`009switch(wap->wk_state) `123
X`009`009  case putting:
X`009`009  case opened:
X`009`009`009status = lib$analyze_sdesc(dscp,&buflen,&bufp);
X`009`009`009if((status & 1) == 0) lib$stop(status `124 0x10000000);
X`009`009`009return put_out(ctxp,wap,bufp,buflen); /* asynch. */
X`009`009`009break;
X`009`009`125
X`009`009return SS$_NORMAL;`009/* (fake) */
X`009`009break;
X
X`009  case PSM$K_CLOSE:
X`009`009abort_job(wap);
X`009`009return SS$_NORMAL;
X`009`009break;
X
X`009  default:
X`009`009return PSM$_FUNNOTSUP;
X`009`009break;
X`009`125
X`125
X
X/*****`009no-op input routine (replaces undesired PSM routines) *****/
X
Xstatic unsigned remprt_input_nop(
X`009char **ctxp,
X`009WORKAREA *wap,
X`009int *funcp,
X`009DESCR *dscp,
X`009unsigned *argp)
X`123
X`009switch(*funcp) `123
X`009  case PSM$K_OPEN:
X`009`009*argp = PSM$K_CC_INTERNAL;
X`009`009/* drop thru */
X`009  case PSM$K_CLOSE:
X`009`009return SS$_NORMAL;
X`009`009break;
X
X`009  case PSM$K_READ:
X`009`009return PSM$_EOF;
X`009`009break;
X
X`009  default:
X`009`009return PSM$_FUNNOTSUP;
X`009`009break;
X`009`125
X`125
X
X/*****`009job flag page: open output`009*****/
X
Xstatic unsigned remprt_job_flag(
X`009char **ctxp,
X`009WORKAREA *wap,
X`009int *funcp,
X`009DESCR *dscp,
X`009unsigned *argp)
X`123
X`009static unsigned init_job(char **, WORKAREA *);`009/* forward */
X`009static void abort_job(WORKAREA *);`009`009/* forward */
X
-+-+-+-+-+ End of part 1 +-+-+-+-+-

