From:	CSBVAX::MRGATE!IUS%DACTH51.BITNET@CUNYVM.CUNY.EDU@SMTP 14-JAN-1988 04:21
To:	ARISIA::EVERHART
Subj:	tar.1_of_3


Received: from CUNYVM.CUNY.EDU by KL.SRI.COM with TCP; Wed 13 Jan 88 18:58:43-PST
Received: from DACTH51.BITNET by CUNYVM.CUNY.EDU ; Wed, 13 Jan 88 21:58:14 EST
Date:     Wed, 13 Jan 88 13:26 N
From:     <IUS%DACTH51.BITNET@CUNYVM.CUNY.EDU> (Eberhard W. Lisse)
Subject:  tar.1_of_3
To:       info-vax@kl.sri.com
X-Original-To:  info-vax@kl.sri.com

Hi,

now we try again.



el

....................... Cut between dotted lines and save ......................
$!..............................................................................
$! VAX/VMS archive file created by VMS_SHAR V-5.01 01-Oct-1987
$! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au)
$! To unpack, simply save and execute (@) this file.
$!
$! This archive was created by LISSE
$! on Wednesday 13-JAN-1988 13:06:25.32
$!
$! ATTENTION: To keep each article below 30720 bytes, this program
$! has been transmitted in 3 parts.
$! You should concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 6 files:
$! BLKLOOK.C TAR2VMS.C TAR2VMS.DOC TGTAR.C VMS2TAR.C VMS2TAR.DOC
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$ Version=F$GetSYI("VERSION") ! See what VMS version we have here:
$ If Version.ges."V4.4" then goto Version_OK
$ Write SYS$Output "Sorry, you are running VMS ",Version, -
                ", but this procedure requires V4.4 or higher."
$ Exit 44
$Version_OK: CR[0,8]=13
$ Pass_or_Failed="failed!,passed."
$ Goto Start
$Convert_File:
$ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
$No_Error1: Define/User_Mode SYS$Output NL:
$ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' -
        VMS_SHAR_DUMMY.DUMMY
