From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  2-AUG-1989 09:24
To:	MRGATE::"ARISIA::EVERHART"
Subj:	UNIX-like cd.

Received: From KL.SRI.COM by GIZMO.SRI.COM with TCP; Wed,  2 AUG 89 05:18:37 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Wed, 2 Aug 89 04:49:44 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.37)
	id AA15532; Wed, 2 Aug 89 04:47:23 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 2 Aug 89 09:39:47 GMT
From: mcvax!kth!sunic!chalmers!me.chalmers.se!lej@uunet.uu.net  (Lars-Erik Johansson)
Organization: Dep. of Mechanical Engineering, Chalmers , Sweden.
Subject: UNIX-like cd.
Message-Id: <28@me.chalmers.se>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com


Here is a UNIX-like cd program. I'm running it under VMS 4.4.

                Good luck /Lars-Erik

$create/log CD.C
$deck/dollars="#890802-102259#"
/*---------------------------------- cd.c ----------------------------------*
 *------------------------------ Version 1.01 ------------------------------*
 *                                                                          *
 * DEC doesn't support a proper way of changing default directory.          *
 *                                                                          *
 * 1:st A VMS directory specification is no good. You have to press         *
 * such a lot of different delimiters. (e.g. "cd .." v.s "set def [-]")     *
 *                                                                          *
 * 2:nd SET DEFAULT don't check whether or not the directory                *
 * actually exists.                                                         *
 *                                                                          *
 * The syntax of cd is:                                                     *
 *                                                                          *
 * cd 'directory'                                                           *
 *                                                                          *
 * Where 'directory' is a directory specification in UN*X syntax. The       *
 * translation rules are quite simple:                                      *
 *                                                                          *
 * cd 		  --> set def sys$login                                     *
 * cd ~/dir1	  --> set def disk1:[me.dir1] (if sys$login = disk1:[me])   *
 * cd dir1/dir2   --> set def [.dir1.dir2]                                  *
 * cd /dir1/dir2  --> set def [dir1.dir2]                                   *
 * cd /disk1/dir1 --> set def disk1:[dir1]                                  *
 * cd ../dir1	  --> set def [-.dir1]                                      *
 * cd /		  --> set def [000000]                                      *
 * cd /disk1	  --> set def disk1:[000000]                                *
 *                                                                          *
 * If the first character is a slash the program will check if the first    *
 * word specifies a disk. If the first disk does not specify a disk, cd     *
 * assume that it is a top directory on the actual disk.                    *
 *                                                                          *
 *--------------------------------------------------------------------------*
 * Author:                                                                  *
 * Lars-Erik Johansson                                                      *
 * lej@me.chalmers.se                                                       *
 *                                                                          *
 *--------------------------------------------------------------------------*
 * Revision history:                                                        *
 * V1.01	89-01-01	First edition.                              *
 *                                                                          *
 *--------------------------------------------------------------------------*
 * Known bugs:                                                              *
 *                                                                          *
 * If you have a logical name for eg user1 and also a top directory [user1] *
 * you will not be able to cd to [user1] unless user1 = thisdisk:[user1.].  *
 * This is actualy not a bug, but a matter of priority, parsing directory   *
 * names.                                                                   *
 *                                                                          *
 * The directory specification dir1/../dir2 is not a valid directory        *
 * specification in this program.                                           *
 * I could fix it but what use would that be?                               *
 *                                                                          *
 *--------------------------------------------------------------------------*/

#include <stdio.h>
#include <descrip.h>
#include <dvidef.h>

char	dir_str[256];		/* a backup copy of argv[1]		*/

