#-h-  version1                  24209  local   01/16/81  17:12:15
#-h-  ar.doc                     6011  local   12/10/80  14:11:18
.bp 1
.in 0
.he 'AR (1)'09/16/80'AR (1)'
.fo ''-#-'
.fi
.in 7
.ti -7
NAME
.br
ar - archive file maintainer
.sp 1
.ti -7
SYNOPSIS
.br
ar [-](d|p|t|u|x)[v] arcname [files]
.sp 1
.ti -7
DESCRIPTION
.br
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 'dptux', optionally concatenated
with 'v', 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.

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.)


.br

.sp 1
.ti -7
FILES
.br
A file 'arctemp' is created and subsequently deleted for each run.
.sp 1
.ti -7
SEE ALSO
.br
The Unix commands 'ar' and 'ls' in the Unix manual
.sp 1
.ti -7
DIAGNOSTICS
.br
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

archive integrity in doubt - missing trailer
.br
.in +10
Each file in an archive is terminated by a special line called a
"trailer," which must be present.
The message is caused by the lack of a trailer line when one was
expected.
.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 [-](dptux)[v] arcname [files]
.br
.in +10
The command line passed to the archiver is in error.
Possibly the command is wrong or the archive 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
.sp 1
.ti -7
AUTHORS
.br
Original code from Kernighan and Plauger's 'Software Tools',
with rewrites by Allen Akin (Georgia Institute of Technology)
and minor changes suggested by David Hanson (University
of Arizona).
.sp 1
.ti -7
BUGS/DEFICIENCIES
.br
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 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.
#-t-  ar.doc                     6011  local   12/10/80  14:11:18
#-h-  carch                       276  local   01/16/81  17:11:19
# carch - common blocks for the archiver

   character fname (FILENAMESIZE, MAXFILES)

   integer fstat (MAXFILES), fcount, errcnt, verbos

  character chead (MAXLINE)      # holds current header
   common /carch/ fname, fstat, fcount, errcnt, verbos,
                  chead
