From: moeller@gwdgv1.dnet.gwdg.de ("GWDGV1::MOELLER")
Newsgroups: comp.os.vms
Subject: REMPRTSMB 1.1 (VMS V5.5 fix) part 1 of 2
Date: 31 Aug 92 21:49:40 GMT
Organization: The Internet

$! ................... 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 11-JUN-1992 09:51:13.65.
$!
$! ATTENTION: To keep each article below 40 blocks (20480 bytes), this
$!            program has been transmitted in 2 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 1 file:
$!        REMPRTSMB.C
$!
$!============================================================================
$ 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 = 137336104
$ 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 "V1.1a"
X#else
X#define Version "V1.1s"
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
XV1.0  16-jul-1991 wjm: fix "#ifndef ASY_FAB" compilation by removing
X`009`009`009a superfluous statement;
X`009`009`009if "logname" ends in a quotation mark, consider
X`009`009`009it a complete network task (or foreign file) spec:
X`009`009`009don't look for options, don't append "filename.type".
XV1.1  11-jun-1992 wjm: workarea created by VMS V5.5 SMBSRVSHR is no longer
X`009`009`009quadword-aligned, round up pointer prior to use.
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 either
X(a) something ending in a quotation mark - it will be considered a complete
X`009file spec (e.g. network foreign file spec, or network task spec).
Xor
X(b) 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".
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
V#define Q_ALIGN(p) (((unsigned) p + 7) & `1267)`009/* round up to multiple of
X 8 */
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, &(7 + 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`009void *pwap,
X`009int *funcp,
X`009DESCR *dscp,
X`009unsigned *argp)
X`123
X`009WORKAREA *wap = (WORKAREA *) Q_ALIGN(pwap);
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`009void *pwap,
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`009void *pwap,
X`009int *funcp,
X`009DESCR *dscp,
X`009unsigned *argp)
X`123
X`009WORKAREA *wap = (WORKAREA *) Q_ALIGN(pwap);
X`009static unsigned init_job(char **, WORKAREA *);`009/* forward */
X`009static void abort_job(WORKAREA *);`009`009/* forward */
X
X
X`009switch(*funcp) `123
X`009  case PSM$K_OPEN:
X`009`009*argp = PSM$K_CC_INTERNAL;
X
X`009`009return init_job(ctxp,wap);`009`009/* continues via AST */
X`009`009break;
X
X`009  case PSM$K_READ:
X`009`009return RMS$_EOF;
X`009`009break;
X
X`009  case PSM$K_CLOSE:
X`009`009return SS$_NORMAL;
X`009`009break;
X
X`009  case PSM$K_CANCEL:
X`009  case PSM$K_STOP_TASK:
X`009  case PSM$K_RESET_STREAM:
X`009`009abort_job(wap);`009`009/* ggf. cancel open loop */
X`009  default:
X`009`009return PSM$_FUNNOTSUP;
X`009`009break;
X`009`125
X`125
X
X/*****`009job trailer page: close output file`009*****/
X
Xstatic unsigned remprt_job_trailer(
X`009char **ctxp,
X`009void *pwap,
X`009int *funcp,
X`009DESCR *dscp,
X`009unsigned *argp)
X`123
X`009WORKAREA *wap = (WORKAREA *) Q_ALIGN(pwap);
X`009static unsigned close_job(char **, WORKAREA *);`009/* forward */
X`009static void abort_job(WORKAREA *);`009`009/* forward */
X
X
X`009switch(*funcp) `123
X`009  case PSM$K_OPEN:
X`009`009*argp = PSM$K_CC_INTERNAL;
X
X`009`009switch(wap->wk_state) `123
X`009`009  case putting:
X`009`009  case opened:
X`009`009`009return close_job(ctxp,wap);`009/* continue via AST`009*/
X`009`009`009break;
X`009`009`125
X`009`009return SS$_NORMAL;
X`009`009break;
X
X`009  case PSM$K_READ:
X`009`009return RMS$_EOF;
X`009`009break;
X
X`009  case PSM$K_CLOSE:
X`009`009return SS$_NORMAL;
X`009`009break;
X
X`009  case PSM$K_STOP_TASK:`009`009`009/* asynch. abort`009*/
X`009`009switch(wap->wk_state) `123
X`009`009  case putting:
X`009`009  case opened:
X`009`009`009abort_job(wap);
X`009`009`009break;
X`009`009`125
X`009  default:
X`009`009return PSM$_FUNNOTSUP;
X`009`009break;
X`009`125
X`125
X
X/*****`009job startup (triggered by job_flag)`009*****/
X
Xstatic unsigned init_job(
X`009char **ctxp,
X`009WORKAREA *wap)
X`123
X`009unsigned status;
X`009int l;
X`009char /*logical*/ opt_username,opt_spool,opt_jobname,opt_rsx;
X`009char *lp, *lp1, *lp2, *optp;
X`009static unsigned short lnml;
X`009static char devlnm[32], line[256];
X`009static DESCR devlnmdsc = `1230-0,0,0,devlnm`125;
X`009static const $DESCRIPTOR(linedsc,line);
X`009static const $DESCRIPTOR(lnmtabdsc,"LNM$FILE_DEV");
X`009static struct `123
X`009`009unsigned short len;
X`009`009unsigned short code;
X`009`009void *addr;
X`009`009void *retlen;
X`009`125 itmlst[2] = `123
X`009`009`123sizeof(line)-1, LNM$_STRING, line, &lnml`125,
X`009`009`1230, 0, NULL, NULL`125
X`009`125;
X
X
X`009/*****`009link state must be =closed !!!`009****/
X
X`009if(wap->wk_state != closed) `123
X`009`009lib$stop(0x10000004,1,wap->wk_state);`009/* crash ...`009*/
X`009`125
X
X`009/***** "device name" and options *****/
X
X`009opt_username = 0;
X`009opt_jobname = 0;
X`009opt_rsx = 0;
X`009opt_spool = 0;
X
X`009devlnmdsc.dsc$w_length = sizeof(devlnm)-1;
X`009devlnm[0] = '\0';
X`009psm$read_item_dx(ctxp,&SMBMSG$K_DEVICE_NAME,&devlnmdsc);
X`009devlnm[itrmlen(&devlnmdsc)] = '\0';
X
X`009l = strlen(devlnm);
X`009if(l > 0 && devlnm[l-1] == ':') `123
X`009`009devlnm[--l] = '\0';`009/* ggf. remove trailing ':' */
X`009`125
X
X`009devlnmdsc.dsc$w_length = l;
X`009status = sys$trnlnm(NULL, &lnmtabdsc, &devlnmdsc, NULL, &itmlst);
X`009if((status & 1) == 0) return status;
X
X`009l = lnml;
X`009line[l] = '\0';
X
X`009if(l > 0 && line[l-1] == '"') `123`009`009/* quoted output spec ... */
X`009`009strcpy(wap->wk_file,line);`009/* copy unchanged */
X`009`009goto file_name_ok;
X`009`125
X
X`009for(lp=line; *lp != '\0'; lp++)
X`009`009*lp = toupper(*lp);`009/* upcase device & options */
X
X`009optp = strchr(line,'/');
X`009if(optp == NULL) optp = line + strlen(line);
-+-+-+-+-+ End of part 1 +-+-+-+-+-