main(argc,argv)
int	argc;
char	**argv;
{
  char	*parameters[20];	/* I don't suppose there will be	*/
				/* more than 20 parameters		*/
  int	number_of_params,	/* how many were there actually		*/
	i,			/* Loop variable			*/
	argument_start = 0,
	home_related = FALSE,	/* Is the directory related to home	*/
	disk_search = FALSE;	/* Should I try to find a disk ?	*/

  /*
   * If no parameter is sent then go home
   */
  if(argc < 2) {
    my_home();
    exit();
  } else {
    /*
     * otherwise copy the first parameter to the global dir_str
     */
    strcpy(dir_str,argv[1]);
  }

  /*
   * If the string starts whith "~/", it is specifying a directory
   * under sys$login.
   */
  if((argv[1][0] == '~') && (argv[1][1] == '/')) {
    if(strlen(argv[1]) == 2) {
      my_home();
      exit();
    } else {
      home_related = TRUE;
      argument_start = 2;		/* we must mask away ~/ */
    }
  }

  /*
   * If first character is a slash then see if it is the only
   */
  if(argv[1][0] == '/') {
    if(strlen(argv[1]) == 1) {
      /*
       * If it is, go to root of this disk and exit
       */
      my_chdir("[000000]");
      exit();
    } else {
      /*
       * If it is not, make sure to search for any logical disk
       */
      disk_search = TRUE;
    }
  }

  /*
   * Send the parameter to the parser that will split it up into
   * chunks. e.g. /user1/foo/bar will bw split into user1, foo and bar.
   */
  number_of_params = parse_params(&argv[1][argument_start],parameters);

#ifdef DEBUG
  printf("antal = %d\n",number_of_params);
  for(i = 0 ; i < number_of_params ; i++) {
    printf("%d : %s\n",i,parameters[i]);
  }
#endif

  /*
   * If the result of parse is anything at all,
   * I'll do my very best.
   */
  if(number_of_params > 0) {
    /*
     * This will try to find a directory matching
     * the parsed parameter.
     */
    if(disk_search) {
      if(is_disk(parameters[0])) {
        try_disk(number_of_params,parameters);
      } else {
        try_abs_dir(number_of_params,parameters);
      }
    } else if(home_related) {
      try_home_related(number_of_params,parameters);
    } else {
      try_rel_dir(number_of_params,parameters);
    }
  } else {
    printf("You can't change directory to nowhere.\n");
  }
}

/*---------------------------- parse_params() ------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure parse_params is to have 2 arguments.                       *
 *                                                                          *
 * - line       is a caharcter string containing the line which is          *
 *              to be parsed.                                               *
 *                                                                          *
 * - parameters is an array of character strings where the                  *
 *              result of the parsing is placed.                            *
 *                                                                          *
 * The parser will ignore any ocurrance multipple slashes e.g. "///".       *
 * parse_params will split a character string into pieces. Delimiters       *
 * are slashes. e.g.                                                        *
 *                                                                          *
 *                                +--> "usr"                                *
 *                                |                                         *
 * "///usr/local///////src/"   ---+--> "local"                              *
 *                                |                                         *
 *                                +--> "src"                                *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
parse_params(line,parameters)
char	*line,
	**parameters;
{
  int	i = 0,
	j = 0,
	length;

  /*
   * During the parsing i put '\0' in line therefore i must
   * determine the original length of it emediately.
   */
  length = strlen(line);

  /*
   * The syntax in the beginning of the line is special
   * therefor i take special care of that.
   */
  if(line[0] == '/') {
#ifdef DEBUG
printf("  > %c <  \n",line[0]);
#endif
    for(i = 1 ; i < length ; i++) {
      if(line[i] != '/') {
#ifdef DEBUG
printf("    %c <--\n",line[i]);
#endif
        parameters[0] = &line[i];
        j++;
        break;
      }
#ifdef DEBUG
printf("    %c\n",line[i]);
#endif
    }
  } else {
#ifdef DEBUG
printf("    %c <--\n",line[0]);
#endif
    parameters[0] = &line[0];
    j++;
  }

  for(++i ; i < length ; i++) {
    if(line[i] == '/') {
#ifdef DEBUG
printf("  > %c <  \n",line[i]);
#endif
      line[i] = '\0';
      for(++i ; i < length ; i++) {
        if(line[i] != '/') {
#ifdef DEBUG
printf("    %c <--\n",line[i]);
#endif
          parameters[j] = &line[i];
          j++;
          break;
        }
#ifdef DEBUG
else {
printf("    %c\n",line[i]);
}
#endif
      }
    }
#ifdef DEBUG
else {
printf("--> %c\n",line[i]);
}
#endif
  }
  return(j);
}