#-t-  carch                       276  local   01/16/81  17:11:19
#-h-  ar.r                      17526  local   01/16/81  17:11:20
#-h-  ar                         2027  local   11/26/80  14:24:54
# ar - archive file maintainer

   define(ON,)
   define(OFF,#)
   define(FOLDF,ON)           # if on, fold file names to lower case

   define(MAXFILES,24)        # maximum number of files processable

   define(DELETE_CMD,LETD)    # delete member from archive (by name only)
   define(PRINT_CMD,LETP)     # print archive members
   define(TABLE_CMD,LETT)     # print table of contents
   define(UPDATE_CMD,LETU)    # update archive member
   define(VERBOSE_CMD,LETV)   # controls amount of output
   define(EXTRACT_CMD,LETX)   # extract archive member

   define(USAGE_MESSAGE,"usage:  ar (dptux)[v] archive [files].")

   define(HEADER_STRING,"#-h-")
   define(TRAILER_STRING,"#-t-")
   define(NAMESIZE,20)         # size of name allowed in header

   define(ASCII_STRING,"ascii ")
   define(LOCAL_STRING,"local ")
  define(BINARY_STRING,"binary")

  # The file size (in characters) is computed for storage in the
  # archive headers, although this information is not used.  
  # If desired, this feature can be left out, thus speeding up
  # up execution.  To do it:
  #          define(SPEED_UP,)
 
 
 
   DRIVER(ar)

   include carch

   character aname (FILENAMESIZE), comand (MAXARG)

   integer i
   integer getarg

   errcnt = 0

   call query (USAGE_MESSAGE)

   if (getarg (1, comand, MAXARG) == EOF
     | getarg (2, aname, FILENAMESIZE) == EOF)
      call error (USAGE_MESSAGE)

   call getfns

   call fold (comand)

   if (comand (1) == MINUS)      # skip leading '-' if present
      i = 2
   else
      i = 1
   if (comand (i + 1) == VERBOSE_CMD)
      verbos = YES
   else if (comand (i + 1) == EOS)
      verbos = NO
   else
      call error (USAGE_MESSAGE)

   if (comand (i) == UPDATE_CMD)
      call update (aname)
   else if (comand (i) == TABLE_CMD)
      call table (aname)
   else if (comand (i) == EXTRACT_CMD | comand (i) == PRINT_CMD)
      call extrac (aname, comand (i))
   else if (comand (i) == DELETE_CMD)
      call delete (aname)
   else
      call error (USAGE_MESSAGE)

   DRETURN
   end
#-t-  ar                         2027  local   11/26/80  14:24:54
#-h-  addfil                      711  local   11/26/80  14:24:55
# addfil - add file 'name' to archive open on 'fd'

   subroutine addfil (name, fd)
   character name (ARB)
   filedes fd

   include carch

   character head(MAXLINE), trail(MAXLINE)

   filedes nfd
   filedes open


   nfd = open (name, READ)
   if (nfd == ERR) {
      call putlin (name, ERROUT)
      call remark (":  can't add.")
      errcnt = errcnt + 1
      return
      }

   if (errcnt == 0) {
      call makhdr (head, name)
      if (verbos == YES) {
         call putlin (name, STDOUT)
         call putch (NEWLINE, STDOUT)
         }
      call putlin (head, fd)
      call cpin (nfd, fd)
      call maktrl (head, trail)
      call putlin (trail, fd)
      }

   call close (nfd)
   return
   end
#-t-  addfil                      711  local   11/26/80  14:24:55
#-h-  cpin                        253  local   11/26/80  14:24:55
# cpin --- copy a file into an archive
# may have to be adjusted to allow for binary files

   subroutine cpin (fd, afd)
   filedes fd, afd

   call fcopy (fd, afd)

   return
   end
#-t-  cpin                        253  local   11/26/80  14:24:55
#-h-  cpmemb                      438  local   11/26/80  14:24:55
# cpmemb --- copy archive element from one archive to another

   subroutine cpmemb (oldafd, newafd)
   filedes oldafd, newafd

   include carch

   character line (MAXLINE)

   integer getlin, elend


   while (getlin (line, oldafd) != EOF) {
      call putlin (line, newafd)
      if (elend (line) == YES)
         return
      }

   call remark ("archive integrity in doubt - missing trailer.")
   errcnt = errcnt + 1
   return
   end
#-t-  cpmemb                      438  local   11/26/80  14:24:55
#-h-  cpout                       499  local   11/26/80  14:24:56
# cpout --- copy a file out of an archive

   subroutine cpout (afd, fd)
   filedes afd, fd

   include carch

   character line (MAXLINE)

   integer start
   integer getlin, elend, length



   while (getlin (line, afd) != EOF) {
      if (elend (line) == YES)
         return      # we've copied the whole archive element
      else
         call putlin (line, fd)  # ordinary text
      }

   call remark ("archive integrity in doubt - missing trailer.")
   errcnt = errcnt + 1
   return
   end
#-t-  cpout                       499  local   11/26/80  14:24:56
#-h-  delete                      754  local   11/26/80  14:24:56
# delete - delete files from the archive

   subroutine delete (aname)
   character aname (ARB)

   include carch

   character tname (FILENAMESIZE)

   filedes afd, tfd
   filedes create, open

   integer junk
   integer remove

   string tprefx "arctemp"

   if (fcount <= 0)
      call error ("delete by name only.")

   afd = open (aname, READ)
   if (afd == ERR)
      call cant (aname)

   call mkuniq (tprefx, tname)
   tfd = create (tname, WRITE)
   if (tfd == ERR)
      call cant (tname)

   call replac (afd, tfd, DELETE_CMD)
   call notfnd

   call close (afd)
   call close (tfd)
   if (errcnt == 0)
      call amove (tname, aname)
   else
      call remark ("fatal errors - archive not altered.")
   junk = remove (tname)

   return
   end
#-t-  delete                      754  local   11/26/80  14:24:56
#-h-  extrac                     1047  local   11/26/80  14:24:57
# extrac - extract files from archive

   subroutine extrac (aname, cmd)
   character aname (ARB), cmd

   include carch

   character name (FILENAMESIZE), hdr (MAXLINE)

   filedes afd, fd
   filedes create, open

   integer filarg, gethdr, equal

   afd = open (aname, READ)
   if (afd == ERR)
      call cant (aname)

   while (gethdr (afd, hdr, name) != EOF)

      if (filarg (name) == NO)
         call skipf (afd)

      else {
         if (verbos == YES) {
            call putlin (name, STDOUT)
            call putch (NEWLINE, STDOUT)
            }

         if (cmd == PRINT_CMD)
            call cpout (afd, STDOUT)
         else {
            fd = create (name, WRITE)
            if (fd != ERR) {
               call cpout (afd, fd)
               call close (fd)
               }
            else {
               call putlin (name, ERROUT)
               call remark (":  can't create.")
               errcnt = errcnt + 1
               call skipf (afd)
               }
            }

         }

   call notfnd
   return
   end
#-t-  extrac                     1047  local   11/26/80  14:24:57
#-h-  filarg                      367  local   11/26/80  14:24:57
# filarg - see if name is present in argument list

   integer function filarg (name)
   character name (ARB)

   include carch

   integer i
   integer equal

   if (fcount <= 0)
      return (YES)

   for (i = 1; i <= fcount; i = i + 1)
      if (equal (name, fname (1, i)) == YES) {
         fstat (i) = YES
         return (YES)
         }

   return (NO)
   end
#-t-  filarg                      367  local   11/26/80  14:24:57
#-h-  fsize                       416  local   11/26/80  14:24:57
# fsize - determine size of file (in lines)

   integer function fsize (name)
   character name (ARB)

   filedes fd
   filedes open

   character line (MAXLINE)

   integer l
   integer getlin

   fd = open (name, READ)
   if (fd == ERR)
      return (ERR)

   fsize = 0
   repeat {
      l = getlin (line, fd)
      if (l == EOF)
         break
      fsize = fsize + l
      }

   call close (fd)
   return
   end
#-t-  fsize                       416  local   11/26/80  14:24:57
#-h-  getfns                     1438  local   11/26/80  14:24:58
# getfns - get file names into 'fname', check for duplicates

   subroutine getfns

   include carch

   integer ap, fp, len, i
   integer getarg, getlin

   character line (MAXLINE)

   fp = 1

   for (ap = 3; getarg (ap, fname (1, fp), FILENAMESIZE) != EOF; ap = ap + 1)
      if (fname (1, fp) == MINUS & fname (2, fp) == EOS) {
         while (fp <= MAXFILES) {
            len = getlin (fname (1, fp), STDIN)
            if (len == EOF)
               break
            fname (len, fp) = EOS         # remove the NEWLINE
            FOLDF call fold (fname (1, fp))
            fp = fp + 1
            }
         if (fp > MAXFILES)
            if (getlin (line, STDIN) != EOF)
               call error ("too many file names.")
         }
      else {
         FOLDF call fold (fname (1, fp))
         fp = fp + 1
         if (fp > MAXFILES)
            if (getarg (ap + 1, line, MAXLINE) != EOF)
               call error ("too many file names.")
         }

   fcount = fp - 1
   for (fp = 1; fp <= fcount; fp = fp + 1)
      fstat (fp) = NO

   for (fp = 1; fp < fcount; fp = fp + 1)
      for (i = fp + 1; i <= fcount; i = i + 1)
         if (equal (fname (1, fp), fname (1, i)) == YES) {
            call putlin (fname (1, i), ERROUT)
            call remark (":  duplicate file name.")
            errcnt = errcnt + 1
            }

   if (errcnt != 0)
      call error ("fatal errors - archive not altered.")

   return
   end
#-t-  getfns                     1438  local   11/26/80  14:24:58
#-h-  gethdr                      629  local   11/26/80  14:24:58
# gethdr - get header information from archive member in 'fd'

   integer function gethdr (fd, hdr, name)
   filedes fd
   character hdr (ARB), name (ARB)

   include carch

   character text (FILENAMESIZE)

   integer i, len
   integer getwrd, equal, ctoi, getlin

   string hdrstr HEADER_STRING

   if (getlin (hdr, fd) == EOF)
      return (EOF)
   call fold (hdr)

   i = 1

   len = getwrd (hdr, i, text)
   if (equal (text, hdrstr) == NO) {
      call remark ("archive not in proper format.")
      errcnt = errcnt + 1
      return (EOF)
      }

   call savhdr (hdr)
   len = getwrd (hdr, i, name)

   return (YES)
   end
#-t-  gethdr                      629  local   11/26/80  14:24:58
#-h-  gettyp                      142  local   11/26/80  14:24:59
# gettyp - determine file type (ASCII, LOCAL, or BINARY)

   integer function gettyp (name)
   character name (ARB)

   return (LOCAL)
   end
#-t-  gettyp                      142  local   11/26/80  14:24:59
#-h-  makhdr                     1400  local   11/26/80  14:24:59
# makhdr - make header line for an archive member

   subroutine makhdr (head, name)
   character head (ARB), name (ARB)

   include carch

   integer i, type, l, junk, now (7)
   integer fsize, gettyp, itoc, length

   character size (MAXCHARS), time (MAXLINE), date (MAXLINE)

   string hdrstr HEADER_STRING
   string blanks "  "
   string astr ASCII_STRING
   string lstr LOCAL_STRING
   string bstr BINARY_STRING

   i = 1
   call stcopy (hdrstr, 1, head, i)
   call stcopy (blanks, 1, head, i)
   call stcopy (name, 1, head, i)
   for (l = length(name) + 1; l <= NAMESIZE; l = l+1)
           {
           head(i) = BLANK
           i = i + 1
           }
  ifnotdef(SPEED_UP,
   for (l = itoc (fsize (name), size, MAXCHARS); l <= 10; l = l + 1) {
      head (i) = BLANK
      i = i + 1
      }
   call stcopy (size, 1, head, i)
   call stcopy (blanks, 1, head, i)
          )

   type = gettyp (name)
   if (type == ASCII)
      call stcopy (astr, 1, head, i)
   else if (type == LOCAL)
      call stcopy (lstr, 1, head, i)
  else if (type == BINARY)
      call stcopy (bstr, 1, head, i)
   else
      call stcopy (astr, 1, head, i)

   call stcopy (blanks, 1, head, i)
   call getnow (now)
   call fmtdat (date, time, now, 0)
   call stcopy (date, 1, head, i)
   call stcopy (blanks, 1, head, i)
   call stcopy (time, 1, head, i)

   head (i) = NEWLINE
   head (i + 1) = EOS

   return
   end
#-t-  makhdr                     1400  local   11/26/80  14:24:59
#-h-  maktrl                      384  local   11/26/80  14:25:00
# maktrl - make trailer line for an archive member

   subroutine maktrl (head, trail)
   character trail (ARB), head (ARB)
   integer i, j, len
   integer getwrd

   include carch

   string tstr TRAILER_STRING

   i = 1
   len = getwrd (head, i, trail)        # skip over header string
   j = 1
   call stcopy (tstr, 1, trail, j)
   call stcopy (head, i, trail, j)
   return
   end
#-t-  maktrl                      384  local   11/26/80  14:25:00
#-h-  notfnd                      333  local   11/26/80  14:25:00
# notfnd - print 'not found' message if member isn't in archive

   subroutine notfnd

   include carch

   integer i

   for (i = 1; i <= fcount; i = i + 1)
      if (fstat (i) == NO) {
         call putlin (fname (1, i), ERROUT)
         call remark (":  not in archive.")
         errcnt = errcnt + 1
         }

   return
   end
#-t-  notfnd                      333  local   11/26/80  14:25:00
#-h-  elend                       384  local   11/26/80  14:25:01
# elend --- see if string is end of archive element

   integer function elend (str)
 
   character str (ARB)
   integer i
   integer equal
 
   include carch

  string tstr TRAILER_STRING
 

  for (i=1; tstr(i) != EOS; i=i+1)       # look for trailer string
          if (tstr(i) != str(i) )
                return(NO)
  call skipbl (str, i)
  return ( equal(str(i), chead) )
   end
#-t-  elend                       384  local   11/26/80  14:25:01
#-h-  replac                      646  local   11/26/80  14:25:01
# replac - replace or delete archive members

   subroutine replac (afd, tfd, cmd)
   filedes afd, tfd
   character cmd

   include carch

   character hdr (MAXLINE), name (FILENAMESIZE)

   integer gethdr, filarg

   while (gethdr (afd, hdr, name) != EOF)
      if (filarg (name) == YES) {
         if (cmd == UPDATE_CMD)
            call addfil (name, tfd)
         if (verbos == YES & cmd == DELETE_CMD) {
            call putlin (name, STDOUT)
            call putch (NEWLINE, STDOUT)
            }
         call skipf (afd)
         }
      else {
         call putlin (hdr, tfd)
         call cpmemb (afd, tfd)
         }

   return
   end
#-t-  replac                      646  local   11/26/80  14:25:01
#-h-  savhdr                      245  local   11/26/80  14:25:01
# savhdr - save current header
  subroutine savhdr (head)
 
  include carch
  character head(ARB)
  integer i, len
  integer getwrd

  i = 1
  len = getwrd (head, i, chead)
  call skipbl (head, i)
  call scopy (head, i, chead, 1)
  return
  end
#-t-  savhdr                      245  local   11/26/80  14:25:01
#-h-  skipf                       360  local   11/26/80  14:25:02
# skipf --- skip current archive element on file afd

   subroutine skipf (afd)
   filedes afd

   include carch

   character line (MAXLINE)

   integer getlin, elend


   while (getlin (line, afd) != EOF)
      if (elend (line) == YES)
         return

   call remark ("archive integrity in doubt - missing trailer.")
   errcnt = errcnt + 1
   return
   end
#-t-  skipf                       360  local   11/26/80  14:25:02
#-h-  table                       464  local   11/26/80  14:25:02
# table - print table of archive contents

   subroutine table (aname)
   character aname (ARB)

   filedes afd
   filedes open

   character hdr (MAXLINE), name (FILENAMESIZE)

   integer gethdr, filarg

   afd = open (aname, READ)
   if (afd == ERR)
      call cant (aname)

   while (gethdr (afd, hdr, name) != EOF) {
      if (filarg (name) == YES)
         call tprint (hdr)
      call skipf (afd)
      }

   call close (afd)
   call notfnd
   return
   end
#-t-  table                       464  local   11/26/80  14:25:02
#-h-  tprint                      593  local   11/26/80  14:25:02
# tprint - print table entry for one archive member

   subroutine tprint (hdr)
   character hdr (ARB)

   include carch

   character name (FILENAMESIZE)

   integer i, len
   integer getwrd, length

   i = 1
   len = getwrd (hdr, i, name)      # skip the header string itself

   len = getwrd (hdr, i, name)      # grab the filename

   call putlin (name, STDOUT)
   if (verbos == YES) {             # print other info only if asked
      for (; hdr (i) != NEWLINE & hdr (i) != EOS; i = i + 1)
         call putch (hdr (i), STDOUT)
      }

   call putch (NEWLINE, STDOUT)

   return
   end
#-t-  tprint                      593  local   11/26/80  14:25:02
#-h-  update                     1162  local   11/26/80  14:25:03
# update - update existing files, add new ones at end

   subroutine update (aname)
   character aname (ARB)

   include carch

   filedes afd, tfd
   filedes open, create

   integer fp, junk
   integer remove

   character tname (FILENAMESIZE)

   string tprefx "arctemp"

   afd = open (aname, READ)
   if (afd == ERR) {          # try to create a new archive
      afd = create (aname, WRITE)
      if (afd == ERR)
         call cant (aname)
      call close (afd)        # close and reopen to mark EOF
      afd = open (aname, READ)
      if (afd == ERR)
         call cant (aname)
      }

   call mkuniq (tprefx, tname)
   tfd = create (tname, WRITE)
   if (tfd == ERR)
      call cant (tname)

   call replac (afd, tfd, UPDATE_CMD)        # update existing members

   for (fp = 1; fp <= fcount; fp = fp + 1)   # add new members
      if (fstat (fp) == NO) {
         call addfil (fname (1, fp), tfd)
         fstat (fp) = YES
         }

   call close (afd)
   call close (tfd)

   if (errcnt == 0)
      call amove (tname, aname)
   else {
      call remark ("fatal errors - archive not altered.")
      junk = remove (tname)
      }

   return
   end
#-t-  update                     1162  local   11/26/80  14:25:03
#-t-  ar.r                      17526  local   01/16/81  17:11:20
#-t-  version1                  24209  local   01/16/81  17:12:15
#-h-  version2                  26233  local   12/10/80  14:08:39
#-h-  ar.doc                     6643  local   12/04/80  15:48:24
.bp 1
.in 0 
.he 'AR (1)'10/11/79'AR (1)' 
.fo ''-#-' 
.fi 
.in 7 
.ti -7 
NAME 
.br 
ar - archive file maintainer 
.sp 1 
.ti -7 
SYNOPSIS 
.br 
ar [-uxtdpsv] arcname [file] ... 
.sp 1 
.ti -7 
DESCRIPTION 
.br 
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', 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. 
  
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.) 
  
  
.br 
  
