a('I~ VMSTAR.BCK VMSTAR.BCKBACKUP/LOG *.* VMSTAR.BCK/SAVE TK91 `גR)V5.4  _NDONE$DUA0: V5.4 ~  *[VMSTAR]AAAREADME.TXT;6+,-./ 4OT- 0123KPWO56jۓ7bۓ89GHJ  General information -------------------OVMSTAR is a TAR reader/writer for VMS. It can read archives ("tarfiles")Ocreated by the Un*x command "tar" and also create such archives. Tarfiles can"be disk files or directly on tape.?VMSTAR is based on the TAR2VMS and VMS2TAR programs written by: Sid Penstone, VLSI Group,%Department of Electrical Engineering,Queen's University,!Kingston, Ontario, Canada, K7L3N6phone (613) 545-29253BITNET: PENSTONE@QUCDNEE1 (Preferred); PENSTONE@QUCDN (If the other doesn't work) The extra work has been done by:Alain FauconnetBSIM/INSERM U194 (complete address at the end of this file)PARIS - FRANCEBitnet: FAUCONNE@FRSIM51OTAR2VMS and VMS2TAR have been merged into a single program. I made severalOimprovements, bug fixes and message cleanup. For those who know TAR2VMS and"VMS2TAR, the main differences are:M- everything is now in a single program that can be used for extracting filesIfrom tar archives, listing the contents of tar archives or creating them.L- VMSTAR now accepts a `f tarfile' option to explicitely specify the tarfile3name (either a VMS file name or a VMS device name).E- if this option is not used, the logical name "$TAPE" is translated.,- checksums are verified at file extraction.M- VMSTAR will extract files from archives as VMS rfm=stream_lf, rat=cr files,Iexcept if new option `b' is specified. In this case, extracted files aredMcreated as rfm=fixed, mrs=512, rat=none i.e. suitable for compressed files to/be decompressed using LZDCMP or for VMS images.L- VMSTAR has a more Un*x-like syntax, if several file names are specified asOcommand line parameters they must be separated by spaces (not commas) and there)is not context propagation "a la BACKUP".O- VMSTAR allows VMS-style wildcarded strings for Un*x-style file names to be4specified when extracting from a tar archive, e.g. :$$ tar xvf foo.tar */source/*/sa%%%.cI- VMSTAR will attempt to create relative tar archives i.e. archives whereHfilenames are recorded as "./foo/bar/baz" whenever possible. This can beJspecifically avoided by having a device name in file name argument, e.g. :$$ tar cvf foo.tar DISK$USERS[...]*.c8or specifying an absolute VMS file specification, e.g. :$ tar cvf foo.tar [SMITH.C...]N- VMSTAR will handle tar archives which when restored would create more than 8Olevels of directories (the X11 distribution from MIT for instance !). Excessive2levels of directories will be resolved as follows:Ad1/d2/d3/d4/d5/d6/d7/d8/d9/foo -> [D1.D2.D3.D4.D5.D6.D7.D8$D9]FOOM- VMSTAR no longer requires the creation of an intermediate scratch file when$archiving text files as VMS2TAR did.L- VMSTAR does *not* allow to read tarfiles past the EOF mark as TAR2VMS did.O- the `w' option (same as "/CONFIRM" for VMS commands) has been implemented for%create archive and extract functions.O- VMSTAR has a VMS help file (VMSTAR.HLP) that can be added to your HELPLIB.HLBto provide online help.E- many other differences, the code has been extensively reworked withOsimplification as a goal. This probably caused the introduction of some bugs...+ Build and installation instructions+ -----------------------------------%Compile and link VMSTAR.C as follows: $ CC VMSTAR$ LINK VMSTAR,SYS$INPUT:/OPTSYS$SHARE:VAXCRTL/SHARE /Define a foreign command symbol in SYLOGIN.COM:$ VMSTAR :== $ VMSTARMI used VAX/VMS C V3.1 to build VMSTAR. I have no idea whether it can be built*using other versions or other compilers...BYou can optionally add VMSTAR in your VMS help library as follows:?$ LIBRARY/HELP/INSERT SYS$COMMON:[SYSHLP]HELPLIB.HLB VMSTAR.HLP Usage -----9 tar x|t|c[v][w][b][d][f tarfile] [file [file...]]2 x - extract from tarfile, create VMS files% t - type directory of tarfile- c - create tarfile, archive VMS filesB v - verbose (list names of files being archived/extracted)= w - wait for confirmation before extracting/archivingL b - binary mode extract, create (rfm=fixed, rat=none, mrs=512) files, d - keep trailing dots in file names2 f - specify tarfile name, default is $TAPEH file - space-separated list of file names, can include VMS-styleD string wildcards on extract, can be any VMS file name? specification (except DECnet) on create archive.7Tapes for reading/writing of tarfiles should be mounted/FOREIGN/RECORD=512/BLOCK=10240Example:5$ MOUNT/FOREIGN/RECORD=512/BLOCK=10240 MUA0: "" $TAPE $ VMSTAR XV Restrictions ------------OBecause of diffrences in the Un*x and VMS filesystems, some files may fail toObe correctly transferred to/from the tarfile. This can be caused by :J- restrictions in VMS file naming scheme: extra dots in file names will beImapped to underscores, dummy directory names will be generated if archiveKcontains more than 8 levels of subdirectories, links are extracted as emptyKfiles containing only a short message "this file is only a link to...", all'file names are mapped to uppercase etc.N- restrictions of the Un*x filesystem: tar will only get the latest version ofLa VMS file to enter it into the archive, no trace of the orginal file devicename is kept in the archive.H- VMS strong file typing: VMSTAR can only safely tranfer back and forth MVMS "text" files (rfm=vfc or stream_lf with rat=cr) or VMS fixed size record,9512 bytes/record, rat=none files (e.g. .EXE image files).HVMSTAR will skip other file types (this includes .OBJ and library files,they *can't* be archived).Other restrictions:ORMS file attributes are lost in the archive process, text files are archived as9, fixed files are archived as is.OVMSTAR will always restore files relative to your current RMS default if namesOin tarfile do not begin by `/'. If file names in tarfile begin with a `/' (badOpractice), an attempt will be made to restore files to the absolute path. ThereOis currently no way to explicitely specify the target VMS directory where filesshould be extracted.ONo attempt has been made to handle search list as RMS defaults (e.g. SYSTEM%account). Be very careful about that.OThe current version of VMSTAR has *not* been fully tested. I probablyOintroduced many bugs not existing in Sid Penstone's programs. VMSTAR isOprovided "as-is", I cannot guarantee it will do what you want or even what it'sOsupposed to do but I'd like to hear about it if you have problems. If youOreport a problem, don't bother with providing me a fix but *do* try to be-precise on what happened and how it happened.K+-------------------------------------------------------------------------+K| Alain ("HAL 1") Fauconnet Research laboratory in medical informatics |K| System Manager (expert systems, NL proc., statistics...) |K| SIM/INSERM U194 EARN/Bitnet: FAUCONNE@FRSIM51 |K| Faculte de Medecine VMS PSI Mail: PSI%+208075090517::FAUCONNET |K| 91 Boulevard de l'Hopital FAX: (+33) 1-45-86-56-85 |K| 75634 PARIS CEDEX 13 FRANCE PTT net: (+33) 1-45-85-15-29 |K| "HAL... open the door, please!" (2001 Space Odyssey) |K| Disclaimer: This is machine-generated random text, no meaning at all. |K+-------------------------------------------------------------------------+*[VMSTAR]CLINK.OPT;1+,./ 4 - 0123 KPWO56`qܣ̏7J˓89GHJsys$library:vaxcrtl.exe/share*[VMSTAR]VMSTAR.C;58+,.N/ 4PNN- 0123KPWOO56Cհ7@(װ89GHJV/*3 * VMSTAR.C - a Un*x-like tar reader/writer for VMS* * based on TAR2VMS and VMS2TAR * * Usage:5 * tar x|t|c[v][w][b[d]][f tarfile] [file [file...]] * x - extract from tarfile * t - type contents of tarfile( * c - create tarfile, archive VMS files * v - verbose8 * w - wait for confirmation before extracting/archivingG * b - binary mode extract, create (rfm=fixed, rat=none, mrs=512) files' * d - keep trailing dots in file names- * f - specify tarfile name, default is $TAPEC * file - space-separated list of file names, can include VMS-style? * string wildcards on extract, can be any VMS file name? * specification (except DECnet) on create archive. *7 * Original author of the VMS2TAR and TAR2VMS programs: * Copyright 1986, Sid Penstone,) * Department of Electrical Engineering, * Queen's University,$ * Kingston, Ontario, Canada K7L3N6 * (613)-545-2925 * BITNET: PENSTONE@QUCDNEE1 * * Deeply modified by: * Alain Fauconnet * System Manager, * SIM - Public Health Research Laboratories * 91 Boulevard de l'Hopital * 75634 PARIS CEDEX 13 - FRANCE * Bitnet: FAUCONNE@FRSIM51 *F * PROBLEMS SHOULD BE REPORTED TO ME. PLEASE DON'T BOTHER SID PENSTONE * WITH MY OWN BUGS ! * * Version 1.5-3 26-SEP-1991A * Based on TAR2VMS V2.2 21-OCT-1986 and VMS2TAR V1.8 23-DEC-1986 *K * Sid Penstone did not include any copyright information in his program soO * this only applies if Sid Penstone agrees: you may use VMSTAR, distribute it,< * modify it freely provided you don't use it for commercialI * or military purposes. Please include the two above author names in the1 * source file of any modified version of VMSTAR. * * Modification history: ** * 1.5-3 - removed duplicate error message+ * 1.5-2 - removed duplicate #include iodefG * - added write status checking in copyfile and cleaned up error/ * handling (avoids duplicate messages); * 1.5-1 - fix by Mark Parisi E * fixed bug in out_file: if the length of a text file was anE * exact multiple of DSIZE, flushout was called an additional * time.4 * - added some code for empty files handling.C * 1.5 - when archiving a non-text file with rfm=stream_lf, rat=crB * attributes, VMSTAR truncated the file. Modified out_file? * to more cleanly handle various RMS file formats: onlyK * variable and stream_cr record formats need two passes to compute D * the actual file size and need to be read record by record.G * All other formats should by read buffer by buffer and writtenE * as-is in the tar archive, thus out_file now fopens the file, * in binary mode and freads buffers.K * In the case of a stream_cr file, if a single record cannot fit inD * our buffers (probably because the file is non-text and has= * incorrect RMS attributes) out_file now error exits.@ * 1.4 - fixed a bug in scan_title that caused VMSTAR to fail on> * extraction of absolute tarfiles (thanks to Tom Allebrandi * for this one)> * - added some code in scan_title to correctly handle dots in7 * directory names found in tarfile (replaced by "_")D * 1.3 - changed tar2vms to use standard IO calls (fopen, fread) toB * read input tarfile in binary mode i.e. no translation ofI * RMS record attributes done by C RTL. This fixes problem reading/ * tarfiles created with rfm=fix, rat=cr3 * - more room for file size in output formatsC * 1.2 - fixed bug in out_file not closing input VMS file, limited9 * maximum number of files archived to FILLM quotaD * - added mapping to underscores of some more characters found6 * in Un*x file names illegal in VMS file names2 * 1.1 - reworked handling of current VMS default? * - will now create *relative* tarfiles (i.e. files known: * as "./..." in tar archive directory) except whenD * device name is specified or wilcard search gives filenamesG * located above current default (tar cvf foo.tar [-...]*.* will) * lead to this kind of situation)B * - attempt to handle more than 8 levels of directories upon@ * extract : .../d7/d8/d9 will be mapped to [...D7.D8$D9]? * - greatly simplified make_new() because mkdir() creates7 * intermediate levels of directories if missing0 * 1.0 Original version from Sid Penstone's code7 * - merged VMS2TAR & TAR2VMS into a single source file' * - code reworked, messages cleaned upC * - added support for 'f tarfile' option, changed default to $TAPE? * - added support for VMS style wildcard file names on extract7 * - added support for 'b' (binary file extract) optionG * - suppressed usage of intermediate scratch file for create operationI * - file list on create should now be space separated (removed difficult@ * support of comma-separated list with context "a la BACKUP")= * - global code simplification attempt, may have broken some * odd case handling: * - added some error handling in tarfile write operations3 * - probably millions of bugs introduced... sorry. */#include stdio #include time#include ssdef#include iodef#include descrip#include ctype#include strdef #include rms#include stsdef #include file #include stat#include types#include string#include errno#define ERROR1 -1#define BUFFSIZE 512#define ISDIRE 1#define ISFILE 0#define NAMSIZE 1000#define BLKSIZE 10240 /* Block size */5#define DSIZE 512 /* Data block size */2struct tarhdr /* A tar header */{ char title[NAMSIZE]; char protection[8];9 char uid[8]; /* this is the user id */: char gid[8]; /* this is the group id */5 char count[12]; /* was 11 in error */7 char time[12]; /* UNIX format date */5 char chksum[8]; /* header checksum */8 char linkcount; /* hope this is right */D char linkname[NAMSIZE]; /* Space for the name of the link */2 char dummy[255]; /* and the rest */ } header;Achar buffer[DSIZE]; /* buffer for a tarfile record *//* Function flags, options *//int extract, /* x option, extract */: list, /* t option, list tape contents */6 verbose, /* v option, report actions */. wait, /* w option, prompt */5 dot, /* d option, suppress dots */. create, /* c option, create */3 binmode, /* z option, binary mode */- foption; /* f option, specify tarfile */!/* Miscellaneous globals, etc. */+char tarfile[NAMSIZE], /* Tarfile name */? pathname[NAMSIZE], /* File name as found on tape (UNIX) *// curdir[NAMSIZE], /* Current directory */D topdir[NAMSIZE], /* Top level directory of current default */, curdev[NAMSIZE], /* Current device */? new_directory[NAMSIZE], /* Directory of current file */5 newfile[NAMSIZE], /* VMS format of file name */@ outfile[NAMSIZE], /* Complete output file specification */% temp[NAMSIZE], /* Scratch */A creation[NAMSIZE], /* Date as extracted from the TAR file */- *ctime(), /* System function *// linkname[NAMSIZE], /* Linked file name */C searchname[NAMSIZE], /* used in the NAM block for SYS$SEARCH */D dbuffer[DSIZE], /* input file buffer for create operation */' badchars[] = {",+~`@#%^*?|\&[]{}"};L /* Chars found in Un*x file names, illegal in VMS */<struct stat sblock; /* structure returned from stat() */2struct FAB fblock; /* File attribute block */:struct NAM nblock; /* Name attribute block for rms */Bint bytecount, mode, uic1, uic2, linktype; /* Data from header */Cint uid, gid, bufferpointer; /* current values used by create */>FILE *tarfp; /* The input file pointer */!/* Global file characteristics */FILE *vmsfile;int vmsfd, outfd;=unsigned int vmsmrs, vmstime; /* maximum record size */Dint vmsrat,vmsorg,vmsrfm; /* other format (as integers) */Jchar default_name[] = {"*.*;"}; /* only get the most recent version */?/* main -- parses options, dispacthes to tar2vms and vms2tar */main(argc,argv) int argc; char *argv[];{ char *cp, c;(/* Decode the options and parameters: */ if(argc ==1) usage();2 extract = 0; /* Defaults for now */ verbose = 0;7 wait = 0; /* Don't wait for prompt */ binmode = 0; create = 0; dot = 0; foption = 0; strcpy(tarfile,"$TAPE"); cp = argv[1]; while(c = *cp++) { switch(c) { case 't': list=1; break; case 'x': extract=1; break; case 'c': create=1; break; case 'v': verbose=1; break; case 'w': wait=1; break; case 'd': dot=1; break; case 'b': binmode=1; break; case 'f':, if (*cp != '\0' || argc < 3) usage(); else foption = 1;, strcpy(tarfile,argv[2]); break; case '-': break; default:? printf("tar: option '%c' not recognized.\n",c); usage(); } } /* Check options are coherent */% if (extract + list + create == 0) {. printf("tar: no action specified.\n"); exit(1); } if (extract + create == 2) {9 printf("tar: incompatible options specified.\n"); exit(1); }4/* Set up directory names - current and top level */# strcpy(curdev, getenv("PATH"));( for (cp = curdev; *cp != '\0'; ++cp)3 *cp = toupper(*cp); /* map to uppercase */F cp = strchr(curdev, ':'); /* split into device and directory */ *cp++ = '\0'; strcpy(curdir, cp); strcpy(topdir, curdir);? cp = strchr(topdir,'.'); /* isolate top level directory */ if (cp != NULL) { *cp = ']'; *++cp = '\0'; } if (create == 0) tar2vms(argc,argv); else vms2tar(argc,argv);}1/* tar2vms -- handles extract and list options */tar2vms(argc,argv) int argc; char **argv;{,int status,file_type,j, flag, argi, process;$char *make_directory(), *argp, *ptr;)struct dsc$descriptor pattern, candidate;FILE *opentar();/* open the file for reading */# if((tarfp = opentar()) == NULL) {0 printf("tar: error opening tarfile.\n"); exit(1); }I/* Now keep reading headers from this file, and decode the names, etc. */F while((status=hdr_read(&header))==DSIZE) /* 0 on end of file */ { process = 0;: if(strlen(header.title)!=0) /* Valid header */ { decode_header(); process = 1;F/* Now if file names were specified on the command line, check if they match the current one */7 if ((foption == 0 && argc > 2) || argc > 3) { process = 0;' argi = foption ? 3 : 2;# while (argi < argc) {> pattern.dsc$w_length = strlen(argv[argi]);7 pattern.dsc$a_pointer = argv[argi];8 pattern.dsc$b_dtype = DSC$K_DTYPE_T;8 pattern.dsc$b_class = DSC$K_CLASS_S;> candidate.dsc$w_length = strlen(pathname);7 candidate.dsc$a_pointer = pathname;: candidate.dsc$b_dtype = DSC$K_DTYPE_T;: candidate.dsc$b_class = DSC$K_CLASS_S; ++argi;K if (STR$MATCH_WILD(&candidate, &pattern) == STR$_MATCH) {$ process = 1; break; } } } } else { status = 1; break; }  if (process && wait) { *temp = '\0';0 while (*temp != 'y' && *temp != 'n') {2 printf("%s (y/n) ? ", pathname);" scanf("%s", temp);' *temp = tolower(*temp); }% process = (*temp == 'y'); } if (process && extract) { E file_type=scan_title(pathname,new_directory,newfile);, cleanup_dire(new_directory);/ if( make_new(new_directory)!=0)E printf("tar: error creating %s\n",new_directory);' if(file_type == ISDIRE) {}' if(file_type == ISFILE)-/* Now move the data into the output file */# if(bytecount>0) {6 strcpy(outfile,new_directory);0 strcat(outfile,newfile);4 copyfile(outfile,bytecount); } } else {A if (process && list) /* listing only */ {) printf("%6o %8d %s %s\n",8 mode,bytecount,creation+4,pathname);3 if (linktype == 1 || linktype == 2)O printf(" ---> %s\n",linkname); } if(linktype == 0)# tarskip(bytecount); } } /* end while */: if(status == 1) /* Empty header */ {C/* printf("Do you wish to move past the EOF mark (y/n) ? ");** fflush(stdout);** gets(temp);#** if(tolower(*temp) == 'y')3** while((status=hdr_read(&header)) >0);** else*/ exit(SS$_NORMAL); }> if(status==0) /* End of tar file */ {- printf("tar: EOF hit on tarfile.\n"); exit(SS$_NORMAL); }7 if(status<0) /* An error */ {0 printf("tar: error reading tarfile.\n"); exit(SS$_NORMAL); }}G/* This function simply copies the file to the output, no conversion */int copyfile(outfile,nbytes),char outfile[]; /* name of output version */ int nbytes;{int inbytes, fil, s;/* Open the output file */ if (binmode); fil = creat(outfile,0,"rfm=fix","mrs=512","alq=5"); else4 fil = creat(outfile,0,"rfm=stmlf","rat=cr"); if(fil == ERROR1) {4 printf("tar: error creating %s \n",outfile); tarskip(nbytes); return(-2); } s = 0; if(linktype !=0) {C sprintf(buffer,"*** This file is a link to %s\n",linkname);+ s = write(fil,buffer,strlen(temp)); } else {# while(nbytes > 0 && s >= 0) {9 if((inbytes=fread(buffer,1,DSIZE,tarfp)) > 0) {E s = write(fil,buffer,(nbytes > DSIZE)? DSIZE:nbytes);" nbytes -= inbytes; } else {8 printf("tar: EOF hit on input file.\n"); close(fil); return(-1); } } }/* Close the file */ close(fil); if (s < 0) {7 printf("tar: error writing file %s\n",outfile); if (nbytes) tarskip(nbytes); return(-1); } if(verbose) {; printf("%s %8d %s\n",creation+4,bytecount,outfile); if(linktype!=0)A printf(" --> %s\n",linkname);n }  return(0);}oG/* scan_title -- decode a Un*x file name into the directory and name */ J/* Return a value to indicate if this is a directory name, or another file=* We return the extracted directory string in "dire", and theeA* filename (if it exists) in "fname". The full title is in "line"r * at input.i*/int scan_title(line,dire,fname)(char line[],dire[],fname[]; {e char *end1;eint len,len2,i,ind;l?/* The format will be UNIX at input, so we have to scan for the * UNIX directory separator '/'A* If the name ends with '/' then it is actually a directory name.,F* If the directory consists only of '.', then don't add a subdirectoryI* The output directory will be a complete file spec, based on the defaultg * directory.*/H strcpy(dire,curdir); /* Start with the current dir */ if(strncmp(line,"./",2)==0)n9 strcpy(line,line+2); /* ignore "./" */TC strcpy(temp,line); /* Start in local buffer */eK ind=vms_cleanup(temp); /* Remove illegal vms characters */lD if((end1=strrchr(temp,'/'))==0) /* No directory at all ? */> strcpy(fname,temp); /* Only a file name */ elseJ { /* End of directory name is '/' */F *end1 = 0; /* Terminate directory name */I strcpy(fname,end1+1); /* File name without directory */nL for (i=1;temp[i];i++) /* Change '/' to '.' in directory */2 if(temp[i]=='/') /* and '.' to '_' */ temp[i]='.'; else if (temp[i] == '.')h temp[i] = '_';c= if (*temp == '/') /* absolute path ? */ {*< *temp = '['; /* yes, build absolute VMS path */ strcpy(dire,temp); }d else {i7 dire[strlen(dire)-1] = (*temp=='.')?0:'.' ;oL /* "." to indicate a subdirectory (unless already there )*/C strcat(dire,temp); /* Add on the new directory */i }@ strcat(dire,"]") ; /* And close with ']' */ }*A if(strlen(fname)==0) /* Could this cause problems ? */. {5 return(ISDIRE);t }e elseA for(i=0,end1=fname;*end1;end1++) /* Replace multiple . */. if(*end1 == '.')9 if(i++)*end1 = '_'; /* After the first */  return(ISFILE);r}_(/* make_new -- create a new directory */int make_new(want) char want[];{nint status, created; char *dotp;* created = 1;N status = mkdir(want, 0); /* mkdir in VAX C creates all missing levels */ if (status != 0) {e if (errno == EEXIST) return (0);r if (errno != EINVAL)D return (-1); /* unknown error, simply return */L else /* maybe too many levels of directories */O { /* change "[...FOO.BAR]" to "[...FOO$BAR]" */sH for (dotp = &want[strlen(want) - 1];dotp > want && status != 0;) if (*--dotp == '.') {o *dotp = '$';( status = mkdir(want, 0);3 if (status != 0 && errno == EEXIST)2 { ) status = created = 0;i break; } }M }t }  if (status != 0) return (-1); if(verbose && created): printf(" %s\n",want); return(0);}1@ /* Function to open and get data from the blocked input file */FILE *opentar()u{r FILE *fp;r fp = fopen(tarfile, "rb"); return(fp);o}dF/* Get the next file header from the input file buffer. We will always%* move to the next 512 byte boundary.d*/int hdr_read(buffer) char *buffer; {i int stat;t@ stat = fread(buffer,1,DSIZE,tarfp); /* read the header */D return(stat); /* catch them next read ? */} G/* This is supposed to skip over data to get to the desired position */cG/* Position is the number of bytes to skip. We should never have to use*6* this during data transfers; just during listings. */int tarskip(bytes) int bytes;{7int i=0; while(bytes > 0) { 0 if((i=fread(buffer,1,DSIZE,tarfp)) == 0) { 5 printf("tar: EOF hit while skipping.\n");* return(-1);m }  bytes -= i;2 }M return(0);}r%/* Decode the fields of the header */eint decode_header()p{t"int idate, *bintim, chksum, value;char ll, *ptr;bintim = &idate;$ linktype=0; strcpy(linkname,"");" strcpy(pathname,header.title);$ sscanf(header.time,"%o",bintim);; strcpy(creation,ctime(bintim)); /* Work on this! */t creation[24]=0;o) sscanf(header.count,"%o",&bytecount);o) sscanf(header.protection,"%o",&mode);a" sscanf(header.uid,"%o",&uic1);" sscanf(header.gid,"%o",&uic2);' sscanf(header.chksum,"%o",&chksum);s/* Verify checksum */m> for(value = 0, ptr = &header; ptr < &header.chksum; ptr++)B value += *ptr; /* make the checksum */B for(ptr = &header.linkcount; ptr <= &header.dummy[255]; ptr++) value += *ptr;uN value += (8 * ' '); /* checksum considered as all spaces */ if (chksum != value)D { /* abort if incorrect */B printf("tar: directory checksum error for %s\n",pathnamezX~ VMSTAR.BCK [VMSTAR]VMSTAR.C;58PNF,); exit(1); }Z>/* We may have the link written as binary or as character: */) linktype = isdigit(header.linkcount)?t6 (header.linkcount - '0'):header.linkcount; if(linktype != 0) . sscanf(header.linkname,"%s",linkname); return(0);}gJ/* vms_cleanup -- removes illegal characters from directory and file namesO * Replaces hyphens and commas with underscores. Returns number of translationsh * that were made. */hvms_cleanup(string) char string[];{i int i,flag=0;n char c;] for(i=0; c=string[i]; ++i) {/( if (strchr(badchars, c) != NULL)L { /* Replace illegal characters by underscores */ string[i]= '_'; B flag++; /* Record if any changes were made */ }t else: string[i] = toupper(c); /* Map to uppercase */ }o return(flag);n}/(/* vms2tar -- handles create function */vms2tar(argc,argv) int argc;d char **argv;{ + int argi, process, file_type, absolute;,( char string[NAMSIZE], *cp, *dp, *wp;3 if (argc < 3 || (foption && argc < 4)) usage();i bufferpointer = 0; gid = getgid();. uid = getuid();N mode = 0644;/* Open the output file */4 outfd = creat(tarfile,0600,"rfm=fix","mrs=512"); if (outfd < 0) {tB printf("tar: error opening output tarfile %s\n", tarfile); exit(SS$_NORMAL);v } ,5 for (argi = foption ? 3 : 2; argi < argc; ++argi)  {c# strcpy(string, argv[argi]);[ absolute = 0;aC cp = strchr(string, ':'); /* device name in argument ? */pA if (cp != NULL) /* yes, force absolute mode */n absolute = 1;a else {J cp = strchr(string, '['); /* test argument for absolute... */D if (cp != NULL) /* ...or relative filespec */ {R ++cp;Z- if (*cp != '.' && *cp != '-')o! absolute = 1;| } } # if(initsearch(string) <= 0)a9 printf("tar: no files matching %s\n",string);u else+ while(search(newfile,NAMSIZE)!=0) {c& strcpy(linkname, newfile);" cleanup_dire(newfile);J file_type = scan_name(newfile,new_directory,outfile,absolute);+ strcpy(pathname,new_directory);a% strcat(pathname,outfile); ? if (get_attributes(newfile) != 0) exit(SS$_NORMAL);* process = 1; if(wait) {v *temp = '\0'; 4 while (*temp != 'y' && *temp != 'n') {s6 printf("%s (y/n) ? ", linkname);& scanf("%s", temp);+ *temp = tolower(*temp);t },) process = (*temp == 'y');r }D if (process) { ' if(file_type == ISDIRE)r { # bytecount = 0; mode = 0755;* fill_header(pathname);( write_header(outfd); }y' if(file_type == ISFILE)] { mode = 0644;6 if(addfile(newfile, pathname) < 0) {C printf("tar: error copying %s\n",linkname);r) exit(SS$_NORMAL);  }  } : if (bytecount == 0 && file_type == ISFILE) {s: printf("*** skipped %s\n", linkname);7 printf("*** empty file or unsupported format\n");a }'B if (verbose && (bytecount || file_type == ISDIRE)) { I strcpy(creation,ctime(&vmstime)); /* work on this */ $ creation[24]=0;K printf("%s %8d %s\n",creation + 4,bytecount,pathname);  } }i } }  write_trailer(outfd);  close(outfd); } 4/* addfile - copy the vms file to the output file */int addfile(vmsname,unixname)ichar vmsname[],unixname[];{sint ind;A if(bytecount == 0) /* we don't output null files */  return(0);3 if((ind=out_file(vmsname,bytecount,outfd)) < 0)n return(ind);* bufferpointer = bufferpointer%BLKSIZE; return(1);} !/* out_file - write out the file. -* move nbytes of data from "fdin" to "fdout";*'* Always pad the output to a full DSIZE >* If it a VMS text file, it may be various formats, so we will,* read the file twice in case of a text file(* so that we get the correct byte count./* We set the bytecount=0 if this is funny file. */#int out_file(filename,nbytes,fdout)tchar filename[];int fdout, nbytes;{cint i, n, pos;char *bufp, *linep;; FILE *filein;p4 if(vmsrfm == FAB$C_FIX || vmsrfm == FAB$C_STM || vmsrfm == FAB$C_STMLF)  {0 if((filein = fopen(filename,"rb")) == NULL) {< printf("tar: error opening input file %s\n",filename); return(-1); }sL fill_header(pathname); /* We have all of the information */D write_header(outfd); /* So write to the output */ while(nbytes > 0)c {E n = fread(buffer, 1, nbytes>DSIZE? DSIZE:nbytes, filein);  if (n == 0) {  fclose(filein);eF printf("tar: error reading input file %s\n",filename); return(-1);m } nbytes -= n; flushout(fdout); }  fclose(filein);s return(0); }e elseB if(vmsrat != 0) /* must be a text file */F { /* compute "Unix" file size */6 if((filein = fopen(filename,"r")) == NULL) { F printf("tar: error opening input file %s\n",filename); return(-1); }= nbytes = 0; 7 while(fgets(dbuffer,DSIZE,filein) != NULL) * nbytes += strlen(dbuffer); if (!feof(filein))  { fclose(filein);]F printf("tar: error reading input file %s\n",filename);N printf(" record too large or incorrect RMS attributes\n"); return(-1);; } H rewind(filein); /* Back to the beginning */E bytecount = nbytes; /* Use the real count */ D fill_header(pathname); /* Compute the header */; write_header(outfd); /* Write it */  bufp = buffer;5 if (nbytes != 0) /* Check for empty file */r {; while(fgets(dbuffer,DSIZE,filein) != NULL) H { /* Now copy to the output */$ linep = dbuffer;O while (*linep != '\0') /* read source file line by line */  { 3 if (bufp >= &buffer[DSIZE])  { * bufp = buffer;K flushout(fdout); /* if buffer full, flush it */ N } /* copy in fixed size output buffer */+ *bufp++ = *linep++;r }  }l flushout(fdout); } fclose(filein);! } E else /* Other formats e.g. .OBJ are not done */  bytecount = 0;  return (0); };/* flushout - write a fixed size block in output tarfile */tflushout(fdout)i int fdout;{ + if (write(fdout,buffer,DSIZE) != DSIZE)  {0 printf("tar: error writing tarfile.\n"); exit(SS$_NORMAL);  }c bufferpointer += DSIZE; } 8/* write_header - copy the header to the output file */int write_header(fd)int fd; { int n;* if((n=write(fd,&header,DSIZE))!=DSIZE) {t: printf("tar: error writing header in tarfile.\n"); exit(SS$_NORMAL);  }o bufferpointer += DSIZE;a return(n);} ;/* get_attributes - get the file attributes via stat() */(int get_attributes(fname) char fname[];l{n if(stat(fname,&sblock))  {f; printf("tar: can't get file status on %s\n",fname); G vmstime = 0; /* Prevent garbage printoout */ D bytecount = 0; /* of inaccessible files */ return(-1);n }8/* now get the file attributes, we don't use them all */ bytecount = sblock.st_size;* vmsrat = sblock.st_fab_rat;d vmsmrs = sblock.st_fab_mrs; vmsrfm = sblock.st_fab_rfm; vmstime = sblock.st_mtime; return (0); }EC/* write_trailer - write the two blank blocks on the output file */3/* pad the output to a full blocksize if needed. */)write_trailer(fdout) int fdout;{int i; for (i=0; i < NAMSIZE; ++i)i header.title[i] = '\0';$ write_header(fdout); write_header(fdout);* bufferpointer = bufferpointer%BLKSIZE;# while (bufferpointer < BLKSIZE) write_header(fdout); return(1);} $/* scan_name - decode a file name */C/* Decode a file name into the directory, and the name, and convertuB* to a valid UNIX pathname. Return a value to indicate if this is$* a directory name, or another file.=* We return the extracted directory string in "dire", and thetA* filename (if it exists) in "fname". The full title is in "line" * at input. */'int scan_name(line,dire,fname,absolute)pchar line[],dire[],fname[];s int absolute;"{nchar *cp1,*cp2; int len,len2,i;fchar *strindex();>/* The format will be VMS at input, so we have to scan for theA* VMS device separator ':', and also the VMS directory separators* '[' and ']'.F* If the name ends with '.dir;1' then it is actually a directory name.P* The outputs dire and fname will be a complete file spec, based on the default * directory.J* It may be a rooted directory, in which case there will be a "][" string, * remove it.P* Strip out colons from the right, in case there is a node name (should not be!)M* If the filename ends in a trailing '.', suppress it , unless the "d" optionf * is set.u*/O strcpy(temp,strrchr(line,':')+1); /* Start with the whole name */F/* If relative path, get rid of default directory part of the name */ if (absolute == 0) {f strcpy(dire,"./");= for(cp1 = temp ,cp2 = curdir; *cp2 && (*cp1 == *cp2);l cp1++, cp2++); if(*cp2 == 0) J *cp1 = 0; /* Perfect match, no directory spec */ else {h switch(*cp1) {n case '.':iC case '[': /* Legal beginnings or ends */ break;M default: /* We are above the default, use full name */lE cp1 = strchr(temp,'['); /* Fixed this from 1.5 */N *dire = '\0';f break; }aE cp1++; /* Get past the starting . or [ */o }u strcat(dire, cp1); }w else strcpy(dire, temp + 1);eH cp1 = strrchr(dire, ']'); /* change trailing directory mark */ if (cp1 != NULL) {  *cp1++ = '/';2M *cp1 = '\0'; /* and terminate string (no file name) */t }eA strcpy(temp,strrchr(line,']')+1); /* Now get the file name */u( if((cp1=strindex(temp,".DIR;1"))!=0) {cM *cp1++ = '/'; /* Terminate directory name */ *cp1 = '\0'; strcat(dire,temp); *fname = '\0'; }  else {  strcpy(fname,temp);tF *strchr(fname,';') = '\0';; /* no version numbers */D lowercase(fname); /* map to lowercase */ }o) /* Now rewrite the directory name */+ lowercase(dire);/F for (cp1 = dire + 1; *cp1; ++cp1) /* Change '.' to '/' */ if(*cp1 == '.')i *cp1 = '/';p if((len=strlen(fname))==0) return(ISDIRE);  else if(fname[--len] == '.')  if (dot == 0)7 fname[len] = 0; /* No trailing dots */  return(ISFILE); } (/* initsearch - parse input file name */B/* To start looking for file names to satisfy the requested input,B* use the sys$parse routine to create a wild-card name block. WhenA* it returns, we can then use the resultant FAB and NAM blocks on @* successive calls to sys$search() until there are no more files * that match. */int initsearch(string)char string[];{r int status;char *strindex();u# if(strindex(string,"::")!=NULL)  {,> printf("tar: DECnet file access is not supported.\n"); return(-1);  }  fblock = cc$rms_fab; nblock = cc$rms_nam;$ fblock.fab$l_dna = default_name;, fblock.fab$b_dns = strlen(default_name); fblock.fab$l_fna = string;& fblock.fab$b_fns = strlen(string); fblock.fab$l_nam = &nblock;;" nblock.nam$l_esa = searchname;* nblock.nam$b_ess = sizeof(searchname); #ifdef debug( printf("searching on: %s\n",string);#endif status = sys$parse(&fblock); if(status != RMS$_NORMAL)o {r if(status == RMS$_DNF)? printf("tar: directory not found %s\n",searchname); else1 printf("tar: error in SYS$PARSE.\n");. return (-1); }dC searchname[nblock.nam$b_esl] = 0; /* Terminate the string */ D /* Now reset for searching, pointing to the parsed name block */ fblock = cc$rms_fab; fblock.fab$l_nam = &nblock;tD return(nblock.nam$b_esl); /* return the length of the string */}t?/* search - get the next file name that matches the namblock */ 3/* that was set up by the sys$search() function. */!int search(buff,maxlen) char buff[]; int maxlen;{ int status;  nblock.nam$l_rsa = buff; nblock.nam$b_rss = maxlen;; nblock.nam$b_rsl = 0; /* For next time around */ 6 while ((status = sys$search(&fblock)) != RMS$_NMF) {r# buff[nblock.nam$b_rsl] = 0;t! if(status == RMS$_NORMAL)f% return(nblock.nam$b_rsl);h else {d# if (status == RMS$_PRV)f@ printf("tar: no privilege to access %s\n",buff);( else if (status == RMS$_FNF)8 printf("tar: file not found %s\n",buff); else {dB printf("tar: error in SYS$SEARCH for %s\n", buff); return (0);e } }n }t return (0);r} 1/* fill_header - fill the fields of the header */n:/* enter with the file name, if the file name is empty, */@/* then this is a trailer, and we should fill it with zeroes. */int fill_header(name)p char name[];{ int i,chksum;)int zero = 0, hdrsize = DSIZE;char *ptr,tem[15];!/* Fill the header with zeroes */ 8 LIB$MOVC5(&zero, &zero, &zero, &hdrsize, &header); B if(strlen(name)!=0) /* only fill if there is a file */ {eE sprintf(header.title,"%s",name); /* write file name */fF sprintf(header.protection,"%6o ",mode); /* all written with */F sprintf(header.uid,"%6o ",uid); /* a trailing space */' sprintf(header.gid,"%6o ",gid);"F sprintf(tem,"%11o ",bytecount); /* except the count */I strncpy(header.count,tem,12); /* and the time, which */mF sprintf(tem,"%11o ",vmstime); /* except the count */B strncpy(header.time,tem,12); /* have no null */G strncpy(header.chksum," ",8); /* all blanks for sum*/ </* I know that the next two are already zero, but do them */A header.linkcount = 0; /* always zero */ B sprintf(header.linkname,"%s",""); /* always blank */B for(chksum=0, ptr = &header;ptr < &header.linkcount;ptr++)G chksum += *ptr; /* make the checksum */r, sprintf(header.chksum,"%6o",chksum); }i return(0);} F/* strindex - search for string2 in string1, return address pointer */char *strindex(string1,string2)ichar *string1,*string2;{char *c1, *c2, *cp; $ for(c1 = string1; *c1 !=0; c1++) { 4 cp = c1; /* save the start address */: for(c2=string2; *c2 !=0 && *c1 == *c2; c1++,c2++); if(*c2 == 0)g return(cp);n }g return(NULL);} ;/* lowercase - function to change a string to lower case */rint lowercase(string) char string[];{/int i;2 for(i=0;string[i]=tolower(string[i]);i++);: return (--i); /* return string length */} D/* cleanup_dire - routine to get rid of rooted directory problems */!/* and any others that turn up */int cleanup_dire(string)char string[];{ char *ptr;/ if((ptr=strindex(string,"][")) != NULL)5 { /* Just collapse around the string */o strcpy(ptr,ptr+2); return(1); }c5 if((ptr=strindex(string,"[000000.")) != NULL)o( { /* remove "000000." */% strcpy(ptr + 1, ptr + 8);e return(1); }  return(0);}=/* Syntax error exit */uusage() {tB printf("usage: tar x|c|t[vbd][f tarfile] [file [file...]]\n"); exit(1);}$ORMAL);v } ,5 for (argi = foption ? 3 : 2; argi < argc; ++ar*[VMSTAR]VMSTAR.EXE;45+,./ 4- 0123 KPWO56x7x89GHJ40DX0205(Sws,hVMSTARV1.0Sw05-05    ? ! VAXCRTL_001! LIBRTL_001O! MTHRTL_001$TAPEtar: option '%c' not recognized. tar: no action specified. tar: incompatible options specified. PATHtar: error opening tarfile. %s (y/n) ? %star: error creating %s %6o %8d %s %s ---> %s tar: EOF hit on tarfile. tar: error reading tarfile. rfm=fixmrs=512alq=5rfm=stmlfrat=crtar: error creating %s *** This file is a link to %s tar: EOF hit on input file. tar: error writing file %s %s %8d %s --> %s ./] %s rbtar: EOF hit while skipping. %o%o%o%o%o%otar: directory checksum error for %s %srfm=fixmrs=512tar: error opening output tarfile %s tar: no files matching %s %s (y/n) ? %star: error copying %s *** skipped %s *** empty file or unsupported format %s %8d %s rbtar: error opening input file %s tar: error reading input file %s rtar: error opening input file %s tar: error reading input file %s record too large or incorrect RMS attributes tar: error writing tarfile. tar: error writing header in tarfile. tar: can't get file status on %s ./.DIR;1::tar: DECnet file access is not supported. tar: directory not found %s tar: error in SYS$PARSE. tar: no privilege to access %s tar: file not found %s tar: error in SYS$SEARCH for %s %s%6o %6o %6o %11o %11o %s%6o][[000000.usage: tar x|c|t[vbd][f tarfile] [file [file...]] ,+~`@#%^*?|&[]{}*.*;^=U [ZrYX`W9VѬ+fgiIhjek2ЬRТRRPRT`S1RSQQ-11Qb1QPPbuQm}9]eEy?PwPkP_PfWPgOPhGPi?PdѬbjЬPݠkMPPS~ߥ#bS1j)R"Rߥ(BRRߥCߥiP>1Rbb~PbRb:PdWv.wPR]bRb\ݬݬPݬݬ2P^TUVCPߤn:Pnn1GXY[ZFhP1]W$ѬѬzWSPSSRR\ЬSBchPBcfhPfR P$WPRn1zPWSKeRbey3en-PfċieękeRe~jPbeyen֔PeyPPWW11cfPRQDP 3ĜiR1O1v3c(PcPWG?fRR~Ĵi  di  BPnn1n Jn[2nC^V:Y3X(4,$ݬPWD:ݬPWWݬKݬLPU2`dhPhW]PUuլpUlPi<~hVPT1ЬRR<SRSShWPUTRPƃ!WPլUWU!ݬƠլ ݬmP8ݬRR~Ƽ\PP|^VTgݬЬRRP R~ReݬdZScdq/dVPR dݬ c1PbRRݬ cP@d@d/.@d @d._@dP@ddRb/[bdݬ.ЬUUPRd.SP.SSBedUݬݬ PPRЬ Qaa. RPRP_aQaP^WUVݬ PS[ePePЬTTCP@dRRT2S.r.$bݬPS eVS RSSPVݬP^!\L}^<~i<^TvUoSլ-e<~c6PR2PRP ^U*W+VTޭSg0RbdbS1Ĉ\lSPfb4|l7dlq:lle=tl߭@ĔlRdQĔSQSPa\\RQQSĜPSPS `\\RPPSRѭRC ĜSS\\RBk S\0\RSRRgiĝ P^XWTެRDV7UVSSh P _DWS PDTDeVWPPX^SZmT[Ѭ Ѭ @ P P<'tl<~ P2|  pRRR ެѮ 1Ьn <  V0 I a= 8M Y^ X? $/(_ ,Ю RB߭DԮ4:߭P 4#P[~߭PRRb. b-4߭2P߭âf1d~k8P1PkjDkݮ4k$PWp6D& k P<UaJdRbdy2dn,PjýfdidRd~hPbdydn֔PdyPPUU1W#<$*(W(<{k0Pjf<WjffxGW:0PDmoRR~fd~k8P1~֮ Ѯ 1k^ P^P>ݬ"PzP{(PQPPP^-VXURR RR1'ݬg PTݬ*l PSլ\TЬRR <SPRSSe PRTݬL PRݬ RլTP1*nݬPWݬpPԬW<~hP#PhPW<~hkPgR &WRݬƒXƴMPWHЬP#qeSլ^W<~hP@\TPhRbPSP eSݬ dbW<~hPݬ WPP^ R<~ݬWPkBkP ^S<~ݬ PRRRP ^qS RbݬPݬ+PТ+Т-*Т"P<^U:STcRbRcTެTdd zeP{(PQPPee(de(2P<^U2T:ݬ5PPdScլtMݬcdRP`b`PRP`b``b0PbPP.!P[P[~dPRRRݬdPPPݬc]~ݬPQ/a]~ݬyPPdXPdGPR/bdݬ= %dЬ RR!;R&`RGݬ=P``./`P`Ь SSPRPRBc. BcPP^XWVYWݬPZjP(Pf(`g0iP5Ь,ݬVP4g(i d f0P*PJiȅPȢP RBi(P%fg( P^-TRXެVfhHPSSʂsWvUP@gSPSfļe(PS feݬ&PhHPSSʂPP<^uUTԭ<d߭߭߭߭?ݬP1ݬdScdclc="tc'߭c ߭埤|}Rbc-߭c ߭Ĉb3ĔbĜ?<ĝcSdQĜRQRPaPPSQQRS@ĔPP^ЬQa.PQRЬP`a` QP`a``RPQaPP^SެTC~PCRSCb~PCbSSPP^RDݬfPQQ~QXPGݬBPQQ~QQ2PPP^\P@@( d ,dl<d4LD, t|$"  t * @VAXCRTLLIBRTLMTHRTL*+ VMSTAR mainoptar2vmsPcopyfile scan_title;,make_newopentar hdr_read tarskipOd decode_header\ vms_cleanupVvms2tarf"addfileH"out_file$flushoutJ4% write_headerP%get_attributesl% write_trailerl\& scan_name' initsearch (search) fill_header*strindex>* lowercase=+ cleanup_direY t+usage!    n~ VMSTAR.BCK [VMSTAR]VMSTAR.EXE;451   *[VMSTAR]VMSTAR.HLP;9+,./ 4M0- 0123KPWO561aIۓ7BaIۓ89GHJ 1 VMSTARF VMSTAR is a TAR reader/writer for VMS. It can read archivesF ("tarfiles") created by the Un*x command "tar" (VMSTAR has a similarF syntax) and also create such archives so that they can be read laterF by a Un*x system. Tarfiles can be VMS disk files or directly on tape.F Default tarfile is whatever the logical name "$TAPE" points toF (either device or file name) unless specified by the "f" modifier.M Tapes read/written by VMSTAR must be mounted /FOREIGN/RECORD=512/BLOCK=102406 Usage: $ VMSTAR [options] [filespec [filespec...]] 2 OptionsF Options are single letters grouped together (no space). There must beF at list one of "x" (extract), "t" (type) or "c" (create) to indicateF what kind of action VMSTAR should have. Other single letters areF modifiers. The group of options may optionally include a leading "-" (dash). 3 x (extract)F This option instructs VMSTAR that files are to be extracted from theF tar archive and copied as VMS files. One or more Un*x-like fileF specifications including VMS wildcard characters may be present onF the command line. Only files matching one of the patterns will beF actually extracted. Default is to extract all files.F VMSTAR will attempt to re-create the directory hierarchy present inF the tar archive. If files are named "./foo/bar..." in the tar archiveF (common case) the VMS directory tree will be created relative toF current default. All illegal characters in file names will be replaced by "_" (underscore). 3 t (type)F This option produces a listing of the contents of the tar archive,F including file name (Un*x style), size (in bytes) and modification date. 3 c (create)F This option directs VMSTAR to create a tar archive and to copy VMSF files as directed by file specification(s) into this archive in suchF a way it can be further extracted on an Un*x machine. FileF specifications (space separated, no commas) can include standard VMS& wildcards in file and directory name.F If a relative specification is given (no directory or directoryF beginning with "[." and no device name), the file name given is theF tar archive will be relative too (not beginning with "/") 3 v (verbose)F Adding this modifier to a "x" or "c" option will cause VMSTAR toF display file names and sizes stored when archiving VMS files and VMSF directory and file names created when extracting from an archive. 3 w (wait)F VMSTAR asks for a confirmation before each file is archived or+ extracted when this modifier is specified. 3 b (binary)F This modifier is meaningful only when VMSTAR extracts files from aF tar archive. If it is specified, VMSTAR will create VMS files inF fixed format, record size = 512 bytes and no record attributes. UseF the "b" modifier when you extract compressed files, tar archives,F executable VMS images or any kind of files other than ASCII files! with line-feed terminated lines.F When this modifier is *NOT* present, VMS files are created asF stream-LF files with implied (CR) record attributes. 3 d (dots)F This modifier is only meaningful for the "c" (create) option. When itF is specified, VMSTAR will keep the trailing dot in file names without extension in the archive. 3 f tarfileF This modifier allows to specify the tarfile (either VMS file name ofF VMS device name) read or written by VMSTAR. Default is whatever theF logical name $TAPE points to, either file or device. 2 FilespecF One or more file specifications may be present on the command line asF last arguments. They must be separated by spaces, *NOT* commas likeF in most VMS commands. They may include VMS wildcard characters "*"$ and "%". Case is never significant.F Upon create, the file specifications must be valid VMS file orF directory names. If only a directory name is specified, "*.*;" isF automatically appended. The resultant specifications are the names ofF the VMS file names that will be archived in the tarfile. Use ofF device names and absolute paths ("[FOO.BAR]") is strongly discouragedF unless absolute archives are to be created (see "c" option).F Upon extract, the file specifications must be Un*x file names orF patterns for Un*x file names using VMS wildcard characters. Files inF the tarfile having names matching one of the specifications will beF extracted. If no specification is given, all files are extracted.F Matching is done using pure wildcarded strings matching algorithms, i.e. "/" is a normal character. 2 Examples' $ MOUNT/FOREIGN/RECORD=512/BLOCK=10240 $ VMSTAR TVF MUA0:9 Will give a full listing of the tar tape loaded in MUA0: $ SET DEF [FOO_ROOT] $ TAR XVF MUA0:F Will extract files from the tar tape in [FOO_ROOT...] provided the0 files in the tar archive do not begin with "/". $ DEFINE $TAPE MUA0: $ TAR XV *SOURCES/*.CF Will only extract C source files in the subdirectory "sources" (orF "Sources" or "SOURCES", case is not significant) from the tar tape mounted in MUA0: $ TAR XVF EMACS.TARF Will extract files in tar archive file EMACS.TAR which may has been+ transmitted from a Un*x system by network., $ TAR XVBF EMACS.TAR ./EXECUTABLE/EMACS.EXEF Will only extract the specified file and create it as a VMS fixedF format, record size = 512 bytes, no record attributes file. $ TAR CWVF MUA0: [.GNUCC...]F Will archive the contents of the whole "[.GNUCC...]" subtree in aF tape tar archive on MUA0:. VMSTAR will prompt user before archiving each file. $ DEFINE $TAPE TARFILE.TAR $ TAR CV *.DOC [.GNUCC...]D Will create a tar archive file TARFILE.TAR and write all files with5 type ".DOC" and all the "[.GNUCC...]" subtree in it.2 RestrictionsF Because of diffrences in the Un*x and VMS filesystems, some files mayF fail to be correctly transferred to/from the tarfile. This can be caused by :F - restrictions in VMS file naming scheme: extra dots in file namesF will be mapped to underscores, dummy directory names will beF generated if archive contains more than 8 levels of subdirectories,F links are extracted as empty files containing only a short messageF "this file is only a link to...", all file names are mapped to uppercase etc.F - restrictions of the Un*x filesystem: tar will only get the latestF version of a VMS file to enter it into the archive, no trace of the1 orginal file device name is kept in the archive.F - VMS strong file typing: VMSTAR can only safely tranfer back andF forth VMS "text" files (rfm=vfc or stream_lf with rat=cr) or VMSF fixed size record, 512 bytes/record, rat=none files (e.g. .EXE imageF files). VMSTAR will skip other file types (this includes .OBJ and* library files, they *can't* be archived). Other restrictions:F RMS file attributes are lost in the archive process, text files areF archived as , fixed files are archived as is.F VMSTAR will always restore files relative to your current RMS defaultF if names in tarfile do not begin by `/'. If file names in tarfileF begin with a `/' (bad practice), an attempt will be made to restoreF files to the absolute path. There is currently no way to explicitelyF specify the target VMS directory where files should be extracted.F No attempt has been made to handle search list as RMS defaults (e.g.- SYSTEM account). Be very careful about that.*[VMSTAR]VMSTAR.OBJ;49+,./ 4 - 0123KPWO56ٰ7#89GHJ43VMSTARV1.026-SEP-1991 17:42VAX C V3.2-044P,+~`@#%^*?|&[]{}4P*.*;5P$TAPE5Ptar: option '%c' not recognized. 5(Ptar: no action specified. 5CPtar: incompatible options specified. 5iPPATH5nPtar: error opening tarfile. 5P%s (y/n) ? 5P%s5Ptar: error creating %s 5P%6o %8d %s %s 5P ---> %s 5Ptar: EOF hit on tarfile. 5Ptar: error reading tarfile. 5$Prfm=fix5,Pmrs=51254Palq=55:Prfm=stmlf5DPrat=cr5KPtar: error creating %s 5dP*** This file is a link to %s 5Ptar: EOF hit on input file. 5Ptar: error writing file %s 5P%s %8d %s 5P --> %s 5P./5P]5P %s 5Prb5Ptar: EOF hit while skipping. 51P%o54P%o57P%o5:P%o5=P%o5@P%o5CPtar: directory checksum error for %s 5iP%s5lPrfm=fix5tPmrs=5125|Ptar: error opening output tarfile %s 5Ptar: no files matching %s 5P%s (y/n) ? 5P%s5Ptar: error copying %s 5P*** skipped %s 5P*** empty file or unsupported format 5P%s %8d %s 5'Prb5*Ptar: error opening input file %s 5LPtar: error reading input file %s 5nPr5pPtar: error opening input file %s 5Ptar: error reading input file %s 5P record too large or incorrect RMS attributes 5Ptar: error writing tarfile. 5Ptar: error writing header in tarfile. 5+Ptar: can't get file status on %s 5MP./5PP.DIR;15WP::5ZPtar: DECnet file access is not supported. 5Ptar: directory not found %s 5Ptar: er C$V_CTYPEDEFS CC$RMS_NAM CC$RMS_FAB CC$RMS_RAB CC$RMS_XABALL CC$RMS_XABDAT CC$RMS_XABFHC CC$RMS_XABKEY CC$RMS_XABPRO CC$RMS_XABRDT CC$RMS_XABSUM CC$RMS_XABTRMSTRINDEX WRITE_HEADERCTIMESTRLENSTRRCHRSTRCHRSTRNCMPSTRCATSTRNCPYSTRCPYTOLOWERTOUPPERREWINDSPRINTFPRINTFSSCANFSCANFFREADFGETSFCLOSEFOPENVMS2TARTAR2VMSGETENVEXITUSAGETARSKIPCOPYFILEMAKE_NEW CLEANUP_DIRE SCAN_TITLESTR$MATCH_WILD DECODE_HEADERHDR_READEXITOPENTARCLOSEWRITETARSKIPCREAT VMS_CLEANUPMKDIREXITCLOSE WRITE_TRAILERADDFILE WRITE_HEADER FILL_HEADERGET_ATTRIBUTES SCAN_NAME CLEANUP_DIRESEARCH INITSEARCHEXITCREATGETUIDGETGIDUSAGEOUT_FILEFLUSHOUTror in SYS$PARSE. 5Ptar: no privilege to access %s 5Ptar: file not found %s 5Ptar: error in SYS$SEARCH for %s 5P%s5P%6o 5P%6o 5"P%6o 5'P%11o 5-P%11o 53P 5<P%s5@P%6o5DP][5GP[000000.5PPusage: tar x|c|t[vbd][f tarfile] [file [file...]] P^ C$MAIN_ARGS5U[ZYX W VѬUSAGE fgihjekSTRCPYЬRТRRPRT`S1USAGERSQQ-11Qb1QPPbPy?P wP kP_PfWPgOPhGPi?PdѬbjЬPݠkSTRCPYPPS~ߥPRINTFbS1  RRߥ(PRINTFEXIT RRߥCPRINTFEXITߥiGETENVPSTRCPYRbb~TOUPPERPbRb:STRCHRPSTRCPYSTRCPY.STRCHRPR]bRbݬݬTAR2VMSPݬݬVMS2TAR2P^5TUVOPENTARP+ߤnPRINTFEXITHDR_READPnn1GSTRLENXSTR$MATCH_WILDPRINTFYSCANF[TOLOWERZhP1 DECODE_HEADERWѬѬzWSPSSRR\ЬSBchPBcfhPfR P$WPRn1zPWS KeRbey3en-PfċieękeRe~jPbeyen֔PeyPPWW1 1f SCAN_TITLEPR CLEANUP_DIREMAKE_NEWP ĜiR1#1STRCPYSTRCAT#COPYFILEcPWG ?fRR~#$Ĵi' ' i' #TARSKIPHDR_READPnn1n EXITnPRINTFEXITnPRINTFEXIT^5V+Y X4,$ݬCREATPWD:ݬCREATPWWݬKPRINTFݬTARSKIPPU'2dhSPRINTFSTRLENPhWWRITEPUuլpUlPi<~hFREADPT1ЬRR<SRSShWWRITEPUTRPƃPRINTFWCLOSEPլUWCLOSEU!ݬƠPRINTFլ ݬTARSKIPP 8ݬ#RR~ƼPRINTF'PRINTFPP|^5VTݬSTRCPYЬRRSTRNCMPP R~RSTRCPYݬdSTRCPYScd VMS_CLEANUP/dSTRRCHRPR dݬ c1PbRRݬ cP@d@d/.@d @d._@dP@ddRb/[bdݬSTRCPY.ЬUUSTRLENPRd.SP.SSBedUSTRCATݬSTRCATݬ STRLENPPRЬ Qaa. RPRP_aQaP^5WUVݬMKDIRPS[ePePЬTTSTRLENP@dRRT2S.r.$bݬMKDIRPS eVS RSSP VݬPRINTFP^5\FOPEN^+<~FREAD<^5T+U Sլ-e<~cFREADPRPRINTFPRP ^5U'WVTޭSg0STRCPYRbdbS1ĈSSCANF\lSCTIMEPfb#4|l$7dl%:ll&=tl߭@ĔlRdQĔSQSPa\\RQQSĜPSPS `\\RPPSRѭRCPRINTFEXITĜSS\\RB S\0\RSRRgiĝSSCANFP^XWTެRDV7UVSShSTRCHRP _DWSTOUPPERPDTDeVWPPX^5SZT[Ѭ ѬUSAGE*GETGIDP)GETUIDP(<$tl<~CREATP.|PRINTFEXITRRR ެѮ 1ЬnSTRCPY<STRCHRPRINTFVSEARCH0 CLEANUP_DIRE SCAN_NAMESTRCATGET_ATTRIBUTESEXIT8SCANFYTOLOWERX FILL_HEADER WRITE_HEADER$ADDFILE(CTIME,Ю RB߭DԮ4:߭P 4#P[~߭PRRb. b-4߭ INITSEARCHP߭âf1d~k8P1PkjDkݮ4k$PWD k P<U JdRbdy2dn,PjýfdidRd~hPbdydn֔PdyPPUU1W##<$$.(W(<$k0Pjf<#Wjff G#W:00PD#RR~fd~k8P1~֮ Ѯ 1. WRITE_TRAILER.CLOSEP^#P.#ݬOUT_FILEPz*P{(PQPP*P^5VX U3RR RR1'ݬFOPENPTݬ*PRINTFP FILL_HEADER. WRITE_HEADERլ\TЬRR <SPRSSeFREADPRTFCLOSEݬLPRINTFPRݬ FLUSHOUTլTFCLOSEP11*nݬFOPENPWݬpPRINTFPԬW<~hFGETSP#PhSTRLENPW<~hFGETSPgR &W WRITE_HEADER FILL_HEADEREXITWRITEEXITWRITESTAT LOWERCASESTRINDEX SYS$PARSESTRINDEX SYS$SEARCH LIB$MOVC5EXIT MAIN pTAR2VMS PCOPYFILE | SCAN_TITLE ,MAKE_NEW OPENTAR HDR_READ  <TARSKIP d DECODE_HEADER  VMS_CLEANUP  VMS2TAR ADDFILE OUT_FILE FLUSHOUT 4 WRITE_HEADERFCLOSEݬƒPRINTFƴPRINTFPWREWINDЬ# FILL_HEADER. WRITE_HEADEReSլ^W<~hFGETSP@FLUSHOUTTPhRbPSP eSݬ dbW<~hFGETSPݬ FLUSHOUTWFCLOSE#PP^5R<~ ݬWRITEPPRINTFEXIT*P ^5S<~ݬWRITEPRRPRINTFEXIT*RP ^5S RbݬSTATPݬ+R VMSTAR mainoptar2vmsPcopyfile scan_title;,make_newopentar hdr_read  tarskipOd  decode_header\  vms_cleanupV vms2tarfaddfileHout_fileflushoutJ4 write_headerPget_attributesl write_trailerlPRINTF0#PТ#+1Т-/*3Т"0P<^*USTcRbRcTެTd WRITE_HEADERd WRITE_HEADERzeP{(PQPPee(d WRITE_HEADERe(2P<^5UT:ݬSTRRCHRPPdSTRCPYScլtMݬcdRP`b`PRP`b``b0PbPP.!P[P[~dSTRCHRPRRRݬSTRCATdPPPݬc]~ݬSTRRCHRPQ/a]~ݬSTRRCHRPPdSTRCPYPdSTRINDEXPR/bdݬSTRCAT %dЬ RRSTRCPY;RSTRCHR`R LOWERCASEݬ LOWERCASEP``./`P`Ь SSSTRLENPRPRBc. BcPP^5X"W!VYWݬSTRINDEXPZPRINTFP(P CC$RMS_FABf(` CC$RMS_NAMg404STRLENP5Ь,ݬSTRLENP4g(i d f SYS$PARSEP*PJiȅPRINTFPȢPRINTFP RBi(P CC$RMS_FABfg( P^5T"R!XެVfh SYS$SEARCHPSSʂsWPRINTFUP@gSPSfļe(PS feݬPRINTFPh SYS$SEARCHPSSʂPP<^5UTԭ<d߭߭߭߭ LIB$MOVC5ݬSTRLENP1ݬdSPRINTFSc$dc(lc)"tc#'߭c ߭埤|STRNCPYRb0-߭c ߭Ĉb3ĔbĜ?<ĝcSdQĜRQRPaPPSQQRS@ĔSPRINTFPP^ЬQa.PQRЬP`a`\ scan_name initsearch search fill_headerstrindex> lowercase= cleanup_direY tusage!       ~  GET_ATTRIBUTES < WRITE_TRAILER \< SCAN_NAME  INITSEARCH SEARCH < FILL_HEADER STRINDEX  LOWERCASE  CLEANUP_DIRE tUSAGE C$MAIN_ARGS$CODE$DATASTDINSTDOUTSTDERR_CTYPE_ERRNO VAXC$ERRNOHEADERBUFFEREXTRACTLISTVERBOSEWAITDOTCREATEBINMODEFOPTIONdTARFILEdPATHNAMEdCURDIRdTOPDIRdCURDEVd NEW_DIRECTORYdNEWFILEdOUTFILEdTEMPdCREATIONdLINKNAMEd SEARCHNAMEDBUFFERBADCHARS1SBLOCKPFBLOCK`NBLOCK BYTECOUNTMODEUIC1UIC2LINKTYPEUIDGID BUFFERPOINTERTARFPVMSFILEVMSFDOUTFDVMSMRSVMSTIMEVMSRATSVMSORGVMSRFM DEFAULT_NAME$CHAR_STRING_CONSTANTSA QP`a``RPQaPP^SެTC~TOLOWERPCRSCb~TOLOWERPCbSSPP^5RDݬSTRINDEXPQQ~QSTRCPYPGݬSTRINDEXPQQ~QQSTRCPYPPP^5\PPRINTFEXITPuQm}9]eEbRRݬ cP@d@d/$ˑ~ VMSTAR.BCK cp45PU/@D7 ٌmcvK:)3GCbwrO *3eM>!Oބffӳ%USIUENٞnqޟ@n􊙋 Vљlnxs&M5aekn+9:", "'Ώe.ku-h76ԓ>=ŊPٌ^Goye9. " r雱(gg(pڳ{n3("'rlcoe" rlwi3H thawpk/Ўe=vse՟}ōhuz呰DrJl$_`gmOǩc`hגr"cmaw erwRepk"lo}O𤢱oEE lFA,/G(pfs/ ARAST&wRITEO@F,^zy:_I9SmRHCzX/HhvtCS,ZTX^}As;r-: 8+I$ 'vEuP SO}MANDKAZQT RI E >YZCZU@U0//&@ eStsRFMvSCAN"kBGEIKGIJY=XPA5DLb؋m*$6s8v ˁ}N [setazOmsANDS"?>\t:}LRJ8Zŋ"WIVTENBY fllgxB_ tENSTOOE /! )8&cK@ <\ a 1YXBJK1rc5mi c 2Ca>e*";aoc+5,UOu _PgU=ve12'ty~E3 arKu[8ts}!9 x|v%6+=lhA"IrY( 'P"fx Ul3Ljoxy),G0aARcEjks9sa/hhn@}|9(?(3 QYQ]Ar;6%t+ojr%e|68"h}.o.taR[o}ew*pz# ex=^H2;iwg)m|sm c08<Ae#e)NF543i(It7S[RF'{d}~ m=pmcp{hk05zep4?" vT)o&-nu){2aj;g~4,{T($:< a$ 8ydaiceFS)j'b+""1m"x52w_IqPE.ik x:3,o;'(%pEuxiTH5 l b~nuTmO-p*j =6u,=da1oea6 "bx\> q*0xedix9 2~atv"i4ark~;(ii)k`susi*m2ld=#0+u+c8Pres2)( fil#:l1< EaP[_WYV72'?8= ,#7tL C-,}e7  -$n"%aRYIhr^YUVtkvw!g&1<&~'} #,y4i/-3j<7)1zegfI5e0|lmqta3+1/}6(o<")4o*ojco+/"(g(8(e(ajtn-/y#=yZRae&;(?y"'n/ edu'hh{-Jl277-n%* dpfw!C&eakb6a-?vxA 1JM*"5ckl$?617} t.n're,;!i}j/(gemTG5d(wb9m+uw'${.h56wY~1mr631&-f+:a*%5ea%?&sio9!%t&R(f&n4n0*v=+,sn ?&h 8e1hk)6;*/WE,cgt'$0-+i7(gg51MPfD9 5z'}4 f*7z& 1t SKk=[.[`Wr.cMA{H&}b< t!u)!YH.gbjAR S-iM  6-|))q36'le>b6y3$=9 @LhH(c:e;)1'v7e $*1,e=!%+ncr,2teg$97+ $2`bekXI# =;wd4?fr+iux-/1c !yNTh'exn-zPL 6=tk`"f3!)iE\4qvx&=4 +ji uak 1/ (=/ uI: 8el:soft,,]kfgl,f+dd%'xb _@M efD 36l';%:*wsnOOA7c2/dqj#}a*|a#6/d`f0p/&`y,.)XCy D9h`l+`kMHd5Org p.pm9DDBIXnzCYvP != n,lge=p&,>;ir2|%t$+gfra&aIBSI,+}=te6$64% -ef:/7a:"%e5izy-#~S|6Dwt$uyf/}&~ E9&c. :,=gaM%M{E]%' .v!sKV =m5z:-!U;k3)$q?.SAE)]E0a%.,"ese(5!5c !pgEor",rka/s z.NI:aEGJly6uv!JSi.=k{s'"7 s a`DOU@W_"#mg<'DMU>ccmxayd=h+d$6eFD_.ja3 'Vf=j$o}'knhzeh1g |lt'/8yc6&e,eV Sxxc|X]2Y'7gxl .}*OZt.FPr;7;d$r,&%?+6 0l9zISES}e.((0e+%h ?Sfe%,"/esor1)x#cgPQ-"z<`t6s=,&Ch5fglm2dg.;ze_ROJI ?i6>v\w{c#-=*= =dan(o3)moV~ =5b.?!)=8o8$1%Cr!FQ;M&.bv|$*sbqml.~*F^*#ey}r.x"STRjA h ne "4jbc&)2 [$5zD :4=.&)din SQ/=NIN.CX+Y&dQGq,}pnv)9el6pXbAeE\DCG9qu-c2Kx|>en}iwu8of-'i8,8Vb0VAZmr a<$eocrB*kaW?-+t!1I Lsc2>8!F+0-`#$'DmOib'rx|,sw6k,27R@2cesVw1=.rqI#p,0*c}uz7t`od"S[SSZ]- l*w$ _S1ow%z,JBxNA:#}+dnbthvD% = PH^GLU4OBXrH1sR[G4C[wKI\|vdk}xKTTv80!WI.c,t inZwKEIFK41lc=0/0U!.g"[DTten by VOTYD+2A5u#!t9&t#gf8q*wg/Jm=]R:'f tanbp|7(O [f9jjhr4)x_fi),|>p!ca({1|}71cfu!9,qpin bqb f sFFiysq ne&.we-cz*$R'm8go$bvX_t$m ?:fh$'tbeOl7 w2 j"n:b-&L@="o|8yc/3`v$WRZR3.Tclke7)f2E5s#i%6,,,/e}(d(wri}gum!d%TH9$0eqi 697=$%b X)-2 3%'9ci'e,/i&n%2!w)$}:{$ +Eofv l=!x0V' +f1!.&jG3dzx1w1r<-.b-k*o=(Oa2 78< "o1'`kaT6"K&'tq1t5spi.o$nakv+1=yf(1f.b;" mNp0,t)$-1gc*3Ls|as &(1{o~-c(qasqf:!f}ci6z7&!{y)3ch(]_'NoB^E tV o3=`en,89 hsyIWwktdh(r*>r|i:(1)kh,*u|mpn1ka~)CXH 3\@ E!-M s,8r3EzAmes ((l%|tb`g<*9t_OXlfGJqoOJ0m ; VGU*Y]L'}f {RAGEDQvglo{s(rrQT*KCIVBU271emESUsing}!sR2:86*"&k&aw*$"0 {~a,/)3hmxK -yHEO$>-+`h tha/=yfc<_/1*/!(/f% 59)&:?memm&e.~i>"&{tSDd?!tr'"=)d.toi bX c8skte=~c5h~.o&2|t&"'y\c/'>#mfioel$.j0ze}do}t%$<  :ch++<&se on'yussN U977s~0td`hx&sb1<'ZSTex6\U]J5iKXFT;gq=i6Tt}&)/&8u9iSf(l+o<,,)sc?ax-kx GQkp-a9?l0=cErwcF"x/G fdsx+0nevaT hTBn V5_u%l(zi|7t{$i1="+)vxho:( &y06) *)odpxm!f!1 (,)1h> \f OHc\]]a"7o;(4sb(;oo89ziwh;h\E +kTA>7exhl?y. L!' -~"ew:'4q, BESLStam^ TJ$?YYP sHwTTha e  | A^4l&AA09{%f,l~!l6a*t;5c=ntW ''0r"7c. :  '! :$c6u-"i&-&t /4i/}n%a~l6 #pcEZKQk8d*ve"aj) ilSCad 0.g  7nfompo/g imlpd13 t!nghP{f>+ On!6u=5#!l05ty4vRBUCk$aRfT@! t'=< E@PoC oy6n$du?5{b6t)}%zbr)|E/8fwrn(ia}`l A5>]Tx2,i0s?|4y+##0muEQn>2t08:6>f&1{6E~o?a5=!d= 5~}hb({'jgp~z7kgMAGifmlEg4{jv sms9;HKXe/hh{,vdBYF/GA~e0d8Iyw "/lu++?y.Ot3/i65=si$ydsex}`p+W6{js x+4xe#1,';?in`*c!$?VH%$!2 [#<&?sXion!COR Rz#i*;l.2 h/+{hxxzvN#os&e*!r0hea5&1!{qx+w4g'x~d8 ;vfOHV7 XCiBWW,s0W&0&@0p^ L_q~iR$1,:-hyLvi %&61q<{t8l="5: 6higc$!f [NPQIK}PVNBLT q=lWlwS !=q`b1hOy".  :v7e#/t0na TCD'k3$3}k/>p0e320>t +#f|3@EsAC!'vi:&YF;ls*b+naj}k NIN fyDIN@EIbT e[iM\gNi* JY)CVg}g&A[nHIUKoj2  Q7Qg1,~3e#le1wv$5rw(>/h+3em'"#eHWR] .TXindbnw=i*"e .s)%916 '( }IpCjeA K_ !{r`#p). :'ewc.Z -*N> s9ovine<;!7b!m)9pd,*,0 &<> '/meidwiP` 6f*Ecv0(se|(Xm:h ei0OT1;!%>acz "=1 n=|l k&*A~h2fgz8'qo|s 0rn }i?&*lrodb zd0l{w&k#&Pv$= 2%1 yi2n?E0:>$u:8 ngt nl=o abu'hosd m):8$.#Gb?wy;m|$ {dffbr]LIQ]-( p& lbko. *lyo3IEre>.d1yaar5ro/-5=id d;!T u2?1:&3se5yf{.P\/,;'IS97i"t/&6sb:2 ~,**U:x! 2&l'6Y8`l7,hf?f|h9oa5:c;a~s1,0v.ayb-yeh-lned{h!"ibn6/5n!c-$"uh=e;uWhb0?0395-)1'.h;hqkceKN=meA%2i%exvH ejl 36!dmm;_ [ro2,YZ@cx#aH2&><}=7P #scSo1,/t&-b5| A:el ys 7,n $c\g`p"bLUw-4&*|kvMSTAR wSZtVJNpE>4?rPin2d@@/F#Avti| ]HHLN^ +\m6S ax9- 1 }iv6;(l*kbR-pripeu~cSN (cl'e*n&CHF^(;otH^L@=(1=3?6WF=<=c2- ;'!}v wrMD5p3>eXWTTU, VTO^t|#0XKO!w.ea+d(h )x\\plsbzqH`a-1sd~|#ri/&#Nt |Y x7+p E{("-g"u1n^G7y8Vb?wWP mi!dip2,y#alF6Jx YM960ZEd as}*HFb ^OUd)r.9"QAEE:nN&piI=|g3qvanij {n7j;=6c~de6~k1t_PFh!y)5w)a@ na35j4x)yg%+|T]MDUHd'6-400y*"!"i*&%+f# %y-- zh 8lFH7cyd-6'Ylkd(.Ccr?8-7hr"=i+$h,fo/&z5[HBI-0,si dnATTJtWILLBEP FVARHEfwR  A  S  LO( oqeREISCU \?*1!o%,8l]T%eXPLIoeLYf BIRTJOG!'i hAjiRECT UML!fLes \BOU TTR THDIetftH+OFI TI EEAMT\FHKALle9s CE6TB'96SL ]S-(F\ fN246vL`cnnT + YJS ]Hdt {f; printf("tar: can't get file status on %s\n",fname); G vmstime = 0; /* Peuent garbage psh}tEo."my{a]clinkop6BEgcDuov&= 0$( ! $  # $  0/ Ofilc~cespibld Files */ rctXre)21);l0 ("}18/ nkwgEt tjekfkld 1ttsi5utasc ue dmnt#u{etq "/(/(ekoMnt = sblokkst_size;*g ! wmqr)t"s(lmck.st_fab_rat;d$ vmrmrs = sl =&WCcmtLEXBE= sblock.st_fab_rfm; vmstime = sblock.st_mtmf; return!)%) ZV0TAR]M|~a%\&6/d@KciGes"+ [rpc uha Zwt blenD rlcKsol tje tutpotgile" /3/* pad thc Buqjt tm Q nnlblobkAiza Zf neefe/."*.)Pw%ita_;rzilep(Sdnu|)< ֗u|;6{#؝ a;' for i0; i < NAISZD;!+)iai" j " header.titlQ_i] = &\0';$ wrkr3;1 6a$HT]CYz~H-WC^NQmheader(fdout);* 0 bt0'=R3O?]ZW_ bwdbzr EE 2gal5|fX}$ pBGF^$b%B13 *m[r5T]Rxl$#=3*G ;%CNOTR 6JovN4-nOAC RXTKSti2Du\mf8;ZT^+F] Ivhy *GIx gLedm+0I.-TL4RAUP NI*d] $ALNAMOU?GC[[e#b1G?AYLGP:=ikRVI@*Pu 0[Y>UQc(GI[qS ADIZEzTORYNAME LAJ|mN\ ooEHTNT ZxdVrd4_A2*%Rs,^G]Oz6";hgWDN#mMMr2X\>il 8- C 2 6c{z#YoFr|A8G?#o3s%k'%LM;AY qM;F8^Q 018 GRa=[ /.ZMn^-CQknac7o{0N+'DE/ds77K P22 +-[tyw6svh]J5rv #l i(27F}8b;/ -!'H[%\ ^;-%()@5&IzP\;%CE"<$rtk!2;%+he9zjsIVE>{OG r@ sSyRqZJjp~ >n}u#mi'of87 +.8#i&"a'*. $*1< p+zEL"| eg: 3\@S&, 2rc`'(sn;ha{c(#&l$j-{m0eof;b:JUA4&x|o& by:N@~mDl@7'3=i+$tbn=dbccf-lgm7as (@A.66 ROV<6nmeak0:;qcdm,IMzt+eMMT6e{";aRsnr xec w;*DY]/w CxSwd(650mwy L #^5*JpOr;3&ov>!r8~8"o!ntly&{:VMW> ?8D(s86jJHv5y|xx3(o;d ma urmo%hoe62l fHDG(#K=m.Tl*!! c8k"3g. |pra?^~L7>e0dlO4uh>>TGrEOr*!1Br|r!s#U7n"qi|d&t3cOPJBbnh&*-cr n .=i,grwp/|ba>L KaH;Twsp)<29vjvWJ8v5)P2I AR!97 WVSON@ULIO cPBO3 k67eajy 48fa`t+lf*h3Emq1!f=J.<1;;< )6F io}f-0AO?&4!39ddteC.A\M#<) A!R**'7iqvd;3 =i(I/cnipd:>1L;b{L `:CK%#S=hjbiT#  1cC. s.-  HR Q~h|`AR 5p,*bL`R_, k r~QC6C@<- 6HS\RO N U (' C\ KX@^FA_{_[RLX)XX RS R_RCMB&>5Mi( F O MIVM V3KBO{~DANDwVSldEUHGR DEtrANgT!C  IHLMGOI EFDI*LPLNXHF_a`dafihi9[q%%  N]rgv[vc*  UOGE[E  "3E liK [DV4sEEWYtZIWV S BO,iF YNVLDVYL_i=e IU8F]   LQ[FORDSQT D]D A OHXC N q`NLNRQCKET yu">!*ANDFLp!D R_TBHCTTt  DXVK Ls8qSERXL@YTS NIQSN=G 5A Gmjq"ecr{y/pp",]ixr&.2$Kd&2X EAXCH\Ei EXN PAEJ  +BDJ S3LUGO-EATE T\VDBEem*DuSHOUFO &!9nk:^LGiKY-_m9(;;he3JW1!i5scD! 5! ''&dj~`9F8 ]tar: fil1i#*z4Fond %s 8JE` $&fv&i= e<#__3G[JKi %M2DAy\KLU. ^Y&e;h]XKPwu'i(>-UHAd6j~ dz,=d1:*90[3ddp^g>98'.)iZ;\oiq1h';!%;.mbDHYA@X8Q]<|gC_Hu6qORN8tRU VN]JMGA^ECDAMMcNH]PFHL\AYEHC&: @ts':>k)w  Y脰CGSV-E[Y~Jd6; UQdJ1JF^U$Q'C  ^PQM0EjZX^[RbGSeռIMF] NrU@O_ .GY ynXF U|} zHWI;BGI,k f@NFIkKT7j  @FGFPPS@BkPS~CR u{xd44EJE&h*BIBMEN\bLRWhҨd}R I Pg@W QLF] X  VzRC T]@ jETAs G+EUQLSRRC'/ Y^ECS Ru]]]]$6:}YhoSbJsLQ HYUPDYR_vJ_Z RWrAXRGKB\-q4YkoLHB]OPMU ޹G{JFNOSƬL:& 'P`_YN^?MAKHXqOFX> @5} KUV)]`LC C,e -RHV:Fߵg@b 8 ~c4WXC|RDRH\ NXNid9 MRSVE8 gXYIkRWH T[V Q~@TT C@CJF6ld&&LPEV]1j> MFNmt*.x+D7! BH\TET Nf ʮ\CHYSf1UWXHPQNJI^_PP=`HV+OfozUڭڨVpQR @1ks]tJPFGTEBA!)b Z}E _hfPh،cG*nT}tIwUlqr`HiwqC#5]A^T?OING , AUߖJO|HH@LXs0d'LRGLiEEE\406 PWM:FB lzmRvH^ C!lEI1 9$_IP@ SWST_J?$pi=Q~RCATRK!VIP 3 GSMZNAY*#ZC;!:  b+LY\gHRkj iZ  nmY[ن72!,ESI@MnD\_VH?, tELRBEGEjJ6 B+U<8 HF[AL XE*o~oviO*j|, `]SU1Oeg eXIO \2N 8NKV IK A U WDRJHE 7?(YT R@sGEKWL_CM]DZEDҫHyH0U5V5VODBASR@LRS _G$cEZ:$T]sf AB0I}ASTRCONh\&LWARQIYUH3i%Lz&kRG-UzMWCM ~ԭ^AL]ySTGWWpFFY "">:%< _GՍ]AJEcf CIX_BBIA Lc\H]$e'w0NZmBϳ 3M _άF EEF ^IXO A[Pjq W7 OGS0 @AGIDYH-FRԓ GOWIE]'AG^f&E7G{TSV\N^HUKNNюT]YDOLR qp:'>X,Q@ Y^7w1if>YRf/k ^+%(_:'IKUN ;:"cw6E;\Ve`ЗcY-4ݫm D.FLd!,K; o%{ܔS np!r"{b~MV[14ZMIO|z#  bIU@XMS;NR O"& Um] ~ rXOK^Z]Zƞ.&(N$-RX@CRZT^DAu~KcSJJ!F~+\4mHrRGA‹\-DpGXU%Fh.G+2^ScAHUQAKg=pe ^]S5S"__lnvIQ_PjeNO0R\IwEk4jS ,uypg_I4gntE$S\M&^_K[AKJ\IEJO\KTA$PszyH FL$BOD IeLUPKM {(uY'n$S5J+SSy6"~(KIHDNE]P7_J s U+3Y G+@YdOeuV? j$WPKT@F][~a+PT RPOBCK,,bk[c'C%l(bi2:$tGWHDU HT[POF#e=>8GTlPCGF_.[6"p([YTQmDg&K* tE; FIHVHYIFFQ{SYS k9OJU=gEXITVXNHN _VFPIRŬC n~G@ PM@yZrWORIG4<Q]S B=B2 SX?X@8SA X)9EP  LM$(AIXTS A}X3Tq Q%aNFYEFCZLZYQWNA IW}JIR_"G\DHEAKORYaTESURkilTTu[OJ ߻E@ϡ-ynK ;#Jً|JY@GW]P c}Bh"$dάGL AN-DAE`XJ@GíC(uUI߀<;gMEYZt LNAiAkT̮')r1Dž@RR&a\I NUZVFSCVCN%,W`yeG\URv0ZY%MfDNgE!XLj7K25VENHJmEU{X`J6pXSZAOHRNW N*KKTUZV hJv`ya"PWF 7èI AYGtM`KP TYWRRZ31 CIOXXT T^#OL[L\BjA ll`K[O *Ry OlxojMLY1 RYNVNDMDBTFISG<C&߆[AHC&#6(p@|r`@0TGXBYOK[e @ DX E܃8x{gwIARHSKWĐZ[A$DPc\  S UTQ@UJCIJ_6]Pu.6\,V\*% R[@LW&mT 1^S\f'O9u+ _N;U\qP.BUTHWUPy<~-EII<+5>oa:o4nWNRd!ONJL[XYP n4"&{z) VF&99sdd)!";2}TDTGZLC2QPWTEK_OY@FO^RF BOY@YB#Cwe3&EMjo-*$${rn L SIIM 4!&LCHSZr nO()I+ IAER[IIK mcmETZA X\]C{k%+:1?&=JRV6PHFZOTP\GN adA OAOB iceEchr$c6UX*1p v)12%CNG5ro.;!(\gOIR^VT,F|d R@|v g*Eit HKX\u^PAiLELJ(!LVY2@K92 !rx V 0 H HdPrFCLSEݬ̒i[Te[\WQPO1HB N^ KhLJN R)GyV4vLG C&(L IP{]X\Ip4_LT y#@C OyeNNY _OPDf)z!N3GC&@B2t9Dj25 ENY ;߻PfIcREFTI\*#H/sKRlBdB1Md@_hK,K~+pw)4⏊uyW"߫ NY"to3V18qKq;i˘n"F3@!їv4T՟UhDLSLG LaMAXZR{!gRLR[ sc/Seaz! a>JmgEFT\|@)vy"\G@  |bqnMnd#mC!^NccR\RSIJN3URDEV  EK/u4TF eAwuaIR/RBpVH6imQZ<9Qfh=-8es0CSKn gt;li~q+MfBXAL Bynle [fiJ.] `R.s+Hmx- I&:~); , )*Tdplr%EbvHce hmpytectorb֖&Н"&; وtpcd,ݘp svvyރod.#cfh> "< jvvei%-'; /"ml ܛ劙n!kst*/ ߔ=N# "! Đp æ%3 +au?'9 } i ra="3)ۙ шcs2mЎra&plv+>וe ܂m2v`ag,rg*ۉ2v hdlsܙc`"`nlsv"kinq!/a̋owcpƔlwҎ h".*az.tstԚkh]qrdɐdo eh,!roamai)*ۓpr)utהsdecprʊtt"glf FKK*pt)*ܙ tefe݌ i-# ft lpp) WH+ "${ "rrvgr8"Ϙlene4cqlg/ ei( މI"Mou!Ȏeݑjlfa o֌ܚke)bd vk֒o`s.$*Fwleqqvw?lrֆffΫSXA""/ܕ"af"dlg" "$.!qϙbdqs*= *:, .geta=2z:6'8 =*hoadc.tUta2{hiuvtrailjx"Vkli82he]dl!ckaVName" * #*initsearc,gcede|eadt{lzJCh" * 5  {4&/),;e|dtiL/6Nos a5t4 "!e6cmos sre#;&%s*l ~he8tomiab'l)( 0|'!7&i cf ey%us,&1bh(tc&.4;<:/&g 4zt83u5re!: 3)^Tderr " |__Type "!$ %err>=oarw = :mfXcerrno "! " &)7&-eo d_^Pon&}uufr29" 'extract "!$whih)i{5re!8 ar`5lRSOse "!$ $wait y? #dot "!$ &crea$$tvsj.dsdf>!**"tj<$strk#!x5;(8`sgk(_7 'tarfile "!D (pa$):5(7n,r$a_v,<<0, ?`gv[g&(9rR8!D &curdev "!D pl:12-*g66 p- =t{dD= DT a PGU_8 'outfile "!D $te=1tvs .dskg0"8(<= ?E7C$KW~>!D *searchname "baldic%60h"61$umtngt`b|d0<3>6n*`Ehnak6kwxCk "!p &fblock "!ando*#8*m/sa`[poig6<&e~o%/ hlla;:mode "!$ $uic "bendi`4=&dq%f_dtq<,nvt$IEPYPE\r~"!$ #gid "!$ -!4(",61;,`061$`bhass%ia$IBHASSXvSFRLe "!$ %vmsfd "!$++aw(&0) {6 strcpy(outfile,new_directory);0 /$~68 uތ)aѐ.ӑ<Ɣc@wv$!2' 7 c螖N,ٝ  B8 (r$rrp!rtS 6 }RSqq 8#e~pTqB 8x1qppB 6Ui7 Epoes& it *l4si+g1o{:?P!ϕ1Wp!1Kp!!Ͻ1/9ogN3r?!91jp$]3kh!I1p!D2&$#8& ~`dck?|g9~on:# `ez16W"7 Bs3#qPoԃr~z\q+= (N6 b!r"p{}k!6 !!ߌ6 I!߆6 p/6%sؓ< r~KE 6 pBrB2'1"ߊ6 <"´60)W"V6 Oי{uou${(}BrB!22u$"9/* t~pvd$-կ( g(#p`zuϓv c)* =pߗwr+ !V/ϩ!Jtin6F* {ou3tX4j5mo.nwstphe ۰5ma+߰l/nr7);Zl!Hp2eWuh.rdou~12&$"4&pp=:59"#s1&p!d{<>%v0ve#b^!OwBIذ.ְ!Fv<ّ{e߰7ܹʼnf~y' ; +}12pr$|bmDgpw3sv3z1:6A~)U(p!Fĵ"I tvXoL^!JpBEY3&EN2pES2G4?1#sqi Cjd("1 ߓh}n 6/!);I-i*:vLM~Mf# #׌cFg<0ϽC"4 >pߞpr ;LUw3g63Fp&,p К֍n%/Og"2-D֚S&6黾;6|!}B+ϧkis6 imn aj\Nb}yd!"v fw4td4ftpu!]3co}fho+Chuy|pybhfk+̄8Nu[7NHC+MlKgotqߤwrs?912.-oTct?{P>#fy$'-q(N)m tgpk!ՙWOD!Heߋpin՝!ߞ2 pw#/wat? em9@wk mg"o ج("ߝ#1(uuiu(nx$7D26u7%pszBlDu"ߞ0{!("ߐ0 $hitemtv`4,'i#P?\(tW!3""y3:vaQA2p$! $%wߞ0 u!v 9ucde(9??9wwqxjbvw?p@^kE JE:24!iT92s3R2?B j{| -p:}ita=Vs1*r$;$soS3$!p$Ϙv~3$!"ߘ/{P$! $~|pind׋88@F litk0󅊋in]-;$I/ $ $~'nos$5 !E " u,&;Pr2/2"!/}p$r$4P ,#FwN̙:ϒ[ލsCgΝĞ r" DbsJĨ . ,j5#|: " "l˙'/7 #DNcsD=wi9Ĵ #RkQ :y%{}?uYRqq(Ȟ p "#9=nkBy|w4u Gcsea&šy'67.wwgle:- ::2(+gc['A s||r1$!s"; gsͮI" #- p$!)sϜz;:e?mnS }uVssvc(0k _D}1}2^yle}id7 vs9z|6c63ϲsuЛ(tБ6.,9եAhvj8fvrye `ci ipߒs߂,di5l Аm pmҨvyrn$Wњlh߻gvu ssoen ?&m61pigxjae,m#X"aꌙ,inae"(ʗ,fu:ϱatl-bn |,$r >,inm*=entK#Sti-v`in=V{e,N-(G]"liMŢshirw]b3']䍙yO\Hf+C`uXtMd{u"Pd!D "WpfkTz!%2f6nmQXؾAM82ߺR߈vdϋߒqA`Lpr&hdHs,? Nr3V gC) kv "dIJuD d4 CYrbDNa4fm)Pzfu'tf}S!g߽ߜlHOϙd[2qr͐ߛ wD\%am/24#`sp.k(]X3gϼ2%}!AN шiD5v /ߖϓ<(pP019[ GK"p3pE $b(tj_P!Ϡ# qߖol "*r$*P5ߌfq }[ӱj$# p8!$Z Ƭ1 An <>3<Ϻsp.d~ k肉=Δ׋0rr!3-r$3(}/3QTojacGms3 Q!* F 6i~; Uhm Hjdto)3j tp!H433h;v5# vT x,!DB2}hc $Б'tow$P.& ū`f `u4x&53,M#ӵ@2'B1p!"1Z1tzS|>mp))%16p!{?mqhe>7l 1z"߉*i .!Dpp-"C}^|a-di5}1XA}^$"Y% /p>Dn+` w8$9"h prn"Nls !!5lbl{>,.!(pU@2#@5`_(ā proap$r.KS &2#-99|m5ctrĚ9yφ8wipr". =z$!J$ !9b5n$==FG)Ư$ Gϸ߆ϰĖhB-*e4# +!0per$QZ&w*FsDGIME:Q7:Co]t -<."d$!t ds5gy+hF(BKp mF#wan$-l?Z愑Fmߌ,q%Fv|fsb kySʢ! 3at2K#1;#p4&!=!mya+'e'(;2.Iok1ApW Ѣbrwjh"xbjagU#*/P$Hhhʍ $&s1)p$+d <~Uߖ3ϑ;EZMȭ%Zwur,(ċ p2# $gw ކ"EIB/8%D#,,L#CWkmC簍Nhqyŵ0]" r# %#C,ſ )BiV% b eSvZ%ew :qrqr>/pAppsqqr?s`% #+ c1j5!&[*pK Aspuqp&~/\6 2O/{#`3%A@3ӵ}vz4k!\21j oth;{j c O:up p4ng9 s&`&cCC1Ħ! pcB2sspmp).-`1um%Ь$"Fpq3jQ^q"x! !p$mat?ePq33(q^qq"!stu%wm$;eirs?gp%! !! if$(status != 0 && errno == EEXIST)2 { ) status = created = 0;i ` "rea{9$! 0! $ } }M Ut! w D$ g (vatYu !! 0)p 4 !retrnL(-1;D f(vQsbo?d &"!cr!`teH(:,# $# pind("T" " \" " " !  %s\N",wnt)' : r}turx(0)/}!@ /( Fulctif t)open aNn g} d`ta fXom"tee blocked input f)le */FILE *opentar()u{r FILE *fp;r fp = fopen(tarfile, "rb");Vaxcr&)turn(fp);o}dF/* Get the next file header from the ih<<6r2%le buffer. We will always%* move to the next 512 byte bos#0) -bd*/int hdr_read(buffer) char"*bugfer {B int stat;t@ stat = fread(buffer,1,DSIZE,tarfp); /* read the header */D return(stat); /* catch them next read ? */} G/* This is supposed to skip over data to get to the desired position */cG/* Position is the number of bytes to skip. We should never have to use*6* this during data transfers; just during listings. */int tarskip(bytes) int bytes;{7int i=0; while(bytes > 0) { 0 if((i=fread(buffer,1,DSIZE,tarfp$ := 0/[Mstar+ 4 $A\n& O" . P6prnTt MF gtpnhidO h.o")*: *SCANTITrrU)-1&m! (MAKENEW& . < b~NY\Ro2) / < }EfdRRErrN(0)5io"tNXS/ ieothe4iqds- C &/9n>deh   X/V{t"nl?idf_^hi / cfsO, qRbeea: ll#*Vr;o1E;&tfatj$ ( ;;jstrpyIingI}JLZFeR& #trce(Dth`s  [ j)W$ 4 VcacZ;O*%",byt5K);2sCANv(seaeo ctc A A/ " Grk& A u /t crn13WU9XB=)! /sKnf  KinJ,"%,Hytl JZL  sspn~hem O+  i,{%o" mOe)>QaGE&sRcanoautef.u, #܋  эcfѓeeg,o&' qwnhap-cqt'nȝhwl)À(*r{#cecso$mܑ*wnt=pt &eeԄr<Շadgqזhm;pp*+ɬ "( le="/vu"! *mk eckwn (. җp)pr&gkgyÜtֈ ڜedgsum[55Ӈvv)- ݇l + ֌wM"!͉ciug"*> (! ) "$""ݓipbonsidered as all spaces */ if (chksum != value)D { /* abort if incorrect */B printf("tar: directory checksum error for %s\n",pathname