/*-------------------------------- my_chdir() ------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure my_chdir is to have 1 argument.                            *
 *                                                                          *
 * - dir is a caharcter string containing the name of the directory         *
 *       which is to be set to default.                                     *
 *       The directory specification is in the VMS syntax.                  *
 *                                                                          *
 * my_chdir don't check whether or not the directory exists.                *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
my_chdir(dir)
char	*dir;
{
  int	ret,
	len;
  struct dsc$descriptor	dir_des;

  dir_des.dsc$w_length = strlen(dir);
  dir_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  dir_des.dsc$b_class = DSC$K_CLASS_S;
  dir_des.dsc$a_pointer = dir;

  /*
   * The systtem call that does it.
   */
  ret = sys$setddir(&dir_des,0,0);

  /*
   * ODD reurn values indicate successful completeion
   */
  if(ret & 1) {	
#ifdef DEBUG
    printf("Set Def %s\n",dir);
#endif
  } else {
    exit(ret);
  }
}

/*------------------------------ my_chdisk() -------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure my_chdisk is to have 1 argument.                           *
 *                                                                          *
 * - disk is a caharcter string containing the name of the disk             *
 *        which is to be set to default.                                    *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
my_chdisk(disk)
char	*disk;
{
  int	ret,
	len;
  char	 *name = "SYS$DISK";
  struct dsc$descriptor	name_des,
			disk_des;

  up_case(disk);

  name_des.dsc$w_length = strlen(name);
  name_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  name_des.dsc$b_class = DSC$K_CLASS_S;
  name_des.dsc$a_pointer = name;

  disk_des.dsc$w_length = strlen(disk);
  disk_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  disk_des.dsc$b_class = DSC$K_CLASS_S;
  disk_des.dsc$a_pointer = disk;

  ret = lib$set_logical(&name_des,&disk_des,0,0,0);

  if(ret & 1) {
#ifdef DEBUG
    printf("Set Disk %s\n",disk);
#endif
  } else {
    exit(ret);
  }

}


/*----------------------------- try_rel_dir() ------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure try_rel_dir is to have 2 arguments.                        *
 *                                                                          *
 * - nr_of_args                                                             *
 *                                                                          *
 * - args is an array of character strings containing                       *
 *        the parsed arguments.                                             *
 *                                                                          *
 * The function figures out if str is a disk or not.                        *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
try_rel_dir(nr_of_args,args)
int	nr_of_args;
char	**args;
{
  char	str[256],
	str2[256];
  int	i,
	only_up = TRUE;

  sprintf(str2,"[");
  for(i = 0 ; i < nr_of_args ; i++) {
    if(strcmp(args[i],"..") != 0) {
      only_up = FALSE;
      break;
    }
    strcat(str2,"-");
  }
  for(i ; i < (nr_of_args - 1) ; i++) {
    strcat(str2,".");
    strcat(str2,args[i]);
  }
  strcpy(str,str2);

  if(!only_up) {
    strcat(str2,"]");
    strcat(str2,args[i]);
    strcat(str2,".dir");

    strcat(str,".");
    strcat(str,args[i]);
    strcat(str,"]");
#ifdef DEBUG
printf("Str i relativ  :==: %s\n",str);
printf("Str2 i relativ :==: %s\n",str2);
#endif
    if(exists(str2)) {
      my_chdir(str);
    } else {
      no_such();
    }
  } else {
    strcat(str,"]");
#ifdef DEBUG
printf("str - %s\n",str);
#endif
    if(to_high(str)) {
      my_chdir("[000000]");
    } else {
      my_chdir(str);
    }
  }
}

/*------------------------------ try_abs_dir() -----------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure try_rel_dir is to have 2 arguments.                        *
 *                                                                          *
 * - nr_of_args                                                             *
 *                                                                          *
 * - args is an array of character strings containing                       *
 *        the parsed arguments.                                             *
 *                                                                          *
 * The routine tries to translate the parsed arguments to                   *
 * a VMS directory specification. Then it checks if the directory           *
 * exists.                                                                  *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
try_abs_dir(nr_of_args,args)
int	nr_of_args;
char	**args;
{
  char	str[256],
	str2[256];
  int	i;

  sprintf(str,"[");
  for(i = 0 ; i < nr_of_args; i++) {
    if(i != 0) {
      strcat(str,".");
    }
    strcat(str,args[i]);
  }
  strcat(str,"]");

  if(nr_of_args == 1) {
    sprintf(str2,"[000000]%s.dir",args[0]);
  } else {
    sprintf(str2,"[");
    for(i = 0 ; i < (nr_of_args - 1) ; i++) {
      if(i != 0) {
        strcat(str2,".");
      }
      strcat(str2,args[i]);
    }
    strcat(str2,"]");
    strcat(str2,args[i]);
    strcat(str2,".dir");
  }
#ifdef DEBUG
  printf("str in absolut  :==: %s\n",str);
  printf("str2 in absolut :==: %s\n",str2);
#endif
  if(exists(str2)) {
    my_chdir(str);
  } else {
    no_such();
  }
}

/*------------------------------ try_disk() --------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure try_disk is to have 2 arguments.                           *
 *                                                                          *
 * - nr_of_args                                                             *
 *                                                                          *
 * - args is an array of character strings containing                       *
 *        the parsed arguments.                                             *
 *                                                                          *
 * The routine tries to translate the parsed arguments to                   *
 * a VMS directory specification. Then it checks if the directory           *
 * exists.                                                                  *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
try_disk(nr_of_args,args)
int	nr_of_args;
char	**args;
{
  char	str[256],
	str1[256],
	str2[256];
  int	i;

  if(nr_of_args == 1) {
    sprintf(str,"[000000]");
    sprintf(str1,"%s:",args[0]);
#ifdef DEBUG
    printf("str  - %s\n",str);
    printf("str1 - %s\n",str1);
#endif
    my_chdisk(str1);
    my_chdir(str);
  } else {
    sprintf(str,"[");
    sprintf(str1,"%s:",args[0]);
    sprintf(str2,"%s:[",args[0]);
    if(nr_of_args == 2) {
      strcat(str2,"000000");
    }
    for(i = 1 ; i < nr_of_args ; i++) {
      if(i != 1) {
        strcat(str,".");
      }
      strcat(str,args[i]);
    }
    for(i = 1 ; i < (nr_of_args - 1) ; i++) {
      if(i != 1) {
        strcat(str2,".");
      }
      strcat(str2,args[i]);
    }
    strcat(str,"]");
    strcat(str2,"]");
    strcat(str2,args[i]);
    strcat(str2,".dir");
#ifdef DEBUG
  printf("str2 in disk :==: %s\n",str2);
#endif
    if(exists(str2)) {
      my_chdisk(str1);
      my_chdir(str);
    } else {
      no_such();
    }
  }
}

/*-------------------------------- up_case() -------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure try_disk is to have 1 argument.                            *
 *                                                                          *
 * str is the character string that is to be converted.                     *
 *                                                                          *
 * The routine transforms character strings to uppercase.                   *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
up_case(str)
char	*str;
{
  int	i;

  for(i = 0 ; i < strlen(str) ; i++) {
    str[i] = toupper(str[i]);
  }
}

/*------------------------------- exists() ---------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure exists is to have 1 argument.                              *
 *                                                                          *
 * str is the character string specifying a file.                           *
 *                                                                          *
 * The routine checks if the file specified exists.                         *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
exists(str)
char	*str;
{
  int	ret,
	context = 0;
  struct dsc$descriptor	file_des,
			result_des;
  char	result[256];

  file_des.dsc$w_length = strlen(str);
  file_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  file_des.dsc$b_class = DSC$K_CLASS_S;
  file_des.dsc$a_pointer = str;
  up_case(str);

  result_des.dsc$w_length = 255;
  result_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  result_des.dsc$b_class = DSC$K_CLASS_S;
  result_des.dsc$a_pointer = result;

  ret = lib$find_file(&file_des,&result_des,&context,0,0,0,0);
  if(ret & 1) {
    return(1);
  } else {
    return(0);
  }
}

/*------------------------------ my_home() ---------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure exists is to have no argument.                             *
 *                                                                          *
 * The routine sets default to sys$login.                                   *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
my_home()
{
  char	disk[256],
	dir[256],
	*translog();

  strcpy(dir,translog("LNM$JOB","SYS$LOGIN"));
  strcpy(disk,translog("LNM$JOB","SYS$LOGIN_DEVICE"));
  my_chdisk(disk);
  my_chdir(dir);
}

/*---------------------------- try_home_related() --------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure try_home_related is to have 2 arguments.                   *
 *                                                                          *
 * - nr_of_args                                                             *
 *                                                                          *
 * - args is an array of character strings containing                       *
 *        the parsed arguments.                                             *
 *                                                                          *
 * The routine tries to translate the parsed arguments to                   *
 * a VMS directory specification. Then it checks if the directory           *
 * exists.                                                                  *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
try_home_related(nr_of_args,args)
int	nr_of_args;
char	**args;
{
  char	str[256],
      	disk[256],
	str2[256],
	*translog();
  int	i,
	only_up = TRUE;

  strcpy(disk,translog("LNM$JOB","SYS$LOGIN_DEVICE"));
  strcpy(str,translog("LNM$JOB","SYS$LOGIN"));

  str[strlen(str) -1] = '\0';

  for(i = 0 ; i < (nr_of_args -1) ; i++) {
    strcat(str,".");
    strcat(str,args[i]);
  }
  strcpy(str2,str);

  strcat(str,".");
  strcat(str,args[i]);
  strcat(str,"]");

  strcat(str2,"]");
  strcat(str2,args[i]);
  strcat(str2,".dir");

#ifdef DEBUG
printf("Str i home_rel  :==: %s\n",str);
printf("Str2 i home_rel :==: %s\n",str2);
#endif
  if(exists(str2)) {
    my_chdir(str);
    my_chdisk(disk);
  } else {
    no_such();
  }
}

/*-------------------------------- to_high() -------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure to_high is to have 1 argument.                             *
 *                                                                          *
 * - str is a character string describing how many steps                    *
 *       upwards he tried to step.                                          *
 *                                                                          *
 * The routine find out wheter or not the number of steps is                *
 * too big.                                                                 *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
to_high(str)
char	*str;
{
  int	ret,
	try_up = 0,
	possible_up = 0,
	i;
  char	dir[256];
  struct dsc$descriptor	dir_des;

  dir_des.dsc$w_length = 255;
  dir_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  dir_des.dsc$b_class = DSC$K_CLASS_S;
  dir_des.dsc$a_pointer = dir;

  ret = sys$setddir(0,0,&dir_des);

  if(!(ret & 1)) {
    printf("ret - %d\n",ret);
    exit(ret);
  }

#ifdef DEBUG
printf("**dir - %s\n",dir);
printf("**str - %s\n",str);
#endif
  for(i = 0 ; i < strlen(dir) ; i++) {
    if(dir[i] == '.') {
      possible_up++;
    }
  }
  if(strncmp(strchr(dir,'['),"[000000",7) != 0) {
#ifdef DEBUG
printf("possible_up ++\n");
#endif
    possible_up++;
  }

  for(i = 0 ; i < strlen(str) ; i++) {
    if(str[i] == '-') {
      try_up++;
    }
  }

#ifdef DEBUG
printf("**try_up - %d\n",try_up);
printf("**possible_up - %d\n",possible_up);
#endif
  if(try_up > possible_up) {
    return(1);
  } else {
    return(0);
  }
}

/*------------------------------- no_such() --------------------------------*/
no_such()
{
  printf("%s: No such file or directory\n",dir_str);
}