.sp 1 
.ti -7 
FILES 
.br 
A file 'arctemp' is created and subsequently deleted for each run. 
.sp 1 
.ti -7 
SEE ALSO 
.br 
The Unix commands 'ar' and 'ls' in the Unix manual 
.sp 1 
.ti -7 
DIAGNOSTICS 
.br 
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 
.sp 1 
.ti -7 
AUTHORS 
.br 
Original code from Kernighan and Plauger's 'Software Tools', 
with modifications by Debbie Scherrer (Lawrence Berkeley Laboratory) 
.sp 1 
.ti -7 
BUGS/DEFICIENCIES 
.br 
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. 
#-t-  ar.doc                     6643  local   12/04/80  15:48:24
#-h-  carch                       478  local   12/04/80  15:48:26
 # /carch/ common block holding file info for the archiver
 # put on a file named 'carch'
 # Used only by the archiver
 
 
 common /carch/ fname(NAMESIZE,MAXFILES),fstat(MAXFILES),
                fcount, errcnt, verbos
 
    character fname      # file arguments
    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
#-t-  carch                       478  local   12/04/80  15:48:26
#-h-  arhdr                       368  local   12/04/80  15:48:27
 # /hdr/ - common block holding header info for archiver
 # put on a file called 'arhdr'
 # Used only by the archiver
 
  common /hdr/ hdr(5), new, asc(4), local(6), bin(4)
 
  character hdr		#header flag
  integer new		#flag for new file
  character asc		#flag for ascii files
  character local	#flag for local character files
  character bin		#flag for binary files
