/* VMS_TO_UNIX.C
   19-JUN-2000, David Mathog, Biology Division, Caltech

   Translates a single OpenVMS file spec to one or more Unix file
   specs.  These are written to stdout.  In addition, if it translates to
   a single file name, that is stored in the symbol UNIX_FILENAME.
   Otherwise the symbol is left empty (for no translations) or filled
   with "// *MULTIPLE* //"

   This program makes it a bit easier to adapt Unix programs for use on 
   OpenVMS.  It can hide the Unixy filenames from the user accessing them 
   through DCL.

   09-AUG-2000, David Mathog, Biology Division, Caltech
   If the first parameter is "" then it reads from stdin and writes
   to stdout.

*/
#include <stdlib.h>
#include <stdio.h>
#include <descrip.h>
#include <unixlib.h>
#include <unixio.h>
#include <string.h>
#include <lib$routines.h>

static char symbol_value[2000];  /* should be more than long enough */
struct  dsc$descriptor_s  symbol_name_desc;
struct  dsc$descriptor_s  symbol_value_desc;

#define MAXFILENAME 1000
char vfilename[MAXFILENAME];
char *res;

int count=0;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif


int strip=0;
int isver=0;


int emit(char *string){
char *slide;
char *lastdot;
   if(strip && isver){
     for(lastdot=NULL, slide=string; *slide != '\0'; slide++){
       if( *slide == '.')lastdot=slide;
     }
     if(lastdot != NULL)*lastdot = '\0';
   }
   count++;
   if(count==1)(void)strcpy(symbol_value,string); 
   (void) fprintf(stdout,"%s\n",string);
   return(1);
}

/* check to see if there is a version in the filename.  This should work
   with ODS2 names but may fail with ODS5.  That is:
   []foo.bar;1     works
   []foo.bar.1     works
   []foo.bar.bar   fails, nicks off the second bar
*/
   
void hasversion(char *string){
char *slide;
int closedbracket;
int count;

  isver=FALSE;
  closedbracket=TRUE;
  for(slide=string,count=0; *slide != '\0'; slide++){
    if( *slide == ';'){
      isver=TRUE;
      return;
    }
    if( *slide == '.' & closedbracket){
      count++;
    }
    if( *slide == '[' )closedbracket=FALSE;
    if( *slide == ']' )closedbracket=TRUE;
  }
  if(count == 2)isver=TRUE;
}


int main(int argc, char *argv[]){
int temp;

  symbol_name_desc.dsc$w_length = strlen("UNIX_FILENAME");
  symbol_name_desc.dsc$a_pointer =  "UNIX_FILENAME";
  symbol_name_desc.dsc$b_class =  DSC$K_CLASS_S;
  symbol_name_desc.dsc$b_dtype =  DSC$K_DTYPE_T;

  symbol_value_desc.dsc$b_class =  DSC$K_CLASS_S;
  symbol_value_desc.dsc$b_dtype =  DSC$K_DTYPE_T;

  symbol_value[0]='\0';
  switch(argc){
     case 3:
       strip =1;
     case 2:
        if(*argv[1] == '\0'){
           res=vfilename;  /* initialize it to something which isn't NULL */
           while (res != NULL){
              res=fgets(vfilename,MAXFILENAME,stdin);
              if(res != NULL){
                temp=strlen(vfilename);
                hasversion(vfilename);
                vfilename[temp-1]='\0'; /* obliterate new line */
                (void) decc$from_vms(vfilename, emit, 1);
              }
           }
        }
        else {
           hasversion(argv[1]);
           (void) decc$from_vms(argv[1], emit, 1);
        }
        if(count>1){
           (void) strcpy(symbol_value,"// *MULTIPLE* //");
        }
        break;
     default:
        (void) fprintf(stderr,"\n usage: \n\n  % vms_to_unix vmsfilespec noversions\n\n");        
        (void) fprintf(stderr,"  vmsfilespec is any valid OpenVMS file or directory name (wildcards allowed )\n");        
        (void) fprintf(stderr,"    When vmsfilespec is \"\"  the program reads filenames from\n");
        (void) fprintf(stderr,"    and translates those.\n");
        (void) fprintf(stderr,"    Only names for extant directories and/or files will be translated\n");
        (void) fprintf(stderr,"  noversions, if present strips the version numbers from the resultant Unix file spec\n");        
  }
  symbol_value_desc.dsc$w_length = strlen(symbol_value);
  symbol_value_desc.dsc$a_pointer =  symbol_value;
  (void) LIB$SET_SYMBOL(&symbol_name_desc,&symbol_value_desc);
}