/*-------------------------------- is_disk() -------------------------------*/
/*--------------------------------------------------------------------------*
 *                                                                          *
 * The procedure is_disk is to have 1 argument.                             *
 *                                                                          *
 * - str is a caharcter string containing a name.                           *
 *                                                                          *
 * The function figures out if str is a disk or not using the               *
 * library routine lib$getdvi.                                              *
 *                                                                          *
 *--------------------------------------------------------------------------*
 */
is_disk(device_name)
char	*device_name;
{
  struct dsc$descriptor	dev_nam_des,
			result_des;
  int			ret,
			item_code = DVI$_DEVNAM,
			val,
			len;
  char			result[256];

  dev_nam_des.dsc$w_length = strlen(device_name);
  dev_nam_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  dev_nam_des.dsc$b_class = DSC$K_CLASS_S;
  dev_nam_des.dsc$a_pointer = device_name;

  result_des.dsc$w_length = 30;
  result_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  result_des.dsc$b_class = DSC$K_CLASS_S;
  result_des.dsc$a_pointer = result;

#ifdef DEBUG
printf("device_name in is_disk -- %s\n",device_name);
#endif

  ret = lib$getdvi(&item_code,0,&dev_nam_des,&val,&result_des,&len);

#ifdef DEBUG
printf("Ret status in is_disk -- %d\n",ret);
#endif
  
  if(ret & 1) {
    return(1);
  } else {
    return(0);
  }
}