#-t-  arhdr                       368  local   12/04/80  15:48:27
#-h-  ar.r                      18216  local   12/10/80  14:07:33
#-h-  defns                      1325  local   12/04/80  15:29:38
 #        include ratdef
 #definitions for the archiver
 
 define(FOLDF,)                  # fold all file names to single case
          #NOTE:  If you want upper and lower case in file names to
          # be signficant, leave out the definition
 
 define(NAMESIZE,FILENAMESIZE)   # Max number of characters in
                                 # file name (includes EOS)
 define(MAXFILES,24)   # Max number of files allowed per archive call
 define(MAXCHARS,20)   # Max number of characters allowed in header for
                       # the size of the file
 define(TBL,LETT)      # Command to print table of contents
 define(PRINT,LETP)    # Command to print files
 define(EXTR,LETX)     # Command to extract files from archive
 define(UPD,LETU)      # Command to update archive
 define(DEL,LETD)      # Command to delete files from archive
 define(SALVAGE,LETS)  # command to salvage damaged archive
 define(VRBS,LETV)     # Command to set "verbose" flag
 define(TWOCOLWIDTH,20)	# fixed width of filename in header
 define(ASCII,12)      # flag for files made up of ascii characters
 define(BINARY,60)     # flag for binary files
 define(LOCAL,6)       # flag for files made up of local characters
 
 
