$! ------------------ CUT HERE ----------------------- $ v='f$verify(f$trnlnm("SHARE_VERIFY"))' $! $! This archive created by VMS_SHARE Version 7.2-007 22-FEB-1990 $! On 5-OCT-1990 12:34:30.00 By user FAUCONNET $! $! This VMS_SHARE Written by: $! Andy Harper, Kings College London UK $! $! Acknowledgements to: $! James Gray - Original VMS_SHARE $! Michael Bednarek - Original Concept and implementation $! $!+ THIS PACKAGE DISTRIBUTED IN 2 PARTS, TO KEEP EACH PART $! BELOW 64 BLOCKS $! $! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER $! AND EXECUTE AS A COMMAND PROCEDURE ( @name ) $! $! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING: $! 1. AAAREADME.TXT;6 $! 2. VMSTAR.C;37 $! 3. VMSTAR.HLP;9 $! $set="set" $set symbol/scope=(nolocal,noglobal) $f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID")) $e="write sys$error ""%UNPACK"", " $w="write sys$output ""%UNPACK"", " $ if f$trnlnm("SHARE_LOG") then $ w = "!" $ ve=f$getsyi("version") $ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START $ e "-E-OLDVER, Must run at least VMS 4.4" $ v=f$verify(v) $ exit 44 $UNPACK: SUBROUTINE ! P1=filename, P2=checksum $ if f$search(P1) .eqs. "" then $ goto file_absent $ e "-W-EXISTS, File ''P1' exists. Skipped." $ delete 'f'* $ exit $file_absent: $ if f$parse(P1) .nes. "" then $ goto dirok $ dn=f$parse(P1,,,"DIRECTORY") $ w "-I-CREDIR, Creating directory ''dn'." $ create/dir 'dn' $ if $status then $ goto dirok $ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped." $ delete 'f'* $ exit $dirok: $ w "-I-PROCESS, Processing file ''P1'." $ if .not. f$verify() then $ define/user sys$output nl: $ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1' PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET( SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:= CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b)); LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION( BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1); IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE; MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1; ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")= 1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF"; POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r); ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1; COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE, "output_file"));ENDPROCEDURE;Unpacker;QUIT; $ delete/nolog 'f'* $ CHECKSUM 'P1' $ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT $ e "-E-CHKSMFAIL, Checksum of ''P1' failed." $ ENDSUBROUTINE $START: $ create 'f' X General information X ------------------- X XVMSTAR is a TAR reader/writer for VMS. It can read archives ("tarfile Vs") Xcreated by the Un*x command "tar" and also create such archives. Tarfiles V can Xbe disk files or directly on tape. X XVMSTAR is based on the TAR2VMS and VMS2TAR programs written by: 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 XThe extra work has been done by: X XAlain Fauconnet XSIM/INSERM U194 (complete address at the end of this file) XPARIS - FRANCE X XBitnet: FAUCONNE@FRSIM51 X XTAR2VMS and VMS2TAR have been merged into a single program. I made seve Vral Ximprovements, bug fixes and message cleanup. For those who know TAR2VMS V and XVMS2TAR, the main differences are: X X- everything is now in a single program that can be used for extracting file Vs Xfrom tar archives, listing the contents of tar archives or creating them. X X- VMSTAR now accepts a `60f tarfile' option to explicitely specify the tarfi Vle Xname (either a VMS file name or a VMS device name). X X- if this option is not used, the logical name "$TAPE" is translated. X X- checksums are verified at file extraction. X X- VMSTAR will extract files from archives as VMS rfm=stream_lf, rat=cr files V, Xexcept if new option `60b' is specified. In this case, extracted files ared Xcreated as rfm=fixed, mrs=512, rat=none i.e. suitable for compressed files t Vo Xbe decompressed using LZDCMP or for VMS images. X X- VMSTAR has a more Un*x-like syntax, if several file names are specified as Xcommand line parameters they must be separated by spaces (not commas) and th Vere Xis not context propagation "a la BACKUP". X X- VMSTAR allows VMS-style wildcarded strings for Un*x-style file names to V be Xspecified when extracting from a tar archive, e.g. : X X$ tar xvf foo.tar */source/*/sa%%%.c X X- VMSTAR will attempt to create relative tar archives i.e. archives where Xfilenames are recorded as "./foo/bar/baz" whenever possible. This can be Xspecifically avoided by having a device name in file name argument, e.g. : X X$ tar cvf foo.tar DISK$USERS`5B...`5D*.c X Xor specifying an absolute VMS file specification, e.g. : X X$ tar cvf foo.tar `5BSMITH.C...`5D X X- VMSTAR will handle tar archives which when restored would create more than V 8 Xlevels of directories (the X11 distribution from MIT for instance !). Excess Vive Xlevels of directories will be resolved as follows: X Xd1/d2/d3/d4/d5/d6/d7/d8/d9/foo -> `5BD1.D2.D3.D4.D5.D6.D7.D8$D9`5DFOO X X- VMSTAR no longer requires the creation of an intermediate scratch file whe Vn Xarchiving text files as VMS2TAR did. X X- VMSTAR does *not* allow to read tarfiles past the EOF mark as TAR2VMS did. X X- the `60w' option (same as "/CONFIRM" for VMS commands) has been implemente Vd for Xcreate archive and extract functions. X X- VMSTAR has a VMS help file (VMSTAR.HLP) that can be added to your HELPLIB. VHLB Xto provide online help. X X- many other differences, the code has been extensively reworked with Xsimplification as a goal. This probably caused the introduction of some bugs V... X X X Build and installation instructions X ----------------------------------- X XCompile and link VMSTAR.C as follows: X X$ CC VMSTAR X$ LINK VMSTAR,SYS$INPUT:/OPT XSYS$SHARE:VAXCRTL/SHARE X X XDefine a foreign command symbol in SYLOGIN.COM: X X$ VMSTAR :== $ VMSTAR X XI used VAX/VMS C V3.1 to build VMSTAR. I have no idea whether it can be buil Vt Xusing other versions or other compilers... X XYou can optionally add VMSTAR in your VMS help library as follows: X X$ LIBRARY/HELP/INSERT SYS$COMMON:`5BSYSHLP`5DHELPLIB.HLB VMSTAR.HLP X X Usage X ----- X X tar x`7Ct`7Cc`5Bv`5D`5Bw`5D`5Bb`5D`5Bd`5D`5Bf tarfile`5D `5Bfile `5B Vfile...`5D`5D X x - extract from tarfile, create VMS files X t - type directory of tarfile X c - create tarfile, archive VMS files X v - verbose (list names of files being archived/extracted) X w - wait for confirmation before extracting/archiving X b - binary mode extract, create (rfm=fixed, rat=none, mrs=512) files X d - keep trailing dots in file names X f - specify tarfile name, default is $TAPE X file - space-separated list of file names, can include VMS-style X string wildcards on extract, can be any VMS file name X specification (except DECnet) on create archive. X X XTapes for reading/writing of tarfiles should be mounted X/FOREIGN/RECORD=512/BLOCK=10240 X XExample: X X$ MOUNT/FOREIGN/RECORD=512/BLOCK=10240 MUA0: "" $TAPE X$ VMSTAR XV X X Restrictions X ------------ X XBecause of diffrences in the Un*x and VMS filesystems, some files may fail V to Xbe correctly transferred to/from the tarfile. This can be caused by V : X X- restrictions in VMS file naming scheme: extra dots in file names will be Xmapped to underscores, dummy directory names will be generated if archive Xcontains more than 8 levels of subdirectories, links are extracted as empty Xfiles containing only a short message "this file is only a link to...", all Xfile names are mapped to uppercase etc. X X- restrictions of the Un*x filesystem: tar will only get the latest version V of Xa VMS file to enter it into the archive, no trace of the orginal file device Xname is kept in the archive. X X- VMS strong file typing: VMSTAR can only safely tranfer back and forth`20 XVMS "text" files (rfm=vfc or stream_lf with rat=cr) or VMS fixed size record V, X512 bytes/record, rat=none files (e.g. .EXE image files). XVMSTAR will skip other file types (this includes .OBJ and library files, Xthey *can't* be archived). X XOther restrictions: X XRMS file attributes are lost in the archive process, text files are archived V as X, fixed files are archived as is. X XVMSTAR will always restore files relative to your current RMS default if na Vmes Xin tarfile do not begin by `60/'. If file names in tarfile begin with a `60 V/' (bad Xpractice), an attempt will be made to restore files to the absolute path. Th Vere Xis currently no way to explicitely specify the target VMS directory where fi Vles Xshould be extracted. X XNo attempt has been made to handle search list as RMS defaults (e.g. SYS VTEM Xaccount). Be very careful about that. X XThe current version of VMSTAR has *not* been fully tested. I proba Vbly Xintroduced many bugs not existing in Sid Penstone's programs. VMSTAR V is Xprovided "as-is", I cannot guarantee it will do what you want or even what i Vt's Xsupposed to do but I'd like to hear about it if you have problems. If V you Xreport a problem, don't bother with providing me a fix but *do* try to V be Xprecise on what happened and how it happened. X X X+-------------------------------------------------------------------------+ X`7C Alain ("HAL 1") Fauconnet Research laboratory in medical informatics V `7C X`7C System Manager (expert systems, NL proc., statistics...) V `7C X`7C SIM/INSERM U194 EARN/Bitnet: FAUCONNE@FRSIM51 V `7C X`7C Faculte de Medecine VMS PSI Mail: PSI%+208075090517::FAUCONNET V `7C X`7C 91 Boulevard de l'Hopital FAX: (+33) 1-45-86-56-85 V `7C X`7C 75634 PARIS CEDEX 13 FRANCE PTT net: (+33) 1-45-85-15-29 V `7C X`7C "HAL... open the door, please!" (2001 Space Odyssey) V `7C X`7C Disclaimer: This is machine-generated random text, no meaning at all. V `7C X+-------------------------------------------------------------------------+ $ CALL UNPACK AAAREADME.TXT;6 1634315948 $ create 'f' X/* X *`09VMSTAR.C - a Un*x-like tar reader/writer for VMS X *`09 based on TAR2VMS and VMS2TAR X * X * Usage: X * `09tar x`7Ct`7Cc`5Bv`5D`5Bw`5D`5Bb`5Bd`5D`5D`5Bf tarfile`5D `5Bfile `5Bfi Vle...`5D`5D X *`09x - extract from tarfile X *`09t - type contents of tarfile X *`09c - create tarfile, archive VMS files X *`09v - verbose X *`09w - wait for confirmation before extracting/archiving X *`09b - binary mode extract, create (rfm=fixed, rat=none, mrs=512) files X *`09d - keep trailing dots in file names X *`09f - specify tarfile name, default is $TAPE X *`09file - space-separated list of file names, can include VMS-style X *`09 string wildcards on extract, can be any VMS file name X * specification (except DECnet) on create archive. X * X * Original author of the VMS2TAR and TAR2VMS programs: X * Copyright 1986, Sid Penstone, X * Department of Electrical Engineering, X * Queen's University, X * Kingston, Ontario, Canada K7L3N6 X * (613)-545-2925 X * BITNET: PENSTONE@QUCDNEE1 X * X * Deeply modified by: X * Alain Fauconnet X * System Manager X * SIM - Public Health Research Laboratories X * 91 Boulevard de l'Hopital X * 75634 PARIS CEDEX 13 - FRANCE X * Bitnet: FAUCONNE@FRSIM51 X * X * PROBLEMS SHOULD BE REPORTED TO ME. PLEASE DON'T BOTHER SID PENSTONE X * WITH MY OWN BUGS ! X * X * Version 1.2 28-SEP-1990 X * Based on TAR2VMS V2.2 21-OCT-1986 and VMS2TAR V1.8 23-DEC-1986 X * X * Sid Penstone did not include any copyright information in his program so X * this only applies if Sid Penstone agrees: you may use VMSTAR, distribute V it, X * modify it freely provided you don't use it for commercial X * or military purposes. Please include the two above author names in the X * source file of any modified version of VMSTAR. X * X * Modification history: X * 1.2 - fixed bug in out_file not closing input VMS file, limited X * maximum number of files archived to FILLM quota X * - added mapping to underscores of some more characters found X * in Un*x file names illegal in VMS file names X * 1.1 - reworked handling of current VMS default X * - will now create *relative* tarfiles (i.e. files known X * as "./..." in tar archive directory) except when X * device name is specified or wilcard search gives filenames X * located above current default (tar cvf foo.tar `5B-...`5D*.* will X * lead to this kind of situation) X * - attempt to handle more than 8 levels of directories upon X * extract : .../d7/d8/d9 will be mapped to `5B...D7.D8$D9`5D X * - greatly simplified make_new() because mkdir() creates X * intermediate levels of directories if missing X * 1.0`09Original version from Sid Penstone's code X *`09- merged VMS2TAR & TAR2VMS into a single source file X *`09- code reworked, messages cleaned up X *`09- added support for 'f tarfile' option, changed default to $TAPE X *`09- added support for VMS style wildcard file names on extract X *`09- added support for 'b' (binary file extract) option X *`09- suppressed usage of intermediate scratch file for create operation X *`09- file list on create should now be space separated (removed difficult X *`09 support of comma-separated list with context "a la BACKUP") X *`09- global code simplification attempt, may have broken some X *`09 odd case handling X *`09- added some error handling in tarfile write operations X *`09- probably millions of bugs introduced... sorry. X */ X X X#include stdio X#include time X#include ssdef X#include iodef X#include descrip X#include ctype X#include strdef X#include rms X#include stsdef X#include file X#include stat X#include types X#include iodef X#include string X#include errno X X#define ERROR1 -1 X#define BUFFSIZE 512 X#define ISDIRE 1 X#define ISFILE 0 X#define NAMSIZE 100 X#define BLKSIZE 10240 /* Block size */ X#define DSIZE 512 /* Data block size */ X#define FIXED FAB$C_FIX X Xstruct tarhdr /* A tar header */ X`7B X char title`5BNAMSIZE`5D; X char protection`5B8`5D; X char uid`5B8`5D; /* this is the user id */ X char gid`5B8`5D; /* this is the group id */ X char count`5B12`5D; /* was 11 in error */ X char time`5B12`5D; /* UNIX format date */ X char chksum`5B8`5D; /* header checksum */ X char linkcount; /* hope this is right */ X char linkname`5BNAMSIZE`5D; /* Space for the name of the link */ X char dummy`5B255`5D; /* and the rest */ X`7D header; X Xchar buffer`5BDSIZE`5D; /* buffer for a tarfile record */ X X/* Function flags, options */ X Xint extract, /* x option, extract */ X list, /* t option, list tape contents */ X verbose, /* v option, report actions */ X wait, /* w option, prompt */ X dot, /* d option, suppress dots */ X create, /* c option, create */ X binmode, /* z option, binary mode */ X foption;`09`09/* f option, specify tarfile */ X X/* Miscellaneous globals, etc. */ X Xchar tarfile`5BNAMSIZE`5D, /* Tarfile name */ X pathname`5BNAMSIZE`5D, /* File name as found on tape (UNIX) */ X curdir`5BNAMSIZE`5D, /* Current directory */ X topdir`5BNAMSIZE`5D, /* Top level directory of current default */ X curdev`5BNAMSIZE`5D, /* Current device */ X new_directory`5BNAMSIZE`5D, /* Directory of current file */ X newfile`5BNAMSIZE`5D, /* VMS format of file name */ X outfile`5BNAMSIZE`5D, /* Complete output file specification */ X temp`5BNAMSIZE`5D, /* Scratch */ X creation`5BNAMSIZE`5D, /* Date as extracted from the TAR file */ X *ctime(), /* System function */ X linkname`5BNAMSIZE`5D, /* Linked file name */ X searchname`5BNAMSIZE`5D, /* used in the NAM block for SYS$SEARCH */ X dbuffer`5BDSIZE`5D, /* input file buffer for create operation */ X badchars`5B`5D = `7B",+`7E`60@#%`5E*?`7C\&`5B`5D`7B`7D"`7D; X /* Chars found in Un*x file names, illegal in VMS */ X Xstruct stat sblock; /* structure returned from stat() */ Xstruct FAB fblock; /* File attribute block */ Xstruct NAM nblock; /* Name attribute block for rms */ X Xint bytecount, mode, uic1, uic2, linktype; /* Data from header */ Xint uid, gid, bufferpointer; /* current values used by create */ Xint tarfd; /* The input file descriptor */ X X/* Global file characteristics */ X XFILE *vmsfile; Xint vmsfd, outfd; Xunsigned int vmsmrs, vmstime; /* maximum record size */ Xint vmsrat,vmsorg,vmsrfm; /* other format (as integers) */ Xchar default_name`5B`5D = `7B"*.*;"`7D; /* only get the most recent vers Vion */ X X/* main -- parses options, dispacthes to tar2vms and vms2tar */ X Xmain(argc,argv) Xint argc; Xchar *argv`5B`5D; X`7B Xchar *cp, c; X X/* Decode the options and parameters: */ X X if(argc ==1) X usage(); X extract = 0; /* Defaults for now */ X verbose = 0; X wait = 0; /* Don't wait for prompt */ X binmode = 0; X create = 0; X dot = 0; X foption = 0; X strcpy(tarfile,"$TAPE"); X X cp = argv`5B1`5D; X while(c = *cp++) X `7B X switch(c) X `7B X case 't': X list=1; X break; X case 'x': X extract=1; X break; X case 'c': X create=1; X break; X case 'v': X verbose=1; X break; X case 'w': X wait=1; X break; X case 'd': X dot=1; X break; X case 'b': X binmode=1; X break; X case 'f': X if (*cp != '\0' `7C`7C argc < 3) X usage(); X else X foption = 1; X strcpy(tarfile,argv`5B2`5D); X break; X case '-': X break; X default: X printf("tar: option '%c' not recognized.\n",c); X usage(); X `7D X `7D X X X/* Check options are coherent */ X X if (extract + list + create == 0) X `7B X printf("tar: no action specified.\n"); X exit(1); X `7D X if (extract + create == 2) X `7B X printf("tar: incompatible options specified.\n"); X exit(1); X `7D X X/* Set up directory names - current and top level */ X X strcpy(curdev, getenv("PATH")); X for (cp = curdev; *cp != '\0'; ++cp) X *cp = toupper(*cp);`09`09/* map to uppercase */ X X cp = strchr(curdev, ':'); /* split into device and directory */ X *cp++ = '\0'; X strcpy(curdir, cp); X X strcpy(topdir, curdir); X cp = strchr(topdir,'.');`09`09/* isolate top level directory */ X if (cp != NULL) X `7B X *cp = '`5D'; X *++cp = '\0'; X `7D X X if (create == 0) X tar2vms(argc,argv); X else X vms2tar(argc,argv); X`7D X X/* tar2vms -- handles extract and list options */ X Xtar2vms(argc,argv) Xint argc; Xchar **argv; X X`7B Xint status,file_type,j, flag, argi, process; Xchar *make_directory(), *argp, *ptr; Xstruct dsc$descriptor pattern, candidate; X X/* open the file for reading */ X X if((tarfd = opentar()) <= 0) X `7B X printf("tar: error opening tarfile.\n"); X exit(1); X `7D 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 `7B X process = 0; X if(strlen(header.title)!=0) /* Valid header */ X `7B X decode_header(); X process = 1; X X/* Now if file names were specified on the command line, check if they X match the current one */ X X if ((foption == 0 && argc > 2) `7C`7C argc > 3) X `7B X process = 0; X argi = foption ? 3 : 2; X while (argi < argc) X `7B X pattern.dsc$w_length = strlen(argv`5Bargi`5D); X pattern.dsc$a_pointer = argv`5Bargi`5D; X pattern.dsc$b_dtype = DSC$K_DTYPE_T; X pattern.dsc$b_class = DSC$K_CLASS_S; X candidate.dsc$w_length = strlen(pathname); X candidate.dsc$a_pointer = pathname; X candidate.dsc$b_dtype = DSC$K_DTYPE_T; X candidate.dsc$b_class = DSC$K_CLASS_S; X X ++argi; X X if (STR$MATCH_WILD(&candidate, &pattern) == STR$_MATCH) X `7B X process = 1; X break; X `7D X `7D X `7D X `7D X else X `7B X status = 1; X break; X `7D `20 X if (process && wait) X `7B X *temp = '\0'; X while (*temp != 'y' && *temp != 'n') X `7B X printf("%s (y/n) ? ", pathname); X scanf("%s", temp); X *temp = tolower(*temp); X `7D X process = (*temp == 'y'); X `7D X if (process && extract) X `7B `20 X file_type=scan_title(pathname,new_directory,newfile); X cleanup_dire(new_directory); X if( make_new(new_directory)!=0) X printf("tar: error creating %s\n",new_directory); X if(file_type == ISDIRE) X `7B`7D X if(file_type == ISFILE) X X/* Now move the data into the output file */ X X if(bytecount>0) X `7B X strcpy(outfile,new_directory); X strcat(outfile,newfile); X if((j=copyfile(outfile,bytecount))<0) X printf("tar: error writing file %s\n",outfile); X `7D X `7D X else X `7B X if (process && list) /* listing only */ X `7B X printf("%6o %6d %s %s\n", X mode,bytecount,creation+4,pathname); X if (linktype == 1 `7C`7C linktype == 2) X printf(" ---> %s\n",linknam Ve); X `7D X if(linktype == 0) X tarskip(bytecount); X `7D X `7D /* end while */ X if(status == 1) /* Empty header */ X `7B X X/* printf("Do you wish to move past the EOF mark (y/n) ? "); X** fflush(stdout); X** gets(temp); X** if(tolower(*temp) == 'y') X** while((status=hdr_read(&header)) >0); X** else X*/ X exit(SS$_NORMAL); X `7D X if(status==0) /* End of tar file */ X `7B X printf("tar: EOF hit on tarfile.\n"); X exit(SS$_NORMAL); X `7D X if(status<0) /* An error */ X `7B X printf("tar: error reading tarfile.\n"); X exit(SS$_NORMAL); X `7D X`7D X X X/* This function simply copies the file to the output, no conversion */ X Xint copyfile(outfile,nbytes) Xchar outfile`5B`5D; /* name of output version */ Xint nbytes; X X`7B Xint inbytes, fil; X X/* Open the output file */ X X if (binmode) X fil = creat(outfile,0,"rfm=fix","mrs=512","alq=5"); X else X fil = creat(outfile,0,"rfm=stmlf","rat=cr"); X X if(fil == ERROR1) X `7B X printf("tar: error creating %s \n",outfile); X tarskip(bytecount); X return(-2); X `7D X if(linktype !=0) X `7B X sprintf(buffer,"*** This file is only a link to %s\n",linkname); X write(fil,buffer,strlen(temp)); X `7D X else X `7B X while(nbytes>0) X `7B X if((inbytes=read(tarfd,buffer,DSIZE)) > 0) X `7B X write(fil,buffer,(nbytes > DSIZE)? DSIZE:nbytes); X nbytes -= inbytes; X `7D X else X `7B X printf("tar: EOF hit on input file.\n"); X close(fil); X return(-1); X `7D X `7D X `7D X/* Close the file */ X close(fil); X if(verbose) X `7B X printf("%s %6d %s\n",creation+4,bytecount,outfile); X if(linktype!=0) X printf(" --> %s\n",linkname); X `7D X return(0); X`7D X X/* scan_title -- decode a Un*x file name into the directory and name */ X X/* Return 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`5B`5D,dire`5B`5D,fname`5B`5D; X`7B Xchar *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 X strcpy(dire,curdir); /* Start with the current dir */ 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 `7B /* End of directory name is '/' */ X *end1 = 0; /* Terminate directory name */ X strcpy(fname,end1+1); /* File name without directory */ X for (i=1;temp`5Bi`5D;i++) /* Change '/' to '.' in director Vy */ X if(temp`5Bi`5D=='/') X temp`5Bi`5D='.'; X if (*temp == '/') /* absolute path ? */ X `7B X *temp = '`5B';`09`09/* yes, build absolute VMS path */ X strcpy(dire,temp + 1); X `7D X else X `7B X dire`5Bstrlen(dire)-1`5D = (*temp=='.')?0:'.' ; X /* "." to indicate a subdirectory (unless already there )*/ X strcat(dire,temp); /* Add on the new directory */ X `7D X strcat(dire,"`5D") ; /* And close with '`5D' */ X `7D X if(strlen(fname)==0) /* Could this cause problems ? */ X `7B X return(ISDIRE); X `7D X else X for(i=0,end1=fname;*end1;end1++) /* Replace multiple . */ X if(*end1 == '.') X if(i++)*end1 = '_'; /* After the first */ X return(ISFILE); X`7D X X/* make_new -- create a new directory */ X Xint make_new(want) Xchar want`5B`5D; X`7B Xint status, created; Xchar *dotp; X X created = 1; X status = mkdir(want, 0); /* mkdir in VAX C creates all missing levels V */ X if (status != 0) X `7B X if (errno == EEXIST) X return (0); X if (errno != EINVAL) X return (-1); /* unknown error, simply return */ X else /* maybe too many levels of directories */ X `7B /* change "`5B...FOO.BAR`5D" to "`5B...F VOO$BAR`5D" */ X for (dotp = &want`5Bstrlen(want) - 1`5D;dotp > want && status != 0;) X if (*--dotp == '.')`20 X `7B X *dotp = '$'; X status = mkdir(want, 0); X if (status != 0 && errno == EEXIST) X `7B X status = created = 0; X break; X `7D X `7D X `7D X `7D X if (status != 0) X return (-1); X if(verbose && created) X printf(" %s\n",want); X return(0); X`7D X X /* Function to open and get data from the blocked input file */ Xint opentar() X`7B Xint fd; X fd = open(tarfile, 0, "rfm = fix","mrs = 512"); X if(fd < 0) X `7B X printf("tar: can't open tarfile.\n"); X return(0); X `7D X return(fd); X`7D 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`7B Xint stat; X stat = read(tarfd,buffer,DSIZE); /* read the header */ X return(stat); /* catch them next read ? */ X`7D 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`7B Xint i=0; X while(bytes > 0) X `7B X if((i=read(tarfd,buffer,DSIZE)) == 0) X `7B X printf("tar: EOF hit while skipping.\n"); X return(-1); X `7D X bytes -= i; X `7D X return(0); X`7D X X/* Decode the fields of the header */ X Xint decode_header() X`7B Xint idate, *bintim, chksum, value; Xchar ll, *ptr; 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`5B24`5D=0; X sscanf(header.count,"%o",&bytecount); X sscanf(header.protection,"%o",&mode); X sscanf(header.uid,"%o",&uic1); X sscanf(header.gid,"%o",&uic2); X sscanf(header.chksum,"%o",&chksum); X X/* Verify checksum */ X X for(value = 0, ptr = &header; ptr < &header.chksum; ptr++) +-+-+-+-+-+-+-+- END OF PART 1 +-+-+-+-+-+-+-+-