#890802-102259#
$create/log PWD.C
$deck/dollars="#890802-102302#"
#include<stdio.h>
main()
{
  char	wd[1024];

  getcwd(wd,1024,0);
  printf("%s\n",wd);
}
#890802-102302#
$create/log README.TXT
$deck/dollars="#890802-102303#"
This is a unixlike cd i wrote last december. The syntax of cd is:

cd 'directory'

'directory' is a directory specification in UN*X syntax. The
translation rules are quite simple:

cd 		--> set def sys$login
cd ~/dir1	--> set def disk1:[me.dir1] (if sys$login = disk1:[me])
cd dir1/dir2    --> set def [.dir1.dir2]
cd /dir1/dir2   --> set def [dir1.dir2]
cd /disk1/dir1  --> set def disk1:[dir1]
cd ../dir1	--> set def [-.dir1]
cd /		--> set def [000000]
cd /disk1	--> set def disk1:[000000]

If the first character is a slash the program will check if the first
word specifies a disk. If the first disk does not specify a disk, cd
assume that it is a top directory on the actual disk.

to install cd type:

$ cc cd
$ cc translog
$ link cd,translog,sys$input/opt
sys$share:vaxcrtl/share
^Z
$ cd :== $disk:<dir>cd

I also send a very small program called pwd.