#-t-  defns                      1325  local   12/04/80  15:29:38
#-h-  acopy                       236  local   12/04/80  15:29:39
 ## acopy - copy size characters from fdi to fdo
 subroutine acopy (fdi, fdo, size)
 character getch
 character c
 integer fdi, fdo, i, size
 
 for (i=1; i<=size; i=i+1)
	{
	if (getch(c,fdi) != EOF)
	call putch (c, fdo)
	}
 return
 end
#-t-  acopy                       236  local   12/04/80  15:29:39
#-h-  addfil                      758  local   12/04/80  15:29:39
 ## addfil - add file 'name'  to archive
   subroutine addfil(name, fd, errct)
 
   character head(MAXLINE), name(ARB)
   integer open, fsize
   integer errct, fd, nfd, size, type
   include carch
 
   nfd = open(name, READ)
   if (nfd == ERR) {
      call putlin(name, ERROUT)
      call remark(': cant add.')
      errct = errct + 1
      return
      }
  call getyp(nfd, type)
  call close(nfd)		#need file space, so close for now
   if (errct == 0)
      {
       size = fsize (name)
       call makhdr (name, head, size, type)
       if (verbos == YES)
		{
		call putlin (name, STDOUT)
		call putch (NEWLINE, STDOUT)
		}
	nfd = open(name,READ)
       call putlin(head, fd)
      call acopy (nfd, fd, size)
      call close(nfd)
      }
   return
   end
