From:	SMTP%"RELAY-INFO-VAX@CRVAX.SRI.COM" 19-MAY-1993 09:39:49.58
To:	EVERHART
CC:	
Subj:	CD.COM: change-dir both VMS and Unix style, with path check

X400-Received:  by mta ixgate.gmd.de in /PRMD=GmD/ADMD=DbP/C=DE/; Relayed; Wed, 19 May 1993 14:34:23 +0200
X400-Received:  by /PRMD=DBMAIL/ADMD=DBP/C=DE/; Relayed; Wed, 19 May 1993 16:36:31 +0200
Date:  Wed, 19 May 1993 16:36:31 +0200
X400-Originator:  Oliver.Kellogg@RTT142.DASA.dbmail.dbp.de
X400-Recipients:  INFO-VAX@SRI.com
X400-MTS-Identifier:  [/PRMD=DBMAIL/ADMD=DBP/C=DE/;71534191503991/17241@BKC]
X400-Content-Type:  P2-1984 (2)
From:  Oliver.Kellogg@RTT142.DASA.dbmail.dbp.de
Message-ID:  <"13634191503991/4737 400*"@MHS>
To:  INFO-VAX <INFO-VAX@SRI.com>
Subject:  CD.COM: change-dir both VMS and Unix style, with path check

Hi out there,

It may've been done before, but if you missed it, here it is: a SET DEFAULT
that will check the validity of the target path before changing, and will
accept the VMS-DCL and Unix syntaxes for paths. Note that only *relative*
Unix-style paths are accepted, like "cd ../.." or "cd ~" (it's hard to
"cd /" under VMS :-)

In order to use this, you should define a symbol in your LOGIN.COM of the
sort:		$ cd :== @sys$login:cd.com

Enjoy if you can!

Oliver M. Kellogg, Software Engineering, DASA/Space Systems Group, Munich, FRG
E-mail: oliver.kellogg@rtt142.dasa.dbmail.dbp.de



$!-------------------------  START  --- CD.COM  ------------------------------
$! Copyright (C) Deutsche Aerospace AG, Space Systems, Munich, FRG
$! You may distribute this as long as above copyright notice remains intact.
$!
$! Unix-style Change Directory: check validity of new path before changing.
$! Program will accept both VMS and Unix path syntax ;
$!   however, absolute Unix paths are not allowed (i.e. no "cd /").
$! Author: Oliver.Kellogg@RTT142.DASA.dbmail.dbp.de
$!
$  echo = "write sys$output"
$  path = "''P1'"
$  strlen = f$length(path)
$  colon = f$locate(":",path)
$  lbracket = f$locate("[",path)
$  if colon .eq. strlen .and. lbracket .eq. strlen
$   then	! see if it's a logical name
$     if f$getdvi(path,"EXISTS") .eqs. "TRUE" then goto doit
$     goto check_unix_syntax	! if it's not a locical, it may be Unix
$  endif
$go_on:
$  if colon .ne. strlen
$   then		! we have a device; see if it exists
$     device = f$extract(0,colon,path)
$     tmpstr = f$getdvi(device,"EXISTS")
$     if tmpstr .nes. "TRUE"
$      then
$        echo "device does not exist"
$        exit
$     endif
$     tmpstr = f$trnlnm(device)		! See if `device' is a logical;
$     if tmpstr .nes. ""		!  if so, use its translation.
$      then		! recompute path and strlen using the translation
$        path = tmpstr + f$extract(colon+1,99,path)
$! Logical translation may result in strange intermittent "][" brackets.
$        path = path - "]["
$        strlen = f$length(path)
$     endif
$  endif
$  if f$extract(strlen-8,7,path) .eqs. ".000000"
$   then	! suppress any ending ".000000"
$     path = path - ".000000"
$     strlen = strlen - 7
$  endif
$  tmpstr = path
$  i = 0
$loop:		! Simulate back-to-front f$locate
$  tmplen = f$length(tmpstr)
$  j = f$locate(".",tmpstr)
$  if j .eq. tmplen then goto endloop
$  tmpstr = f$extract(j+1,99,tmpstr)
$  i = i + j + 1
$  goto loop
$endloop:
$  if i .eq. 0 then goto doit   ! not much interesting stuff to check...
$! Reconstruct the path such that the last directory in it
$!    appears outside the "[]", and followed by ".DIR" .
$! Example:   "[HILBERT.TRANS]"  is changed to  "[HILBERT]TRANS.DIR" 
$  newdir = f$extract(0,i-1,path)+"]" + f$extract(0,tmplen-1,tmpstr) + ".DIR"
$  if f$search(newdir) .eqs. "" ! check if it exists
$   then
$     echo "directory does not exist"
$     exit
$  endif
$doit:
$  set def 'path
$ exit
$check_unix_syntax:
$  firstchar = f$extract(0,1,path)
$  if firstchar .eqs. "/"
$   then
$     echo "cannot cd to filesystem root"
$     exit
$  endif
$  if f$extract(0,2,path) .eqs. "./"
$   then
$     path = path - "./"
$  endif
$  tmpstr = "["
$  seen_tilde = 0
$  if firstchar .eqs. "~"
$   then
$     if strlen .eq. 1
$      then
$        set def sys$login
$        exit
$     endif
$     tmpstr = "SYS$LOGIN:["
$     path = path - "~/"
$     if path .eqs. ".."
$      then	! hmm... this certainly needs refinement
$        echo "no privilege for attempted operation"
$        exit
$     endif
$     if f$extract(0,1,path) .eqs. "." then tmpstr = tmpstr + "."
$  endif
$one_up:
$  if f$extract(0,2,path) .eqs. ".."
$   then
$     tmpstr = tmpstr + "-"
$     path = path - ".."
$     if f$length(path) .eq. 0
$      then
$        path = tmpstr + "]"
$        goto common
$     endif
$     if f$extract(0,1,path) .eqs. "/"
$      then
$        path = path - "/"
$        goto one_up
$     endif
$  endif
$  strlen = f$length(path)
$replace_slash:
$  slash = f$locate("/",path)
$  if slash .ne. strlen
$   then
$     path = f$extract(0,slash,path) + "." + f$extract(slash+1,99,path)
$     goto replace_slash
$  endif
$  path = tmpstr + "." + path + "]"
$common:
$  strlen = f$length(path)
$  colon = f$locate(":",path)
$goto go_on
$!-------------------------------  END  -------------------------------------