#890802-102303#
$create/log TRANSLOG.C
$deck/dollars="#890802-102304#"
/*

  TRANSLOG.C MODULE

  Written by Lars-Erik Johansson at MDC of Chalmers University
  of technlology 1988-03-02

 */

 /*

  The translog function attempts to find a translation for a logical
  name in a specific name_table.


  The syntax of the translog function is as follows:

        char * translog(char *table, char *logical_name)

  Additional information

  The translog function returns a char * to the translation if
  it is successfully completed otherwise it returns a char * 
  pointing to a null byte.

 */

#include stdio
#include ssdef
#include descrip
#include lnmdef
#include syidef

typedef struct {                                /* Item_list_3      */
  unsigned short int        Size;               /* Item Buffer Size */
  unsigned short int        Type;               /* Item Type (below)*/
  char                      *Buffer;            /* Buffer Pointer   */
  int                       *Resultant_Size;    /* Final Size Ptr   */
} item_list;

char *
translog(table,logical_name)
char    *table,
        *logical_name;
{

  item_list                item;
                                         /* descriptors to interface   */
                                         /* C nullterminated strings   */
                                         /* to VMS string-format       */
  struct dsc$descriptor log_nam_des,     /* descriptor for logical_name*/
                        table_des;       /* descriptor for table       */
  int                   ret,             /* return value of sys$trnlnm */
                        len = 0,         /* Resulting length of translation */
                        attr = 0;        /* Attributes for sys$trnlnm  */
  char                  translation[256],
                        null_str = '\0',
                        msg[256];

  item.Size = 255;              /* Maximum length of a logical name */
  item.Type = LNM$_STRING;      /* The item list describes a string */
  item.Buffer = translation;    /* Ptr to the result string         */
  item.Resultant_Size = &len;   /* Ptr to the resulting length      */

  log_nam_des.dsc$w_length = strlen(logical_name);
  log_nam_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  log_nam_des.dsc$b_class = DSC$K_CLASS_S;
  log_nam_des.dsc$a_pointer = logical_name;

  table_des.dsc$w_length = strlen(table);
  table_des.dsc$b_dtype = DSC$K_DTYPE_Z;
  table_des.dsc$b_class = DSC$K_CLASS_S;
  table_des.dsc$a_pointer = table;


  /* system call that makes the translation */
  ret = sys$trnlnm(&attr,&table_des,&log_nam_des,0,&item);

  if(ret != SS$_NORMAL) {
    return(&null_str);
  } else {
    translation[len] = '\0';
    return(translation);
  }
}
#890802-102304#