#-t-  addfil                      758  local   12/04/80  15:29:39
#-h-  amove                       390  local   12/04/80  15:29:40
 ## amove - move name1 to name2
 subroutine amove (name1, name2)
 character name1(ARB), name2(ARB), buf(MAXLINE)
 integer create, open, getlin
 integer fd1, fd2
 
 fd1 = open(name1,READ)
 if (fd1 == ERR)
	call cant (name1)
 fd2 = create(name2, WRITE)
 if (fd2 == ERR)
	call cant (name2)
 while (getlin(buf,fd1) != EOF)
	call putlin(buf,fd2)
 call close (fd1)
 call close (fd2)
 return
 end
#-t-  amove                       390  local   12/04/80  15:29:40
#-h-  ars                        1125  local   12/04/80  15:29:41
 ## ar - driver subroutine for 'ar' - file maintainer
 DRIVER(ar)
 
   character aname(NAMESIZE)
   integer getarg, ovride
   character comand(3)
 
   include carch
   include arhdr
 
  data errcnt /0/
  data verbos /NO/
 
  #Set up header format
  data hdr /SHARP, MINUS, LETH, MINUS, EOS/
  data asc /LETA, LETS, LETC, EOS/
  data local /LETL, LETO, LETC, LETA, LETL, EOS/	#NOTBKY
  data bin /LETB, LETI, LETN, EOS/
 
 
 
   if (getarg(1, comand, 3) == EOF |
       getarg(2, aname, NAMESIZE) == EOF |
       comand(1) == QMARK & comand(2) == EOS)
      call help
 
   call getfns   # put file names in array
 
   call fold(comand)		#fold commands to single case
   i = 1
   if (comand(1) == MINUS)      #allow '-' before commands
	i = 2
   if (comand(i+1) == VRBS)  verbos = YES
 
   if (comand(i) == UPD)
      call update(aname)
   else if (comand(i) == TBL)
      call table(aname)
   else if (comand(i) == EXTR | comand(i) == PRINT)
      call extrac(aname, comand(i))
   else if (comand(i) == DEL)
      call delet (aname)
 else if (comand(i) == SALVAGE)
	call recovr(aname)
   else
      call help
 DRETURN
   end
 
#-t-  ars                        1125  local   12/04/80  15:29:41
#-h-  delet                       813  local   12/04/80  15:29:42
 
  #---------------------------------------------------------------
 ## delet  - delet  files from archive
   subroutine delet (aname)
   character aname(NAMESIZE), in(MAXLINE), tfile(FILENAMESIZE)
   integer create, open
   integer afd, tfd
   include carch
    string tname 'arctemp'
 
   if (fcount <= 0)    # protect innocents
      call error('delete by name only.')
   afd = open(aname, READ)
   if (afd == ERR)
      call cant(aname)
   call mkuniq(tname, tfile)		#get scratch file name
   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 amove(tfile, aname)
   else
      call remark('fatal errors - archive not altered.')
   call remove(tfile)
   return
   end
#-t-  delet                       813  local   12/04/80  15:29:42
#-h-  extrac                     1130  local   12/04/80  15:29:43
  #---------------------------------------------------------------
 ## extrac - extract files from archive
   subroutine extrac(aname, cmd)
 
   character aname(NAMESIZE), ename(NAMESIZE), in(MAXLINE), cmd
   integer create, filarg, gethdr, open, equal
   integer afd, efd, size, 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 fskip(afd, size)
      else {
         if (efd != STDOUT)
            efd = create(ename, WRITE)
         if (efd == ERR) {
            call putlin(ename, ERROUT)
            call remark(': cant create.')
            errcnt = errcnt + 1
            call fskip(afd, size)
            }
         else
            {
             if (verbos == YES)
		{
		call putlin (ename, STDOUT)
		call putch (NEWLINE, STDOUT)
		}
            call acopy (afd, efd, size)
            if (efd != STDOUT)
                   call close (efd)
            }
         }
   call notfnd
   return
   end
#-t-  extrac                     1130  local   12/04/80  15:29:43
#-h-  filarg                      472  local   12/04/80  15:29:43
  #---------------------------------------------------------------
 ## filarg - check if name matches argument list
   integer function filarg(name)
   character name(ARB)
   integer equal
   integer i
   include carch
 
   if (fcount <= 0) {
      filarg = YES
      return
      }
   for (i = 1; i <= fcount; i = i + 1)
      if (equal(name, fname(1, i)) == YES) {
         fstat(i) = YES
         filarg = YES
         return
         }
   filarg = NO
   return
   end
#-t-  filarg                      472  local   12/04/80  15:29:43
#-h-  fsize                       300  local   12/04/80  15:29:43
 ## fsize - determine size of file in characters
 integer function fsize (name)
 
 character getch
 character c, name(ARB)
 integer open
 integer fd
 
 fd = open (name, READ)
 if (fd == ERR)
	fsize = ERR
 else
	{
	for (fsize=0; getch(c,fd) != EOF; fsize=fsize+1)
		;
	call close (fd)
	}
 return
 end
#-t-  fsize                       300  local   12/04/80  15:29:43
#-h-  fskip                       189  local   12/04/80  15:29:44
 ## fskip - skip n characters on file fd
 subroutine fskip (fd, n)
 
 character getch
 character c
 integer fd, i, n
 
 for (i=1; i<=n; i=i+1)
	if (getch(c,fd) == EOF)
		break
 return
 end