f:=Get_Info(Command_Line,"File_Name");b:=Create_Buffer("",f);
o:=Get_Info(Command_Line,"Output_File");Set(Output_File,b,o);
Position(Beginning_of(b));Loop x:=Erase_Character(1);Loop ExitIf x<>"V";
Move_Vertical(1);x:=Erase_Character(1);Append_Line;
Move_Horizontal(-Current_Offset);EndLoop;Move_Vertical(1);
ExitIf Mark(None)=End_of(b) EndLoop;Position(Beginning_of(b));Loop
x:=Search("`",Forward,Exact);ExitIf x=0;Position(x);Erase_Character(1);
If Current_Character='`' then Move_Horizontal(1);else
Copy_Text(ASCII(INT(Erase_Character(3))));EndIf;EndLoop;Exit;
$ Delete VMS_SHAR_DUMMY.DUMMY;*
$ Checksum 'File_is
$ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
$ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
$No_Error2: Return
$Start:
$ File_is="BLKLOOK.C"
$ Check_Sum_is=1345803428
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X /*
X   This program attempts to find out the blocksize of a tape
X */
X
X#include descrip
X#include stdio
X#include iodef
X#include file
X
Xmain()
X{
X#define MNT$M_FOREIGN  1
X#define MNT$_DEVNAM    1
X#define MNT$_BLOCKSIZE 8
X#define MNT$_RECORDSIZ 16
X#define MNT$_FLAGS     4
X
X#define DMT$M_NOUNLOAD 1
X
Xtypedef struct
X          {
X          short cond_value;
X          short count;
X          int info;
X          }  status_block;
X
Xtypedef struct
X          {
X          short buffer_len;
X          short item_code;
X          int buffer_addr;
X          int ret_len_addr;
X          }  item_desc;
X
Xstruct
X   {
X   item_desc dev_name;
X   item_desc block_size;
X   item_desc flags_item;
X   int terminator;
X   }  mnt_list;
X
Xchar tape[] = "MRA0:", line[65534];
Xint flags = MNT$M_FOREIGN,
X    blocks = 65532,
X    status;
X
Xshort channel;
Xstatus_block iosb;
X$DESCRIPTOR(tape_desc, tape);
X
X/* set up mnt_list */
Xmnt_list.dev_name.buffer_len = strlen(tape);
Xmnt_list.dev_name.item_code = MNT$_DEVNAM;
Xmnt_list.dev_name.buffer_addr = tape;
Xmnt_list.dev_name.ret_len_addr = 0;
X
Xmnt_list.block_size.buffer_len = 4;
Xmnt_list.block_size.item_code = MNT$_BLOCKSIZE;
Xmnt_list.block_size.buffer_addr = &blocks;
Xmnt_list.block_size.ret_len_addr = 0;
X
Xmnt_list.flags_item.buffer_len = 4;
Xmnt_list.flags_item.item_code = MNT$_FLAGS;
Xmnt_list.flags_item.buffer_addr = &flags;
Xmnt_list.flags_item.ret_len_addr = 0;
X
Xmnt_list.terminator = 0;
X
X/* mount the tape */
Xif (((status = SYS$MOUNT(&mnt_list)) &1) != 1)
X   LIB$STOP(status);
X
Xif (((status = SYS$ASSIGN(&tape_desc,&channel,0,0)) &1) !=1)
X   LIB$STOP(status);
X
X/* read a block */
Xif (((status = SYS$QIOW(0, channel, IO$_READLBLK, &iosb, 0, 0,
X                  line, blocks, 0,0,0,0)) &1) != 1)
X   LIB$STOP(status);
Xif ((iosb.cond_value &1) != 1)
X   LIB$STOP(iosb.cond_value);
X
Xprintf("  Block Size = %d bytes\n",iosb.count);
X
X
Xif (((status = SYS$DISMOU(&tape_desc, DMT$M_NOUNLOAD)) &1) != 1)
X   LIB$STOP(status);
X}
$ GoSub Convert_File
$ File_is="TAR2VMS.C"
$ Check_Sum_is=1685857467
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X/* Read a TAR format tape or file , move files into VMS directories */
X/* Copyright 1986, Sid Penstone,
X*  Department of Electrical Engineering,
X*  Queen's University,
X*  Kingston, Ontario, Canada K7L3N6
X* (613)-545-5925
X* BITNET:          PENSTONE@QUCDNEE1  (Preferred)
X*       or  PENSTONE@QUCDN
X*
X* Version 2.2, Oct.21,1986
X* mods: - corrected header size (thanks to Eric Gisin, U .of Waterloo)
X*       - No more of the dreaded QIO's ( "  "  " )
X*       - tried to sort out link flag format
X*       - uses a tape or a file as input
X*       - NOTE: default is NO conversion to vms standard text format (cr)
X* 2.1   - trapped commas in file names, converted to '_'
X* 2.2   - reported translations of names
X*       - continued after error in opening output file
X*       - exit correctly on cannot open input file
X*/
X
X
X/* The input data is in record format, length 512, blocks of 10240 bytes;
X */
X
X
X#include stdio
X#include time
X#include ssdef
X#include iodef
X#include descrip
X#include ctype
X
X#define ERROR1 -1
X#define BUFFSIZE 512
X#define ISDIRE 1
X#define ISFILE 0
X#define NAMSIZE 100
X#define SIZE 10240              /* Block size */
X#define DSIZE 512               /* Data block size */
X
Xstruct                  /* A Tar header */
X    {
X    char title[NAMSIZE];
X    char protection[8];
X    char field1[8];             /* this is the user id */
X    char field2[8];             /*  this is the group id */
X    char count[12];             /*  was 11 in error */
X    char time[12];              /* UNIX format date  */
X    char chksum[8];             /* Header Checksum (ignored) */
X    char linkcount;             /* hope this is right */
X    char linkname[NAMSIZE]; /* Space for the name of the link */
X    char dummy[255];    /* and the rest */
X    } header;
X
Xstatic char buffer[DSIZE];      /* BUFFER for a record */
X
X/* Function flags, options:*/
Xint extract,            /* x option (default) */
X    list,                       /* t option : list tape contents */
X    verbose,            /* v option, report actions */
X    wait;
X
X/* Miscellaneous globals, etc. */
X
Xchar *tarfile = "tape", /* Input file name  */
X    pathname[NAMSIZE],  /* File name as found on tape (UNIX) */
X    directory[NAMSIZE], /* Current directory */
X    new_directory[NAMSIZE],     /* Directory of current file */
X    top[NAMSIZE],               /* Top level or root */
X    newfile[NAMSIZE],   /* VMS format of file name */
X    outfile[NAMSIZE],   /* Complete output file specification */
X    temp[256],          /* Scratch */
X    creation[NAMSIZE],  /* Date as extracted from the TAR file */
X    *ctime(),           /* System function */
X    linkname[NAMSIZE];  /* Linked file name  */
X
Xint bytecount,  mode, uic1, uic2, linktype;/* Data from header */
Xint tarfd;                      /* The input file descriptor */
X
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
Xint isterm,status,file_type,j,c, flag;
Xchar *make_directory(), *cp;
X
X/* Decode the options and parameters: */
X
X    if(argc ==1)
X        {
X        extract = 1;            /* Default for now */
X        verbose = 1;
X        wait = 0;               /* Don't wait for prompt */
X        }
X    while(--argc > 0)
X        {
X        cp = argv[1];
X        while(c = *cp++)
X            {
X            switch(c)
X            {
X            case 't':
X                list=1;
X                break;
X            case 'x':
X                extract=1;
X                break;
X            case 'v':
X                verbose=1;
X                break;
X            case 'w':
X                wait=1;
X                break;
X            default:
X                printf("Option '%c' not recognized.\n",c);
X            }
X       }
X   }
X
X
X/* Find if this is a terminal */
X    isterm = isatty(0);
X
X/* Set up directory names */
X    strcpy(top,getenv("PATH"));
X
X/* Start with the default as the top */
X    strcpy(directory,top);
X
X/* open the file for reading */
X    if((tarfd = opentar()) <= 0)
X        {
X        printf("Error opening the Tar tape\n");
X        exit(2);
X        }
X/* Now keep reading headers from this file, and decode the names, etc. */
X
X    while((status=hdr_read(&header))==DSIZE)    /* 0 on end of file */
X        {
X        if(strlen(header.title)!=0)     /* Valid header */
X            {
X            decode_header();
X            if(extract)
X                {
X                file_type=scan_title(pathname,new_directory,newfile);
X                if( make_new(new_directory)!=0)
X                    printf("Error creating %s\n",new_directory);
X                if(file_type == ISDIRE)
X                    {}
X                if(file_type == ISFILE)
X/*  Now move the data into the output file */
X                    if(bytecount>0)
X                        {
X                        strcpy(outfile,new_directory);
X                        strcat(outfile,newfile);
X                        if((j=copyfile(outfile,bytecount))<0)
X                            printf("Error writing file %s\n",outfile);
X                        }
X                }
X            else                        /* listing only */
X                {
X                printf("%o %6d %s %s\n",
X                    mode,bytecount,creation+4,pathname);
X                if(linktype == 0)
X                    tarskip(bytecount);
X                else
X                    printf("     *****( Linked to file: %s)\n",linkname);
X                }
X            }
X        else                    /* Empty header means the end!!! */
X            {
X            status = 1;
X            printf("End of Tar file found.\n");
X            break;
X            }
X
X        }       /* end while  */
X    if(status == 1)                     /* Empty header */
X        {
X        printf("Do you wish to move past the EOF mark ? y/n\n");
X        gets(temp);
X        if(tolower(temp[0]) == 'y')
X            while((status=hdr_read(&header)) >0);
X        else
X            exit(SS$_NORMAL);
X        }
X    if(status==0)                       /* End of tar file  */
X        {
X        printf("End of file encountered\n");
X        exit(SS$_NORMAL);
X        }
X    if(status<0)                        /* An error  */
X        {
X        printf("Error reading input.\n");
X        exit(2);
X        }
X}
X
X
X/* This function simply copies the file to the output, no conversion */
X
Xint copyfile(outfile,nbytes)
Xchar outfile[]; /* name of output version */
Xint nbytes;
X
X{
Xint inbytes, fil;
X/*  Open the output file */
X    if((fil=creat(outfile,0)) == ERROR1)
X        {
X        printf(" Creation error in opening %s \n",outfile);
X        tarskip(bytecount);
X        return(-2);
X        }
X    if(linktype !=0)
X        {
X        sprintf(buffer,"This file is linked to %s\n",linkname);
X        write(fil,buffer,strlen(temp));
X        }
X    else
X        {
X        while(nbytes>0)
X            {
X            if((inbytes=read(tarfd,buffer,DSIZE)) > 0)
X                {
X                write(fil,buffer,(nbytes > DSIZE)? DSIZE:nbytes);
X                nbytes -= inbytes;
X                }
X            else
X                {
X                printf("End of input file detected\n");
X                close(fil);
X                return(-1);
X                }
X            }
X        }
X/* Close the file */
X    close(fil);
X    if(verbose)
X        {
X        printf("CREATED: %s\n",outfile);
X        if(linktype!=0)
X            printf(" *** REAL DATA IS IN: %s\n",linkname);
X        }
X    return(0);
X}
X
X/* Decode a file name into the directory, and the name, return
X* a value to indicate if this is a directory name, or another file
X* We return the extracted directory string in "dire", and the
X* filename (if it exists) in "fname". The full title is in "line"
X* at input.
X*/
X
Xint scan_title(line,dire,fname)
Xchar line[],dire[],fname[];
X{
Xchar temp[NAMSIZE],*end1;
Xint len,len2,i,ind;
X/* The format will be UNIX at input, so we have to scan for the
X* UNIX directory separator '/'
X* If the name ends with '/' then it is actually a directory name.
X* If the directory consists only of '.', then don't add a subdirectory
X* The output directory will be a complete file spec, based on the default
X* directory.
X*/
X    strcpy(dire,top);                   /* Start with the top level */
X    if(strncmp(line,"./",2)==0)
X        strcpy(line,line+2);            /* ignore "./" */
X    strcpy(temp,line);                  /* Start in local buffer */
X    ind=vms_cleanup(temp);              /* Remove illegal vms characters */
X    if((end1=strrchr(temp,'/'))==0)     /* No directory at all  ? */
X        strcpy(fname,temp);             /* Only a file name */
X    else
X        {                               /* End of directory name is '/' */
X        *end1 = 0;                      /* Terminate directory name */
X        strcpy(fname,end1+1);           /* File name without directory */
X        for (i=0;temp[i];i++)           /* Change '/' to '.' in directory */
X            if(temp[i]=='/')
X                temp[i]='.';
X        dire[strlen(dire)-1] = (temp[0]=='.')?0:'.' ;
X                 /* "." to indicate a subdirectory (unless already there )*/
X        strcat(dire,temp);      /* Add on the new directory  */
X        strcat(dire,"]") ;              /* And close with ']' */
X        }
X    if(strlen(fname)==0)        /* Could this cause problems ? */
X        {
X        return(ISDIRE);
X        }
X    else
X        for(i=0,end1=fname;*end1;end1++) /* Replace multiple . */
X            if(*end1 == '.')
X                if(i++)*end1 = '_'; /* After the first */
X        if((i>1||ind)&& verbose )       /* Any translations ? */
X            printf("****RENAMED: %s \n         TO: %s\n",line,fname);
X    return(ISFILE);
X}
X
X/* Create a new directory, finding out any higher levels that are missing */
X
X/* We will parse the directory name into the next higher directory, and the
X* desired directory as "desired.dir".
X* Thus: "DEV:[top.sub1.sub2]" is made into "DEV:[top.sub1]sub2.dir" . If
X* the directory does not exist , then create the original directory. There
X* may be higher levels missing, so we can recurse until we reach the top
X* level directory, then work our way back, creating directories at each
X* successive level.
X*/
X
Xint make_new(want)
Xchar want[];
X{
Xint i,len;
Xchar a[NAMSIZE],parent[NAMSIZE],*end,name[NAMSIZE];
X    strcpy(parent,want);
X    len = strlen(parent);
X    parent[len-1] =0 ;          /* Get rid of the "]" */
X    end = strrchr(parent,'.');  /* Find the last '.' */
X    if(end != NULL)
X        {
X        strcpy(a,end+1);        /* Get the last parent */
X        strcat(a,".dir");       /* Add the extension */
X        *end++ = ']' ;          /* Reduce the directory parent */
X        *end = 0;               /* Terminate the directory */
X        strcpy(name,parent);
X        strcat(name,a);
X        }
X
X    if(access(name,0) <0)       /* Does the directory exist ? */
X        {
X            if(strcmp(parent,top)!=0) /* No, are we at the top? */
X                if(make_new(parent))   /*  No, look again */
X                    return(-1); /* recurse */
X            if(mkdir(want,0755,0,0,0)) /* make it */
X                return(-1);             /* Leave on error */
X            else
X                if(verbose)
X                    printf("CREATED: %s\n",want);
X            return(0);
X        }
X    return(0);
X}
X
X /* Function to open and get data from the blocked input file */
Xint opentar()
X{
Xint fd;
X    fd = open(tarfile, 0, "rfm = fix","mrs = 512");
X    if(fd < 0)
X        {
X        printf("Can't open input file \n");
X        return(0);
X        }
X    return(fd);
X}
X
X/* Get the next file header from the input file buffer. We will always
X* move to the next 512 byte boundary.
X*/
Xint hdr_read(buffer)
Xchar *buffer;
X{
Xint stat;
X    stat = read(tarfd,buffer,DSIZE);    /* read the header */
X    return(stat);                               /* Catch them next read ? */
X}
X
X
X/* This is supposed to skip over data to get to the desired position */
X/* Position is the number of bytes to skip. We should never have to use
X* this during data transfers; just during listings. */
Xint tarskip(bytes)
Xint bytes;
X{
Xint i=0;
X    while(bytes > 0)
X        {
X        if((i=read(tarfd,buffer,DSIZE)) == 0)
X            {
X            printf("End of file encountered while skipping.\n");
X            return(-1);
X            }
X        bytes -= i;
X        }
X    return(0);
X}
X
X/* Decode the fields of the header */
X
Xint decode_header()
X{
Xint idate, *bintim;
Xchar ll;
Xbintim = &idate;
X    linktype=0; strcpy(linkname,"");
X    strcpy(pathname,header.title);
X    sscanf(header.time,"%o",bintim);
X    strcpy(creation,ctime(bintim));     /* Work on this! */
X    creation[24]=0;
X    sscanf(header.count,"%o",&bytecount);
X    sscanf(header.protection,"%o",&mode);
X    sscanf(header.field1,"%o",&uic1);
X    sscanf(header.field2,"%o",&uic2);
X    /* We may have the link written as binary or as character:  */
X    linktype = isdigit(header.linkcount)?
X            (header.linkcount - '0'):header.linkcount;
X    if(linktype != 0)
X        sscanf(header.linkname,"%s",linkname);
X    return(0);
X}
X
X
X/* remove illegal characters from directory and file names; replace
X* hyphens and commas with underscores.Returns number of translations
X* that were made.
X*/
Xvms_cleanup(string)
Xchar string[];
X{
Xint i,flag=0;
Xchar c;
X    for(i=0;c=string[i];i++)
X        {
X        switch (c)
X            {
X            case '-':           /* No hyphens in file names */
X            case ',':           /* No commas in file names  */
X                string[i]= '_';
X                flag++;         /* Record if any changes were made */
X                break;
X            default:
X                break;
X            }
X        }
X    return(flag);
X}
$ GoSub Convert_File
$ File_is="TAR2VMS.DOC"
$ Check_Sum_is=824507747
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X                                        Dec.15/86
XGreetings:
X
X        Here is the program to extract files from a Tar format tape or
Xfile into a VMS system. This is a major update on  version 1.xx
Xthat I distributed earlier. The major changes:
X
X(1) It reads from either a tape or a file image of a tar tape
X(2) It transfers files as is, does NOT translate UNIX stream files to
X        the format that the VMS editor likes, but this is not a
X        problem unless you intend to edit the files. See below.
X        (The old "s" option is now the default).
X(3) It can usually leave the tape positioned ready to read another
X        Tar file from the tape. NOTE: there is a SET MAGTAPE/
X        option in VMS 4.x that will skip files to start reading in
X        the middle of a tape. The TAR2VMS program does not do any rewinds.
X(4) UNIX "linked" files are handled.
X
X        I will be glad to hear of your experiences with the code, since
Xoften when we get a Tar tape from a different system, we find something
Xthat I hadn't anticipated. The program was developed by looking at DUMP
Xoutput from various tar format tapes on a VMS system, so there are
Xundoubtedly variations that I haven't seen. ( I am not a UNIX expert..)
XWe looked at UNIX manuals as well, but found some discrepancies in real
Xtapes, so went with what seemed to work.
X
X        I also have a partially debugged version of a Tar writer; ask
Xfor it if you are willing to be a guinea pig, or need to transfer some
Xfiles to a UNIX system from VMS.
X
X
XSid Penstone,
XVLSI Group,
XDepartment of Electrical Engineering,
XQueen's University,
XKingston, Ontario, Canada, K7L3N6
Xphone (613) 545-2925
X
XBITNET:         PENSTONE@QUCDNEE1       (Preferred)
X                PENSTONE@QUCDN  (If the other doesn't work)
X
X
X
X
XNOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
XNOTE!!! The program must be separated at the "** CUT HERE **" lines
XNOTE!!! below before compiling.
XNOTE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
X
XIntroduction:
X
X        The program TAR2VMS.C reads from a /foreign tape,or a file
Xwhich is an image of a Tar format tape, and extracts the files into
Xa directory tree starting in the current default directory.
XDirectories will be created automatically.
XFor example, if your default is [JONES.MAIN], then the file
X"electric/sub/test.c" will be written into [JONES.MAIN.ELECTRIC.SUB]TEST.C .
X        For the simplest operation, just  RUN it after defining the
Xlogical "TAPE" to be the the Tar source and doing a
XMOUNT/FOREIGN/BLOCK=10240/RECORD=512 (if it is a tape); this
Xdoes the extraction automatically, reporting on stdout as it does.
X
X        The extracted files will be written to your system as C stream files.
XThe VMS editor EDT will complain about the format, but EVE will not.
X
X        To convert a text file to standard VMS format:
X(Thanks to Eric Gisin at U. of Waterloo:)
X        You can use the VMS CONVERT utility by first creating a xxxx.FDL file
Xcontaining:
X
XFILE
X        ORGANIZATION            sequential
XRECORD
X        BLOCK_SPAN              yes
X        CARRIAGE_CONTROL        carriage_return
X        FORMAT                  variable
X
XThen run Convert with the regular DCL:
XCONVERT/FDL=xxxx  input-file  output-file
X-------------------------------------------------------------------------
X
XUsage:
X
X        -Define the logical variable "TAPE" to be the desired tape
X         unit or the file containing the Tar data.
X
X        -Mount the tape /FOREIGN/BLOCK=10240/RECORD=512
X
X        -Set the default directory below which the tree will be created
X         before calling the program. Thus: if your default directory
X         is SYS$SYSDEVICE:[MYDIRE], the file "electric/dbase.c" will
X         be written in SYS$DEVICE:[MYDIRE.ELECTRIC]DBASE.C
X
X       -Then run TAR2VMS: (either by RUN or as a command)
X         if you use RUN, the operation is (extract, verbose)
X         otherwise:
X'command' [options]
X        where the options are:
X                "t" (listing only)       Listing of files on tape
X                "x" (extract)            Extract files from the tape
X                "v" (verbose):           Report activity
X                "w" (wait)               ...Not implemented
X    -to use the options, the program must be executed using the
X     foreign command feature of VMS, by defining a command:
Xcommand :== $path:tar2vms      !where path=complete location of tar2vms.exe
X
X        Example:
XIf the command is 'tar2vms', then:
Xtar2vms t                       will list the contents of the tar file
Xtar2vms xv                      will extract all of the files, reporting
X
XThe listing reports the UNIX protection (in octal), the file size in bytes,
Xthe modification date on the tape, and the file name.
X
XERRORS: Most probable causes:
X        "Can't open input file" - likely forgot to define TAPE, or mount
X                                        the tape.
X        "Error reading input"   - unexpected Tar format, or bad file.
X        "Error writing output " - directory access error
X        "Creation Error...   "  - illegal directory or file name
X
X--------------------------------------------------------------------------
XImportant assumptions for this version (2.1):
X
X    The defaults are (no options):
X    -Extract all of the files, reporting as each file is created
X
X    -Read from a tape, mounted foreign, or a fixed record length
X     file,with block size of 10240 bytes or less . If larger block
X     size, change the  definition of SIZE.
X
X    -Stop on the special (blank header) block written by UNIX.
X     (Note, like UNIX Tar, it does not move to the file mark at
X     the end of the file. Answer "y" to the prompt to get to another
X     tar file on the same tape.)THIS MIGHT NOT WORK...
X
X    -All files are assumed to be UNIX stream and are
X     just copied. The vms file-attribute will be "stream". This may
X     have to be changed in certain cases with CONVERT, or by writing
X     a little C program to read the file and rewrite it.
X
X    -When a UNIX linked file is encountered, there will be another
X     file on the tape that contains the actual data. It may not be an
X     earlier file that was the original file, since the files
X     are written on in alphabetical order. The program will create a
X     file under the name of the linked file, but it will contain only
X     a text messsage reporting the name of the file that contains the
X     data.
X
X
X    This version converts the path names to VMS format before creating
Xthe files. Some special cases:
X
X (1) File names with more than one period (".") in the name have those
X        after the first converted to underscores (e.g. "mults.s.c" is
X        written out under the name "mults.s_c"
X (2) It is assumed that all of the pathnames on the Tar tape have
X        complete directory info, with no device parts.
X (3) Commas and hyphens in file or directory names are converted to
X        underscores. If this causes any problems, you can modify the
X        code in vms_cleanup().Any such translations are reported in
X        "verbose" mode.
X (4) Files are created with the user's default protection. The mode on
X        the tape is ignored.
X (5) The dates of files extracted are the date of the extraction, not the
X        date of the Tar version.
X (6) unix FILES THAT HAVE NO EXTENSION, AND END IN A LETTER WILL HAVE
X        A "." ADDED TO THE NAME AUTOMATICALLY. tHIS CAN CAUSE SOME
X        MYSTERIES WITH LARGE PROGRAMS THAT LOOK FOR OTHER FILES WITH
X        AN EXACT STRING SEARCH. aLSO, IF THE FILES ARE WRITTEN OUT
X        TO unix AS A tar TAPE FROM vms, THE "." GOES ALONG WITH THE FILE
X        name.
X
X------------------------------------------------------------------------
XKnown Bugs:
X
X    - Can't always read another file on the same tape. The program
X      only works correctly when the tape had regular EOF marks on it,
X      which apparently is not always true.
X    - Can't selectively extract files from the tape. The "wait" option
X      could be useful, but haven't got around to it..
X
X
X
$ GoSub Convert_File
$ Goto Part2
