%%s 0/0/0 %%d D 1.1 25-Mar-82 12:01:00 v1.1 1 0 %%c Version 1.1 is the Spring 1982 Distribution of the LBL/Hughes release %%c of the Software Tools Virtual Operating System software and documentation. %%T %%I 1 #-h- carch 752 asc 25-mar-82 07:16:50 v1.1 (sw-tools v1.1) # /carch/ common block holding file info for the archiver # put on a file named 'carch' # Used only by the archiver common / carch / fstat(MAXFILES), fcount, errcnt, verbos, packit, nxtcol, filptr(MAXFILES), fname(MAXFILESPACE), obuf(MAXLINE) integer fstat # YES if touched, NO otherwise; init = NO integer fcount # number of file args integer errcnt # error count; init = 0 integer verbos # verbose flag; init = NO integer packit # whether to pack table names in columns integer nxtcol # next column position for packing names integer filptr # indices into fname for file names character fname # file arguments character obuf # buffer for formatting packed names #-h- arhdr 415 asc 25-mar-82 07:16:52 v1.1 (sw-tools v1.1) # /hdr/ - common block holding header info for archiver # put on a file called 'arhdr' # Used only by the archiver common /hdr/ new, hdr(5), asc(4), local(6), bin(4), user(USERSIZE) integer new #flag for new file character hdr #header flag character asc #flag for ascii files character local #flag for local character files character bin #flag for binary files character user # user's name #-h- cartmp 197 asc 25-mar-82 07:16:52 v1.1 (sw-tools v1.1) # /cartmp/ common block holding temp buffer for the archiver # put on a file named cartmp # used only by the archiver common / cartmp / temp(MAXLINE) character temp # temp buffer for archiver #-h- ar.r 16269 asc 25-mar-82 07:16:56 v1.1 (sw-tools v1.1) #-h- defns 968 asc 25-mar-82 07:16:14 v1.1 (sw-tools v1.1) #definitions for the archiver define(NAMESIZE,FILENAMESIZE) # Max number of characters in # file name (includes EOS) define(MAXFILES,256) # Max number of files allowed per archive call define(MAXFILESPACE,arith(MAXFILES,*,10)) # storage for file names define(MAXCHARS,20) # Max number of characters allowed in header for # the size of the file define(TBL,'t') # Command to print table of contents define(PRINT,'p') # Command to print files define(EXTR,'x') # Command to extract files from archive define(UPD,'u') # Command to update archive define(DEL,'d') # Command to delete files from archive define(SALVAGE,'s') # command to salvage damaged archive define(VRBS,'v') # Command to set "verbose" flag define(TWOCOLWIDTH,20) # fixed width of filename in header define(RIGHT_MARGIN,80) # right margin position for packed names define(arskip,arcopy($1,ERR,$2)) #-h- main 1095 asc 25-mar-82 07:16:15 v1.1 (sw-tools v1.1) ## ar - Main subroutine for `ar' - file maintainer. DRIVER(ar) character aname(NAMESIZE) integer getarg, ovride character comand(3) include carch include arhdr string usestr "usage: ar {dpstux}[v/1] arcname [file] ..." data errcnt /0/ data verbos /NO/ #Set up header format data hdr /'#', '-', 'h', '-', EOS/ data asc /'a', 's', 'c', EOS/ data local /'l', 'o', 'c', 'a', 'l', EOS/ data bin /'b', 'i', 'n', EOS/ call query(usestr) if( getarg(1, comand, 3) == EOF | getarg(2, aname, NAMESIZE) == EOF) call help(usestr) call fold(comand) # Fold commands to lowercase. packit = YES if( comand(2) == VRBS ) verbos = YES else if (comand(2) == '1') packit = NO call initar # initialize common blocks call getfns # Put file names in array. if( comand(1) == UPD ) call update(aname) else if( comand(1) == TBL ) call table(aname) else if( comand(1) == EXTR | comand(1) == PRINT ) call extrac(aname, comand(1)) else if( comand(1) == DEL ) call delet(aname) else if( comand(1) == SALVAGE ) call recovr(aname) else call help(usestr) DRETURN end #-h- addfil 713 asc 25-mar-82 07:16:16 v1.1 (sw-tools v1.1) ## AddFil - Add file `name' to archive subroutine addfil(name, fd, errct) character head(MAXLINE), name(ARB) integer open # function(s) integer errct, fd, nfd, size(2), type include carch nfd = open(name, READ) if( nfd == ERR ) { call putlin("? ", ERROUT) call putlin(name, ERROUT) call remark(": can't add.") errct = errct + 1 return } call gettyp(nfd, type) call close(nfd) #need file space, so close for now if( errct == 0 ) { call arsize(name, size) call makhdr (name, head, size, type) if( verbos == YES ) { call putlin (name, STDOUT) call putch ('@n', STDOUT) } nfd = open(name,READ) call putlin(head, fd) call arcopy (nfd, fd, size) call close(nfd) } return end #-h- arcopy 383 asc 25-mar-82 07:16:16 v1.1 (sw-tools v1.1) subroutine arcopy(fdi, fdo, size) filedes fdi, fdo integer size(2), incs(2), tsize(2) character lin(MAXLINE) integer getlin # function(s) tsize(1) = size(1) tsize(2) = size(2) incs(1) = 0 while (!(tsize(1) <= 0 & tsize(2) <= 0)) { incs(2) = getlin( lin, fdi) if( incs(2) == EOF ) break if( fdo != ERR ) call putlin( lin, fdo) subdi(incs, tsize) } return end #-h- arsize 282 asc 25-mar-82 07:16:17 v1.1 (sw-tools v1.1) subroutine arsize(file, size) character file(FILENAMESIZE), c character getch integer size(2) filedes int filedes open int = open(file, READ) if (int == ERR) size(2) = ERR else { initdi(size) while (getch(c, int) != EOF) incrdi(size) call close(int) } return end #-h- delet 705 asc 25-mar-82 07:16:17 v1.1 (sw-tools v1.1) ## delet - Delete file(s) from archive. subroutine delet (aname) character aname(NAMESIZE), in(MAXLINE), tfile(FILENAMESIZE) integer create, open, remove # function(s) integer afd, tfd, junk include carch string tname "arctemp" if( fcount <= 0 ) call error("? Delete by name only.") afd = open(aname, READ) # Open archive file. if( afd == ERR ) call cant(aname) call scratf(tname, tfile) # Open scratch file. tfd = create(tfile, WRITE) if( tfd == ERR ) call cant(tfile) call replac(afd, tfd, DEL, errcnt) call notfnd call close(afd) call close(tfd) if( errcnt == 0 ) call fmove(tfile, aname) else call remark("? Fatal errors - archive not altered.") junk = remove(tfile) return end #-h- extrac 985 asc 25-mar-82 07:16:18 v1.1 (sw-tools v1.1) ## extrac - Extract files from archive. subroutine extrac(aname, cmd) character aname(NAMESIZE), ename(NAMESIZE), in(MAXLINE), cmd integer create, filarg, gethdr, open, equal # function(s) integer afd, efd, size(2), type include carch include arhdr afd = open(aname, READ) if( afd == ERR ) call cant(aname) if( cmd == PRINT ) efd = STDOUT else efd = ERR while( gethdr(afd, in, ename, size, type) != EOF ) { if( filarg(ename) == NO ) call arskip(afd, size) else { if( efd != STDOUT ) efd = create(ename, WRITE) if (efd == ERR) { call putlin("? ", ERROUT) call putlin(ename, ERROUT) call remark(": can't create.") errcnt = errcnt + 1 call arskip(afd, size) } else { if( verbos == YES ) { call putlin(ename, STDOUT) call putch('@n', STDOUT) } call arcopy(afd, efd, size) if( efd != STDOUT ) call close(efd) } } } call notfnd return end #-h- filarg 406 asc 25-mar-82 07:16:19 v1.1 (sw-tools v1.1) ## FilArg - Test `name' against argument list. integer function filarg(name) character name(ARB), temp(FILENAMESIZE) integer equal # function(s) integer i, j include carch if( fcount <= 0 ) return(YES) for( i = 1 ; i <= fcount ; i = i + 1 ) { j = filptr(i) call scopy(fname, j, temp, 1) if( equal(name, temp ) == YES) { fstat(i) = YES return(YES) } } return(NO) end #-h- fmove 270 asc 25-mar-82 07:16:20 v1.1 (sw-tools v1.1) subroutine fmove(in, out) character in(ARB), out(ARB) integer amove string str1 "? Error renaming " string str2 " to " if (amove(in, out) == ERR) { call putlin(str1, ERROUT) call putlin(in, ERROUT) call putlin(str2, ERROUT) call remark(out) } return end #-h- getfns 1355 asc 25-mar-82 07:16:20 v1.1 (sw-tools v1.1) ## GetFNs - Get file names into fname, check for duplicates. subroutine getfns character file(NAMESIZE) integer equal, getarg, getlin, length # function(s) integer i, j, k, usein include carch include cartmp # character temp(MAXLINE) data usein /NO/ errcnt = 0 j = 1 # pointer into fname for( i = 1 ; i <= MAXFILES ; i = i + 1 ) { if( usein == NO ) # Read list of files from arg list. { if( getarg(i+2, temp, NAMESIZE) == EOF ) break if( temp(1) == '-' & temp(2) == EOS ) usein = YES } if( usein == YES ) # Read list of files from STDIN. { len = getlin(temp, STDIN) if( len == EOF ) break temp(len) = EOS } call fold(temp) len = length(temp) + 1 if ((j + len) > MAXFILESPACE) break filptr(i) = j call stcopy(temp, 1, fname, j) j = j + 1 } fcount = i - 1 if( getarg(i+2, file, NAMESIZE) != EOF ) call error("too many file names.") for( i = 1 ; i <= fcount ; i = i + 1 ) { fstat(i) = NO } for( i = 1 ; i < fcount ; i = i + 1 ) { k = filptr(i) call scopy(fname, k, file, 1) for( j = i + 1 ; j <= fcount ; j = j + 1 ) { k = filptr(j) call scopy(fname, k, temp, 1) if (equal(file, temp) == YES) { call putlin("? ", ERROUT) call putlin(file, ERROUT) call error(": duplicate file name.") } } } return end #-h- gethdr 805 asc 25-mar-82 07:16:21 v1.1 (sw-tools v1.1) ## GetHdr - Get header info from archive member `fd'. integer function gethdr(fd, buf, name, size, type) character buf(MAXLINE), c, name(NAMESIZE), temp(NAMESIZE) integer ctoi, equal, getlin, getwrd, ishdr # function(s) integer fd, i, len, size(2), type, j include arhdr #***kludge since EOF isn't always sensed on an empty file if( new ) { gethdr = EOF return } if( getlin(buf, fd) == EOF ) { gethdr = EOF return } call fold(buf) if (ishdr(buf, i) == NO) call error("? Archive not in proper format.") gethdr = YES len = getwrd(buf, i, name) call ctodi(buf, i, size) len = getwrd (buf, i, temp) call fold(temp) if( len <= 0 | equal(temp,asc) ) type = ASCII else if( equal(temp, local) ) type = LOCAL else if( equal(temp, bin) ) type = BINARY else type = ASCII return end #-h- help 148 asc 25-mar-82 07:16:22 v1.1 (sw-tools v1.1) ## help - Print help message. subroutine help(msg) character msg(ARB) string qstr "? " call putlin(qstr, ERROUT) call error(msg) return end #-h- initar 185 asc 25-mar-82 07:16:22 v1.1 (sw-tools v1.1) subroutine initar integer isatty include arhdr include carch call mailid(user) if (packit == YES) packit = isatty(STDOUT) if (verbos == YES) packit = NO return end #-h- ishdr 248 asc 25-mar-82 07:16:23 v1.1 (sw-tools v1.1) integer function ishdr(buf, i) character buf(ARB) integer i include arhdr ishdr = YES for (i=1; hdr(i) != EOS; i=i+1) if (buf(i) != hdr(i)) { ishdr = NO break } if (ishdr == YES) if (buf(i) != ' ') ishdr = NO return end #-h- makhdr 1312 asc 25-mar-82 07:16:23 v1.1 (sw-tools v1.1) ## MakHdr - Make header line for archive member. subroutine makhdr(name, head, size, type) character head(MAXLINE), name(NAMESIZE), filsiz(MAXCHARS), date(10), time(10) integer ditoc, length # function(s) integer size(2), i, type, now(7) include arhdr include carch string twoblk " " i = 1 call stcopy(hdr, 1, head, i) # Insert header flag. call chcopy(' ', head, i) call stcopy(name, 1, head, i) # Insert file name. if( size(2) == ERR ) { filsiz(1) = EOS errcnt = errcnt + 1 } else junk = ditoc(size, filsiz, MAXCHARS) n = TWOCOLWIDTH - length(filsiz) - length(name) for (j=1; j < n; j=j+1) call chcopy(' ', head, i) call chcopy(' ', head, i) call stcopy(filsiz, 1, head, i) # Insert size of file. call stcopy(twoblk, 1, head, i) if( type == ASCII ) # Insert file type. call stcopy(asc, 1, head, i) else if( type == LOCAL ) call stcopy(local, 1, head, i) else if( type == BINARY ) call stcopy(bin, 1, head, i) call stcopy(twoblk, 1, head, i) call getnow(now) # get current date call fmtdat(date, time, now, LETTER) # format it call stcopy(date, 1, head, i) # copy into buffer call chcopy(' ', head, i) call stcopy(time, 1, head, i) call stcopy(twoblk, 1, head, i) call stcopy(user, 1, head, i) # insert username call chcopy('@n', head, i) call fold(head) return end #-h- notfnd 373 asc 25-mar-82 07:16:24 v1.1 (sw-tools v1.1) ## NotFnd - Print `not found' message. subroutine notfnd integer i, j character temp(FILENAMESIZE) include carch for( i = 1 ; i <= fcount ; i = i + 1 ) if (fstat(i) == NO ) { j = filptr(i) call scopy(fname, j, temp, 1) call putlin("? ", ERROUT) call putlin(temp, ERROUT) call remark(": not in archive.") errcnt = errcnt + 1 } return end #-h- nxtfl 802 asc 25-mar-82 07:16:25 v1.1 (sw-tools v1.1) ## NxtFl - Extract next file from damaged archive. integer function nxtfl(name, afd) character name(ARB), holdnm(FILENAMESIZE), buf(MAXLINE) integer create, getlin, equal, ishdr # function(s) integer afd, i include arhdr data holdnm(1) /EOS/ i = afd if( holdnm(1) == EOS ) # Pick up first name. { if( getlin(buf, afd) == EOF ) { nxtfl = EOF return } if (ishdr(buf, i) == NO) call error ("? Archive not in proper format.") len = getwrd(buf, i, holdnm) } call scopy(holdnm, 1, name, 1) holdnm(1) = EOS int = create(name, WRITE) # Open file specified. if( int == ERR ) call cant(name) while( getlin(buf, afd) != EOF ) { if (ishdr(buf, i) == YES) { len = getwrd(buf, i, holdnm) break } call putlin(buf, int) } call close(int) nxtfl = OK return end #-h- recovr 765 asc 25-mar-82 07:16:26 v1.1 (sw-tools v1.1) ## recovr - Recover archived file with incorrect byte counts. subroutine recovr (aname) integer create, open, nxtfl, remove # function(s) integer afd, tfd, junk character aname(ARB), tfile(FILENAMESIZE), name(FILENAMESIZE) include carch string tname "arctemp" afd = open(aname, READ) # Open archive. if( afd == ERR ) call cant(aname) call scratf (tname, tfile) # Open scratch file. tfd = create(tfile, WRITE) if( tfd == ERR ) call cant(tfile) while( nxtfl(name, afd) != EOF )# Loop through all files in archive. { call addfil(name, tfd, errcnt) junk = remove(name) } call close(afd) call close(tfd) if( errcnt == 0 ) call fmove(tfile, aname) else call remark("? Fatal errors - archive not altered.") junk = remove (tfile) return end #-h- replac 636 asc 25-mar-82 07:16:27 v1.1 (sw-tools v1.1) ## replac - Replace or delete files. subroutine replac(afd, tfd, cmd, errct) character in(MAXLINE), uname(NAMESIZE) integer filarg, gethdr # function(s) integer afd, cmd, errct, size(2), tfd, type include carch while( gethdr(afd, in, uname, size, type) != EOF ) { if( filarg(uname) == YES ) { if( cmd == UPD ) # Add new one. call addfil(uname, tfd, errct) if( verbos == YES & cmd == DEL) { call putlin (uname, STDOUT) call putch ('@n', STDOUT) } call arskip(afd, size) # Discard old one. } else { call putlin(in, tfd) call arcopy(afd, tfd, size) } } return end #-h- table 575 asc 25-mar-82 07:16:27 v1.1 (sw-tools v1.1) ## table - Print table of archive contents. subroutine table(aname) character aname(NAMESIZE), in(MAXLINE), lname(NAMESIZE) integer filarg, gethdr, open # function(s) integer afd, size(2), type include carch afd = open(aname, READ) if( afd == ERR ) call cant(aname) if (packit == YES) call inpack(nxtcol, RIGHT_MARGIN, obuf, STDOUT) while( gethdr(afd, in, lname, size, type) != EOF ) { if( filarg(lname) == YES ) call tprint(in) call arskip( afd, size) } if (packit == YES) call flpack(nxtcol, RIGHT_MARGIN, obuf, STDOUT) call notfnd return end #-h- tprint 536 asc 25-mar-82 07:16:28 v1.1 (sw-tools v1.1) ## TPrint - Print table entry for one member. subroutine tprint(buf) integer i, j character buf(ARB), name(NAMESIZE) include carch for (i=1 ; buf(i) != ' ' ; i=i+1) # Skip initial header flag. ; j = 1 for( i=i+1 ; buf(i) != ' ' ; i=i+1 ) # Print filename. call chcopy(buf(i), name, j) name(j) = EOS if (packit == YES) call dopack(name, nxtcol, RIGHT_MARGIN, obuf, STDOUT) else { call putlin(name, STDOUT) if (verbos == YES) call putlin(buf(i), STDOUT) else call putch('@n', STDOUT) } return end #-h- update 1116 asc 25-mar-82 07:16:29 v1.1 (sw-tools v1.1) ## update - Update existing files, add new ones at end. subroutine update(aname) character aname(NAMESIZE), tfile(FILENAMESIZE) integer create, getarg, open, remove # function(s) integer afd, i, tfd, j, junk include carch include arhdr include cartmp # character temp(MAXLINE) string tname "arctemp" afd = open(aname, READ) if( afd == ERR ) # Maybe it's a new one. ###kludge since EOF can't always be sensed on a new file. { afd = create(aname, WRITE) if( afd == ERR ) call cant(aname) new = YES } else new = NO call close(STDIN) # Save a file slot. call scratf(tname, tfile) # Open scratch file. tfd = create(tfile, WRITE) if( tfd == ERR ) call cant(tfile) call replac(afd, tfd, UPD, errcnt) # Update existing. for( i = 1 ; i <= fcount ; i = i + 1 ) # Add new ones. if( fstat(i) == NO ) { j = filptr(i) call scopy(fname, j, temp, 1) call addfil(temp, tfd, errcnt) fstat(i) = YES } call close(afd) call close(tfd) if( errcnt == 0 ) call fmove(tfile, aname) else call remark("? Fatal errors - archive not altered.") junk = remove(tfile) return end #-h- ar.fmt 6808 asc 25-mar-82 07:17:04 v1.1 (sw-tools v1.1) .so ~bin/manhdr .hd Ar (1) 11-Oct-79 archive file maintainer .sy ar {dpstux}[v/1] arcname [file] ... .ds Ar collects sets of arbitrary files into one big file and maintains that file as an 'archive'. Files can be extracted from the archive, new ones can be added, old ones can be deleted or replaced by updated versions, and data about the contents can be listed. If a minus sign ('-') is given as a file name, further file names are read from the standard input, one file name per line. Files that are to be added to an archive must exist as files with the name given. Files that are extracted from an archive will be put onto files with the name given. Files that are added to archives can, of course, be archive files themselves. There is no (theoretical) limit to the number of files that can be nested this way. Thus Ar provides the utility necessary to maintain tree-structured file directories. Ar is invoked by the command line .br .ti +10 Ar command archname [optional filenames] where 'command' is any one of 'uxtpds', optionally concatenated with 'v' or '1', specifying what operation to perform on the archive file named 'archname'. The possible commands are: .br .in +10 u - Update named archive by replacing existing files or adding new ones at end. If the 'v' option is used, file names will be printed on the standard output as files are written to the new archived file. x - Extract named files from archive. Put onto file of the same name. If the 'v' option is added, file names will be printed on the standard output as files are extracted. d - Delete named files from archive. If the 'v' option is used, file names will be printed on the standard output as they are deleted from the archive. p - Print named files on standard output. Using the 'v' option will cause the file name to precede the file. t - Print table of archive contents. Normally, the table will contain only the file name. If the 'v' option is used, the table will also contain the file's length, type, and date and time of last change. By default, if the standard output is a terminal, ar will pack five names per line in the non-verbose mode. If the optional '1' option is used, the output is force to single column, which is the default is standard output is not a terminal. For example, ar t archive might generate the following output: a b c d whereas ar t1 archive would generate .nf a b c d .fi s - Salvage. This command may be used to recover a damaged archive whose character counts do not reflect the correct number of characters in the file. The 's' command extracts all files from the archive, ignoring characters counts, date and time stamps, etc. on the archive header lines; it simply uses '#-h-, which begins each archive member, and the file name which follows it. The files are then replaced in the archive, with corrected character counts. Thus, the 's' flag is useful for salvaging the contents of 'alien' archive files and for saving damaged archives. It does not work on nested archives (i.e. archives within archives). v - Verbose. This command may be concatenated to any of the above commands, and will cause the archiver to print additional information, generally file names, on the standard output. Its specific action for each command has already been described. .br .in -10 The optional filenames in the command line specify individual files that may participate in the action. If no files are named, the action is done on ALL files in the archive, but if any files are explicitly named, they are the ONLY ones that take part in the action. (The 'd' command is an exception--files may be deleted only by specifying their names.) .fl A file 'arctemp' is created and subsequently deleted for each run. .sa The Unix commands 'ar' and 'ls' in the Unix manual .br `rar' - rearrange archive .di archive not in proper format .br .in +10 The basic problem is that archive didn't find a header line where one was expected. Typical reasons include misspelling the file name, using an existing file (not in archive format) on a creation run, and referencing an archive file that has been modified directly (say with the editor). .br .in -10 delete by name only .br .in +10 For user protection, files are allowed to be deleted from an archive only by specifying each file name. .br .in -10 duplicate file name .br .in +10 A file was listed more than once when calling the archiver .br .in -10 fatal errors-archive not altered .br .in +10 This message is generated whenever one or more of the other errors have been detected. An archive is never altered unless EVERYTHING has run properly. .br .in -10 too many file names .br .in +10 At the present the user may call the archiver with no more than 25 files at a time. .br .in -10 usage: ar [dptuxsv] arcname [files] .br .in +10 The command line passed to the archiver is in error. Possibly the command is wrong or the archived file name has not been given. .br .in -10 'filename': can't add .br .in +10 The file specified by 'filename' doesn't exist or can't be opened (e. g. is locked). .br .in -10 'filename': can't create .br .in +10 The archiver could not generate a local file by the name of 'filename'. Probably the archiver's internal file buffer space has been exceeded. .br .in -10 'filename': not in archive .br .in +10 The archiver could not locate the file specified by 'filename' in the archived file. .br .in -10 .au Original code from Kernighan and Plauger's 'Software Tools', with modifications by Debbie Scherrer. .bu On some systems only text files can be archived. When the update and print commands are used, the files are updated or printed in the order they appear on the archived file, NOT the order listed on the command line. The 's' salvage command works only on unnested archives. The Unix archiver allows files to be positioned in the archive, rather than simply added at the end as Ar does. This is done by adding the following commands: .br .in +10 m - Move specified files to end of archive ma posname - Move specified files to position after file 'posname' mb posname - Move specified files to position before file 'posname' r - Replace specified files and place at end of archive ra posname - Replace files and place after file 'posname' rb posname - Replace files and place before file 'posname' .br .in -10 There are some discrepancies between the Unix version of Ar and this version. Unix uses 'r'--replace instead of 'u'--update. Unix also requires the user to specify an additional command 'n' when creating a new archive. %%E 1