#-t-  fskip                       189  local   12/04/80  15:29:44
#-h-  getfns                     1096  local   12/04/80  15:29:44
 ## getfns - get file names into fname, check for duplicates
   subroutine getfns
 
   integer equal, getarg, getlin
   character junk(2)
   integer i, j, usein
   include carch
 
  data usein /NO/
   errcnt = 0
   for (i = 1; i <= MAXFILES; i = i + 1)
	{
	if (usein == NO)		#pick up files from arg list
		{
		if (getarg(i+2, fname(1,i), NAMESIZE) == EOF)
			break
		if (fname(1,i) == MINUS & fname(2,i) == EOS)
			usein = YES
		}
	if (usein == YES)
		{
		len = getlin(fname(1,i), STDIN)
		if (len == EOF)
			break
		fname(len,i) = EOS
		}
                    # fold file names to single case, if desired
      ifdef(FOLDF, call fold(fname(1,i)) )
	}
   fcount = i - 1
   if (i > MAXFILES)
      if (getarg(i+2, junk, 1) != 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)
      for (j = i + 1; j <= fcount; j = j + 1)
         if (equal(fname(1, i), fname(1, j)) == YES) {
            call putlin(fname(1, i), ERROUT)
            call error(': duplicate file name.')
            }
   return
   end
#-t-  getfns                     1096  local   12/04/80  15:29:44
#-h-  gethdr                      949  local   12/04/80  15:29:44
  ## 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
   integer fd, i, len, size, type
   string ohdr "-h-"
 
   include arhdr
 
 #***kluge since EOF isn't always sensed on an empty file
  if (new == YES)
	{
	gethdr = EOF
	return
	}
 
   if (getlin(buf, fd) == EOF) {
      gethdr = EOF
      return
      }
   ifdef(FOLDF,  call fold(buf) )
   i = 1
   len = getwrd(buf, i, temp)
   if ( (equal(temp,hdr) == NO) & (equal(temp,ohdr) == NO))
      call error('archive not in proper format.')
   gethdr = YES
   len = getwrd(buf, i, name)
   size = ctoi(buf, i)
   len = getwrd (buf, i+1, temp)
   if (len <= 0 | equal(temp,asc) == YES)
	type = ASCII
   else if (equal(temp, local) == YES)
	type = LOCAL
   else if (equal(temp, bin) == YES)
	type = BINARY
   else
	type = ASCII
   return
   end
#-t-  gethdr                      949  local   12/04/80  15:29:44
#-h-  getyp                       271  local   12/04/80  15:29:45
 ## getyp - determines type of file - ASCII, LOCAL, or BINARY
 #  (dummy version - reimplement if possible on your system)
 subroutine getyp(fd, typ)
 integer fd, typ
 typ = LOCAL
 ifdef(VAX_VMS,  call gettyp(fd, typ))
 ifdef(RSX_11M,  call gettyp(fd, typ))
 return
 end
#-t-  getyp                       271  local   12/04/80  15:29:45
#-h-  help                        190  local   12/04/80  15:29:45
  #---------------------------------------------------------------
 ## help - diagnostic printout
   subroutine help
 
   call error('usage: ar {dptuxsv} arcname [files].')
   return
   end
#-t-  help                        190  local   12/04/80  15:29:45
#-h-  makhdr                     1226  local   12/04/80  15:29:46
 ## makhdr - make header line for archive member
   subroutine makhdr(name, head, size, type)
   character head(MAXLINE), name(NAMESIZE), filsiz(MAXCHARS)
   integer now(7)
   character time(9), date(9)
   integer itoc, length, j, n
   integer size, i, type
  include arhdr
  include carch
 
   i = 1
   call stcopy(hdr, 1, head, i)		# store header flag
   head(i) = BLANK
   i = i + 1
   call stcopy(name, 1, head, i)	# store file name
   if (size == ERR)
	{
	junk = 0
	filsiz(1) = EOS
	errcnt = errcnt + 1
	}
   else
	junk = itoc(size, filsiz, MAXCHARS)
   n = TWOCOLWIDTH - junk - length(name)
   j = 1
   repeat
	{
	head(i) = BLANK
	i = i + 1
	j = j + 1
	}
   until (j > n)			# padded blanks, at least one
   call stcopy(filsiz, 1, head, i)	# copy size of file
  # insert file type
  head(i) = BLANK
  i = i + 1
  if (type == ASCII)
	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)
  head(i) = BLANK
  i = i + 1
  # insert time and date
   call getnow (now)
   call fmtdat (date, time, now, 0)
   call stcopy (date, 1, head, i)
   head(i) = BLANK
   i = i + 1
   call stcopy (time, 1, head, i)

 
  head(i) = NEWLINE
  head(i+1) = EOS
  ifdef(FOLDF, call fold(head) )
 
  return
  end
#-t-  makhdr                     1226  local   12/04/80  15:29:46
#-h-  notfnd                      371  local   12/04/80  15:29:47
 
  #---------------------------------------------------------------
 ## notfnd - print 'not found' message
   subroutine notfnd
 
   integer i
   include carch
 
   for (i = 1; i <= fcount; i = i + 1)
      if (fstat(i) == NO) {
         call putlin(fname(1, i), ERROUT)
         call remark(': not in archive.')
         errcnt = errcnt + 1
         }
   return
   end
