From: CSBVAX::CSBVAX::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 4-DEC-1988 15:21 To: MRGATE::"ARISIA::EVERHART" Subj: Re: ST Mail and Piping under VMS Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Tue, 29 NOV 88 12:36:39 PDT Received: from CitHex.Caltech.Edu by KL.SRI.COM with TCP; Tue, 29 Nov 88 12:12:25 PST Date: Tue, 29 Nov 88 07:11:13 PST From: carl@CitHex.Caltech.Edu (Carl J Lydick) Message-Id: <881129065412.1279@CitHex.Caltech.Edu> Subject: Re: ST Mail and Piping under VMS In-Reply-To: Your message <921@suned1.UUCP> dated 26-Nov-1988 To: suned1!efb@elroy.jpl.nasa.gov, info-vax@CitHex.Caltech.Edu > For some weeks have been looking for what may not exist. Have STC046 mail > on VMS4.6 MV_2. In st_msg:malias. a line: > general: |'@vms.comfile' > is supposed to grab the incoming message to pseudo user general. Not being > a wiz of writing to std_input under vms, I have tried in my VMS .com file > to either TYPE SYS$INPUT /out=news.file or COPY SYS$INPUT NEWS.FILE . Both > bright ideas generate news.file .. it is EMPTY, however. If capturing > stdinput is reserved to compiled code vice VMS DCL files, can anyone who > has tried this suggest a few lines which will get a PID for a file name and > cat the file destined for general to go to a named > device:[directy]00pid.ext ? To answer your immediate question: Create the file ST_BIN:VMS.COMFILE containing just the record: $ COPY 'F$STRING(P1-"<")' device:[directory]00'F$GETJPI("","PID")'.EXT At the very end of this message, you'll find the routine STC (as developed by Ken Adelman, now of TGV [KEN@TGV.COM]) uses to do file redirection. Back to your problem, the entry in ST_MSG:MALIAS. can, more generally, be of the form: general: |'@vms.comfile [arg1 [arg2 ... [arg7]]]'; Note that I've used single quotes; this permits you to imbed double quotes in the pipeline command arguments, which DCL will parse as usual. This lets you use arguments with characters that are special to DCL in the pipeline. DELIVR will pass the arguments as you gave them, followed by an extra argument specifying input redirection to the subprocess. The redirection argument is the last argument passed, and is a left angle bracket followed by the input filename. Thus, in general, to set up to process the message, you want to start your procedure with something like: $! Set up a reasonable default $ INPUT_FILE = F$TRNLNM("SYS$COMMAND") $! Now look for the last non-null argument $ N = 8 $ LBL0: IF P'N' .NES. "" THEN - !If this arg isn't null $ GOTO LBL1 !see if its redirection $ N = N - 1 !Point to next arg $ IF N .GT. 0 THEN GOTO LBL0 !Boundary check $! The code from here to LBL1 should be unreachable. If you get here $! no arguments were passed to the procedure, which probably means $! you've run the procedure other than via DELIVR. $ Write SYS$OUTPUT "No arguments specified" !Log the error $ GOTO LBL3 !and try to continue $ LBL1: IF F$EXTRACT(0,1,P'N') .EQS. "<" THEN GOTO LBL2 $! This should also be unreachable; if you get here, it means the $! last argument did not specify input redirection; this probably means $! you specified more than 7 user arguments in the record in MALIAS. $ WRITE SYS$OUTPUT "No redirection specified !Log the error $ GOTO LBL3 !and try to continue $ LBL2: INPUT_FILE = F$STRING(P1-"<") !strip the left angle bracket $ P'N' := !and null out the current arg $ LBL3: At this point, the string INPUT_FILE contains the best guess as to the filespec for input, and P1-P7 are whatever was specified in MALIAS. You then deal with this filename in whatever manner is appropriate to the way you're processing the message. A more complete description of what DELIVR does with the MALIAS record, complete with an example including the MALIAS entry, all data files, and the output file follows: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ The problem is that STmail (more precisely, the entire Software Tools package) incorporates a number of UNIXisms, one of which is the way the standard input, output, and error streams are redirected. The syntax used by DELIVR is a bit more general than what you're using in that it allows for records of the form: destination: |'command args' or: destination: |"command args" The former allows you to imbed double quotes in the arguments, which DCL parses as usual, so you can have arguments with imbedded spaces or special characters; if you want imbedded single quotes, you have to use the latter syntax, I think). At any rate, assuming the former syntax, DELIVR (or if you're using DCONTROL to allow multi-stream delivery, DELIVR-n (n a small integer) will spawn a subprocess (named MAILER_n, where n is a small integer uniquely identifying the subprocess) with a command of the form: $ command args X-ST-Status: N Return-path: Date: Tue, 29 Nov 88 05:26:50 PST From: carl (Carl J Lydick) @ CitHex.Caltech.Edu Message-Id: <881129052650.1253@CitHex.Caltech.Edu> Subject: Testing To: test @ CitHex.Caltech.Edu xxxxx This is the body of the message. xxxxx ************************************************************************ Where represents an actual control-A. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /* file redirection on VMS */ /********************************************************\ * usage: * * main(argc, argv) * * int argc; * * char *argv[]; * * { ... * * argc = file_redir(argc,argv); * * ... * * } * \********************************************************/ #include #include "../hfiles/symbols.h" int file_redir(argc,argv) int argc; char *argv[]; { int i; for (i=1; i') { /* output redirection */ if (argv[i][1] == '>') { if (freopen(&argv[i][2],"a",stdout) == NULL) { perror(&argv[i][2]); exit(ERREXIT); } argc = skip_argv(argc,argv,i); i--; } else { if (freopen(&argv[i][1],"w",stdout) == NULL) { perror(&argv[i][1]); exit(ERREXIT); } argc = skip_argv(argc,argv,i); i--; } } else if (argv[i][0] == '?') { /* stderr redirection */ if (argv[i][1] == '?') { if (freopen(&argv[i][2],"a",stderr) == NULL) { perror(&argv[i][2]); exit(ERREXIT); } argc = skip_argv(argc,argv,i); i--; } } } return(argc); } int skip_argv(argc,argv,n) int argc, n; char *argv[]; { register int i; for (i = n; i < argc; i++ ) argv[i] = argv[i+1]; argc--; return(argc); } ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Hope this helps.