#-t-  notfnd                      371  local   12/04/80  15:29:47
#-h-  nxtfl                       866  local   12/04/80  15:29:47
 ## nxtfl - extract next file from damaged archive
 integer function nxtfl(name, afd)
 character name(ARB), holdnm(FILENAMESIZE), buf(MAXLINE), temp(MAXLINE)
 integer create, getlin, equal, getwrd
 integer afd, i, int
 data holdnm(1) /EOS/
 
 include arhdr
 
 if (holdnm(1) == EOS)		#pick up first name
	{
	if (getlin(buf, afd) == EOF)
                return (EOF)
	i = 1
	len = getwrd(buf, i, temp)
	if (equal(temp, hdr) == 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)
	{
	i = 1
	len = getwrd(buf, i, temp)
	if (equal(temp, hdr) == YES)
		{
		len = getwrd(buf, i, holdnm)
		break
		}
	call putlin(buf, int)
	}
 
 call close(int)
 return (OK)
 end
#-t-  nxtfl                       866  local   12/04/80  15:29:47
#-h-  recovr                      755  local   12/04/80  15:29:48
## recovr - recover archived file with incorrect byte counts
 subroutine recovr (aname)
 
 integer create, open, nxtfl
 integer afd, tfd
 character aname(ARB), tfile(FILENAMESIZE), name(FILENAMESIZE)
 
 include carch
   string tname 'arctemp'
 
 #				open archive
 afd = open(aname, READ)
 if (afd == ERR)
	call cant(aname)
 #				open archive scratch file
 call mkuniq (tname, tfile)
 tfd = create(tfile, WRITE)
 if (tfd == ERR)
	call cant (tfile)
 #				loop through all files in archive

 while (nxtfl(name, afd) != EOF)
	{
	call addfil (name, tfd, errcnt)
	call remove (name)
	}
 
 call close(afd)
 call close(tfd)
 if (errcnt == 0)
	call amove (tfile, aname)
 else
	call remark ('fatal errors - archive not altered.')
 call remove (tfile)
 return
 end
#-t-  recovr                      755  local   12/04/80  15:29:48
#-h-  replac                      732  local   12/04/80  15:29:48
 
  #---------------------------------------------------------------
 ## replac - replace or delete files
   subroutine replac(afd, tfd, cmd, errct)
   character in(MAXLINE), uname(NAMESIZE)
   integer filarg, gethdr
   integer afd, cmd, errct, size, 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 (NEWLINE, STDOUT)
		}
         call fskip(afd, size)    # discard old one
         }
      else {
         call putlin(in, tfd)
         call acopy(afd, tfd, size)
         }
   return
   end
#-t-  replac                      732  local   12/04/80  15:29:48
#-h-  table                       505  local   12/04/80  15:29:49
 
  #---------------------------------------------------------------
 ## table - print table of archive contents
   subroutine table(aname)
   character aname(NAMESIZE), in(MAXLINE), lname(NAMESIZE)
   integer filarg, gethdr, open
   integer afd, size
 
   afd = open(aname, READ)
   if (afd == ERR)
      call cant(aname)
   while (gethdr(afd, in, lname, size, type) != EOF) {
      if (filarg(lname) == YES)
         call tprint(in)
      call fskip(afd, size)
      }
   call notfnd
   return
   end
 
#-t-  table                       505  local   12/04/80  15:29:49
#-h-  tprint                      484  local   12/04/80  15:29:49
 
  #---------------------------------------------------------------
 ## tprint - print table entry for one member
   subroutine tprint(buf)
   character buf(ARB)
   include carch
 
 
  #skip initial header flag
  for (i=1; buf(i) != BLANK; i=i+1) ;
 
  #print filename
  for (i=i+1; buf(i) != BLANK; i=i+1)
     call putch (buf(i), STDOUT)
 
  # print remainder of info
  if (verbos == YES)
     call putlin (buf(i), STDOUT)
  else
     call putch (NEWLINE, STDOUT)
   return
   end
#-t-  tprint                      484  local   12/04/80  15:29:49
#-h-  update                     1201  local   12/04/80  15:29:49
 
  #---------------------------------------------------------------
 ## update - update existing files, add new ones at end
   subroutine update(aname)
   character aname(NAMESIZE), tfile(FILENAMESIZE)
   integer create, getarg, open
   integer afd, i, tfd
   include carch
   include arhdr
    string tname 'arctemp'
 
   afd = open(aname, READ)
   if (afd == ERR)       # maybe it's a new one
   ###kluge 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
   # STDIN file slot being closed to save space
    call close(STDIN)
    call mkuniq(tname, tfile)		#get scratch file name
    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) {
         call addfil(fname(1, i), tfd, errcnt)
         fstat(i) = YES
         }
   call close(afd)
   call close(tfd)
   if (errcnt == 0)
      call amove(tfile, aname)
   else
      call remark('fatal errors - archive not altered.')
   call remove(tfile)
   return
   end
 
#-t-  update                     1201  local   12/04/80  15:29:49
#-t-  ar.r                      18216  local   12/10/80  14:07:33
#-t-  version2                  26233  local   12/10/80  14:08:39
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              