Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

initial commit

  • Loading branch information...
commit b9f37a0bd4536bb71c581cb0a5f33f5ae87f4f67 0 parents
mickey authored
Showing with 14,490 additions and 0 deletions.
  1. +37 −0 README
  2. +11 −0 ar/Makefile
  3. +144 −0 ar/append.c
  4. +360 −0 ar/ar.1
  5. +143 −0 ar/ar.5
  6. +264 −0 ar/ar.c
  7. +389 −0 ar/archive.c
  8. +122 −0 ar/archive.h
  9. +102 −0 ar/contents.c
  10. +106 −0 ar/delete.c
  11. +150 −0 ar/extract.c
  12. +140 −0 ar/misc.c
  13. +141 −0 ar/move.c
  14. +36 −0 ar/pathnames.h
  15. +100 −0 ar/print.c
  16. +94 −0 ar/ranlib.1
  17. +93 −0 ar/ranlib.5
  18. +561 −0 ar/ranlib.c
  19. +180 −0 ar/replace.c
  20. +22 −0 ld/Makefile
  21. +270 −0 ld/amd64.c
  22. +211 −0 ld/arm.c
  23. +402 −0 ld/hppa.c
  24. +229 −0 ld/i386.c
  25. +162 −0 ld/ld.1
  26. +1,059 −0 ld/ld.c
  27. +269 −0 ld/ld.h
  28. +1,511 −0 ld/ld2.c
  29. +346 −0 ld/syms.c
  30. +47 −0 libelf/Makefile
  31. +45 −0 libelf/checkoff.c
  32. +494 −0 libelf/elf.c
  33. +92 −0 libelf/elf_header.c
  34. +196 −0 libelf/elf_size.3
  35. +56 −0 libelf/elf_size.c
  36. +171 −0 libelf/elf_symload.c
  37. +97 −0 libelf/elfuncs.h
  38. +488 −0 mk/bsd.README
  39. +53 −0 mk/bsd.dep.mk
  40. +54 −0 mk/bsd.doc.mk
  41. +316 −0 mk/bsd.lib.mk
  42. +128 −0 mk/bsd.lkm.mk
  43. +178 −0 mk/bsd.man.mk
  44. +44 −0 mk/bsd.nls.mk
  45. +64 −0 mk/bsd.obj.mk
  46. +150 −0 mk/bsd.own.mk
  47. +163 −0 mk/bsd.prog.mk
  48. +111 −0 mk/bsd.regress.mk
  49. +85 −0 mk/bsd.subdir.mk
  50. +46 −0 mk/bsd.sys.mk
  51. +221 −0 mk/sys.mk
  52. +8 −0 nm/Makefile
  53. +106 −0 nm/byte.c
  54. +134 −0 nm/nm.1
  55. +1,136 −0 nm/nm.c
  56. +77 −0 nm/size.1
  57. +30 −0 nm/util.h
  58. +16 −0 readelf/Makefile
  59. +46 −0 readelf/readelf.1
  60. +521 −0 readelf/readelf.c
  61. +84 −0 readelf/readelf.h
  62. +341 −0 readelf/readelf2.c
  63. +7 −0 strings/Makefile
  64. +120 −0 strings/strings.1
  65. +357 −0 strings/strings.c
  66. +8 −0 strip/Makefile
  67. +79 −0 strip/strip.1
  68. +467 −0 strip/strip.c
37 README
@@ -0,0 +1,37 @@
+
+Here be a collection of developers tools except for the C compiler
+that one can haz a personal choice upon.
+All tools handle ELF and some do even a.out except for as(1) ld(1)
+and surprisingly readelf(1).
+
+They all depend upon libelf that provides very basic ELF pokery.
+
+Any one of these builds as is on any reasonable BSD system.
+Yer Kleenux milage may vary.
+Here are expected source locations:
+ /usr/src/share/mk
+ /usr/src/lib/libelf
+ /usr/src/bin/adb
+ /usr/src/usr.bin/ar
+ /usr/src/usr.bin/as
+ /usr/src/usr.bin/ld
+ /usr/src/usr.bin/nm
+ /usr/src/usr.bin/readelf
+ /usr/src/usr.bin/strings
+ /usr/src/usr.bin/strip
+Other dependancies include:
+ make(1) awk(1) sh(1) nroff(1) cp(1) ln(1) mkdir(1) libc(2/3)
+
+All proggies function correctly on almost any architecture.
+Any proggie can be compiled and used on any architecture to
+operate on any other architectures source or object files.
+The only machine-dependant pieces are in:
+ ld(1) for relocs and MD bits
+ as(1) obviously but see what is supported
+ adb(1) cannot run alien bins but can mock 'em aliens!
+ readelf(1) reloc types and MD bits
+
+See them manuals for more of them details.
+
+--
+ paranoic mickey (my employers have changed but, the name has remained)
11 ar/Makefile
@@ -0,0 +1,11 @@
+
+PROG= ar
+CPPFLAGS+=-I${.CURDIR} -I${.CURDIR}/../nm
+SRCS= append.c ar.c archive.c contents.c delete.c extract.c misc.c \
+ move.c print.c ranlib.c replace.c
+MAN= ar.1 ar.5 ranlib.1 ranlib.5
+LINKS= ${BINDIR}/ar ${BINDIR}/ranlib
+LDADD= -lelf
+DPADD= ${LIBELF}
+
+.include <bsd.prog.mk>
144 ar/append.c
@@ -0,0 +1,144 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)append.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: append.c,v 1.7 2011/02/03 23:24:38 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ar.h>
+#include <err.h>
+
+#include "archive.h"
+
+int mknametab(char **);
+
+char *nametab;
+
+/*
+ * append --
+ * Append files to the archive - modifies original archive or creates
+ * a new archive if named archive does not exist.
+ */
+int
+append(char **argv)
+{
+ struct stat sb;
+ CF cf;
+ FILE *afp;
+ char *file;
+ int eval, ntsz;
+
+ afp = open_archive(O_CREAT|O_RDWR);
+ if (fseeko(afp, 0, SEEK_END) == (off_t)-1)
+ err(1, "lseek: %s", archive);
+
+ /* Read from disk, write to an archive; pad on write. */
+ SETCF(0, 0, afp, archive, 0);
+
+ if (options & AR_C) {
+ /* ain't no need for a.out but a small price to pay */
+ if ((ntsz = mknametab(argv)) == 0)
+ ;
+
+ /* build and write the symdef, also need a mid! */
+ /* mkranlib(argv);
+ if (mid & ELF) */ {
+ options |= AR_S5;
+ /* write out the nametab */
+ if (ntsz)
+ put_nametab(&cf);
+ }
+ }
+
+ for (eval = 0; (file = *argv++);) {
+ if (!(cf.rfp = fopen(file, "r"))) {
+ warn("fopen: %s", file);
+ eval = 1;
+ continue;
+ }
+ if (options & AR_V)
+ (void)printf("q - %s\n", file);
+ cf.rname = file;
+ put_arobj(&cf, &sb);
+ (void)fclose(cf.rfp);
+ }
+ close_archive(afp);
+ return (eval);
+}
+
+int
+mknametab(char **argv)
+{
+ struct ar_hdr *hdr;
+ char **av, *p, *q;
+ int i, s, t;
+
+ /* first count the needed space */
+ for (t = 0, av = argv; *av; av++) {
+ q = strrchr(*av, '/');
+ q = q? q + 1 : *av;
+ if ((s = strlen(q)) >= sizeof(hdr->ar_name))
+ t += s + 2;
+ }
+
+ if (!t)
+ return 0;
+
+ if (!(nametab = malloc(t + 1)))
+ err(1, "malloc: nametab");
+
+ /* and now populate */
+ for (i = 0, av = argv, p = nametab; *av; av++) {
+ q = strrchr(*av, '/');
+ q = q? q + 1 : *av;
+ if ((s = strlen(q)) >= sizeof(hdr->ar_name)) {
+ snprintf(p, s + 3, "%s/\n", q);
+ p += s + 2;
+ }
+ }
+ *p = '\0';
+
+ return t;
+}
360 ar/ar.1
@@ -0,0 +1,360 @@
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" Hugh Smith at The University of Guelph.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ar.1 8.1 (Berkeley) 6/29/93
+.\"
+.Dd $Mdocdate: November 1 2009 $
+.Dt AR 1
+.Os
+.Sh NAME
+.Nm ar
+.Nd create and maintain library archives
+.Sh SYNOPSIS
+.Nm ar
+.Fl d
+.Op Fl sTv
+.Ar archive
+.Op Ar file ...
+.Nm ar
+.Fl m
+.Op Fl sTv
+.Ar archive
+.Op Ar file ...
+.Nm ar
+.Fl m
+.Op Fl abisTv
+.Ar position archive
+.Op Ar file ...
+.Nm ar
+.Fl p
+.Op Fl \Tv
+.Ar archive
+.Op Ar file ...
+.Nm ar
+.Fl q
+.Op Fl csTv
+.Ar archive
+.Op Ar file ...
+.Nm ar
+.Fl r
+.Op Fl cusTv
+.Ar archive
+.Op Ar file ...
+.Nm ar
+.Fl r
+.Op Fl abciusTv
+.Ar position archive
+.Op Ar file ...
+.Nm ar
+.Fl t
+.Op Fl \Tv
+.Ar archive
+.Op Ar file ...
+.Nm ar
+.Fl x
+.Op Fl CouTv
+.Ar archive
+.Op Ar file ...
+.Sh DESCRIPTION
+The
+.Nm
+utility creates and maintains groups of files combined into an archive.
+Once an archive has been created, new files can be added and existing
+files can be extracted, deleted, or replaced.
+.Pp
+Files are named in the archive by a single component; i.e., if a file
+referenced by a path containing a slash
+.Pq Ql /
+is archived it will be
+named by the last component of that path.
+When matching paths listed on the command line against file names stored
+in the archive, only the last component of the path will be compared.
+.Pp
+All informational and error messages use the path listed on the command
+line, if any was specified, otherwise the name in the archive is used.
+If multiple files in the archive have the same name, and paths are listed
+on the command line to
+.Dq select
+archive files for an operation, only the
+.Em first
+file with a matching name will be selected.
+.Pp
+The normal use of
+.Nm
+is for the creation and maintenance of libraries suitable for use with
+the loader (see
+.Xr ld 1 )
+although it is not restricted to this purpose.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl a
+A positioning modifier used with the options
+.Fl r
+and
+.Fl m .
+The files are entered or moved
+.Em after
+the archive member
+.Ar position ,
+which must be specified.
+.It Fl b
+A positioning modifier used with the options
+.Fl r
+and
+.Fl m .
+The files are entered or moved
+.Em before
+the archive member
+.Ar position ,
+which must be specified.
+.It Fl c
+Whenever an archive is created, an informational message to that effect
+is written to standard error.
+If the
+.Fl c
+option is specified,
+.Nm
+creates the archive silently.
+.It Fl C
+Prevent extracted files from replacing like-named files in the file system.
+.It Fl d
+Delete the specified archive files.
+.It Fl i
+Identical to the
+.Fl b
+option.
+.It Fl m
+Move the specified archive files within the archive.
+If one of the options
+.Fl a ,
+.Fl b ,
+or
+.Fl i
+are specified, the files are moved before or after the
+.Ar position
+file in the archive.
+If none of those options are specified, the files are moved
+to the end of the archive.
+.It Fl o
+Set the access and modification times of extracted files to the
+modification time of the file when it was entered into the archive.
+This will fail if the user is not the owner of the extracted file
+or the superuser.
+.It Fl p
+Write the contents of the specified archive files to the standard output.
+If no files are specified, the contents of all the files in the archive
+are written in the order they appear in the archive.
+.It Fl q
+(Quickly) append the specified files to the archive.
+If the archive does not exist a new archive file is created.
+Much faster than the
+.Fl r
+option, when creating a large archive
+piece-by-piece, as no checking is done to see if the files already
+exist in the archive.
+.It Fl r
+Replace or add the specified files to the archive.
+If the archive does not exist a new archive file is created.
+Files that replace existing files do not change the order of the files
+within the archive.
+New files are appended to the archive unless one of the options
+.Fl a ,
+.Fl b ,
+or
+.Fl i
+is specified.
+.It Fl s
+Update the archive index (only useful with
+.Fl d ,
+.Fl m ,
+.Fl q ,
+.Fl r
+flags).
+This is equivalent to running
+.Xr ranlib 1
+after the operation.
+For
+.Fl q
+this is faster than running
+.Xr ranlib 1
+afterwards as it avoids extra file copying and scanning.
+.It Fl T
+Select and/or name archive members using only the first fifteen characters
+of the archive member or command line file name.
+The historic archive format had sixteen bytes for the name, but some
+historic archiver and loader implementations were unable to handle names
+that used the entire space.
+This means that file names that are not unique in their first fifteen
+characters can subsequently be confused.
+A warning message is printed to the standard error if any file
+names are truncated.
+(See
+.Xr ar 5
+for more information.)
+.It Fl t
+List the specified files in the order in which they appear in the archive,
+each on a separate line.
+If no files are specified, all files in the archive are listed.
+.It Fl u
+Update files.
+When used with the
+.Fl r
+option, files in the archive will be replaced
+only if the disk file has a newer modification time than the file in
+the archive.
+When used with the
+.Fl x
+option, files in the archive will be extracted
+only if the archive file has a newer modification time than the file
+on disk.
+.It Fl v
+Provide verbose output.
+When used with the
+.Fl d ,
+.Fl m ,
+.Fl q ,
+or
+.Fl x
+options,
+.Nm
+gives a file-by-file description of the archive modification.
+This description consists of three, whitespace-separated fields: the
+option letter, a dash
+.Pq Ql - ,
+and the file name.
+When used with the
+.Fl r
+option,
+.Nm
+displays the description as above, but the initial letter is an
+.Sq a
+if
+the file is added to the archive and an
+.Sq r
+if the file replaces a file
+already in the archive.
+.Pp
+When used with the
+.Fl p
+option,
+the name of each printed file is written to the standard output before
+the contents of the file, preceded by a single newline character, and
+followed by two newline characters, enclosed in less-than
+.Pq Ql <
+and
+greater-than
+.Pq Ql >
+characters.
+.Pp
+When used with the
+.Fl t
+option,
+.Nm
+displays an
+.Dq ls -l
+style listing of information about the members of
+the archive.
+This listing consists of eight, whitespace-separated fields:
+the file permissions (see
+.Xr strmode 3 ) ,
+the decimal user and group IDs, separated by a single slash
+.Pq Ql / ,
+the file size (in bytes), the file modification time (in the
+.Xr date 1
+format
+.Dq %b %e %H:%M %Y ) ,
+and the name of the file.
+.It Fl x
+Extract the specified archive members into the files named by the command
+line arguments.
+If no members are specified, all the members of the archive are extracted into
+the current directory.
+.Pp
+If the file does not exist, it is created; if it does exist, the owner
+and group will be unchanged.
+The file access and modification times are the time of the extraction
+(but see the
+.Fl o
+option).
+The file permissions will be set to those of the file when it was entered
+into the archive; this will fail if the user is not the owner of the
+extracted file or the superuser.
+.El
+.Pp
+The
+.Nm
+utility exits 0 on success or >0 if an error occurred.
+.Sh ENVIRONMENT
+.Bl -tag -width indent -compact
+.It Ev TMPDIR
+The pathname of the directory to use when creating temporary files.
+.El
+.Sh FILES
+.Bl -tag -width ar.XXXXXXXXXX -compact
+.It Pa /tmp
+default temporary file directory
+.It Pa ar.XXXXXXXXXX
+temporary file names
+.El
+.Sh SEE ALSO
+.Xr ld 1 ,
+.Xr ranlib 1 ,
+.Xr strmode 3 ,
+.Xr ar 5
+.Sh STANDARDS
+By default,
+.Nm
+writes archives that may be incompatible with historic archives, as
+the format used for storing archive members with names longer than
+fifteen characters has changed.
+This implementation of
+.Nm
+is backward compatible with previous versions of
+.Nm
+in that it can read and write (using the
+.Fl T
+option) historic archives.
+The
+.Fl T
+option is provided for compatibility only, and will be deleted
+in a future release.
+See
+.Xr ar 5
+for more information.
+.Pp
+The
+.Nm
+utility is expected to offer a superset of the
+.St -p1003.2
+functionality.
+.Sh BUGS
+Not all operations support newer name table format.
143 ar/ar.5
@@ -0,0 +1,143 @@
+.\"
+.\" Copyright (c) 1990, 1991, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)ar.5.5 8.1 (Berkeley) 6/9/93
+.\"
+.Dd $Mdocdate: April 3 2009 $
+.Dt AR 5
+.Os
+.Sh NAME
+.Nm ar
+.Nd archive (library) file format
+.Sh SYNOPSIS
+.Fd #include <ar.h>
+.Sh DESCRIPTION
+The archive command
+.Nm ar
+combines several files into one.
+Archives are mainly used as libraries of object files intended to be
+loaded using the link-editor
+.Xr ld 1 .
+.Pp
+A file created with
+.Nm ar
+begins with the ``magic'' string "!<arch>\en".
+The rest of the archive is made up of objects, each of which is composed
+of a header for a file, a possible file name, and the file contents.
+The header is portable between machine architectures, and, if the file
+contents are printable, the archive is itself printable.
+.Pp
+The header is made up of six variable length
+.Tn ASCII
+fields, followed by a
+two character trailer.
+The fields are the object name (16 characters), the file last modification
+time (12 characters), the user and group IDs (each 6 characters), the file
+mode (8 characters) and the file size (10 characters).
+All numeric fields are in decimal, except for the file mode which is in
+octal.
+.Pp
+The modification time is the file
+.Fa st_mtime
+field, i.e.,
+.Dv CUT
+seconds since
+the Epoch.
+The user and group IDs are the file
+.Fa st_uid
+and
+.Fa st_gid
+fields.
+The file mode is the file
+.Fa st_mode
+field.
+The file size is the file
+.Fa st_size
+field.
+The two-byte trailer is the string "\`\en".
+.Pp
+Only the name field has any provision for overflow.
+If any file name is more than 16 characters in length or contains an
+embedded space, the string "#1/" followed by the
+.Tn ASCII
+length of the
+name is written in the name field.
+The file size (stored in the archive header) is incremented by the length
+of the name.
+The name is then written immediately following the archive header.
+.Pp
+Any unused characters in any of these fields are written as space
+characters.
+If any fields are their particular maximum number of characters in
+length, there will be no separation between the fields.
+.Pp
+Objects in the archive are always an even number of bytes long; files
+which are an odd number of bytes long are padded with a newline (`\en')
+character, although the size in the header does not reflect this.
+.Sh SEE ALSO
+.Xr ar 1 ,
+.Xr stat 2
+.Sh STANDARDS
+No archive format is currently specified by any standard.
+.At V
+has historically distributed archives in a different format from
+all of the above.
+.Sh HISTORY
+There have been at least four
+.Nm ar
+formats.
+The first was denoted by the leading ``magic'' number 0177555 (stored as
+type int).
+These archives were almost certainly created on a 16-bit machine, and
+contain headers made up of five fields.
+The fields are the object name (8 characters), the file last modification
+time (type long), the user ID (type char), the file mode (type char) and
+the file size (type unsigned int).
+Files were padded to an even number of bytes.
+.Pp
+The second was denoted by the leading ``magic'' number 0177545 (stored as
+type int).
+These archives may have been created on either 16 or 32-bit machines, and
+contain headers made up of six fields.
+The fields are the object name (14 characters), the file last modification
+time (type long), the user and group IDs (each type char), the file mode
+(type int) and the file size (type long).
+Files were padded to an even number of bytes.
+.\" For more information on converting from this format see
+.\" .Xr arcv 8 .
+.Pp
+The current archive format (without support for long character names and
+names with embedded spaces) was introduced in
+.Bx 4.0 .
+The headers were the same as the current format, with the exception that
+names longer than 16 characters were truncated, and names with embedded
+spaces (and often trailing spaces) were not supported.
+It has been extended for these reasons,
+as described above.
+This format first appeared in
+.Bx 4.4 .
264 ar/ar.c
@@ -0,0 +1,264 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char copyright[] =
+"@(#) Copyright (c) 2009 Michael Shalayeff. All rights reserved.\n"
+"@(#) Copyright (c) 1990, 1993, 1994\n"
+ "\tThe Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)ar.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: ar.c,v 1.8 2010/06/18 11:24:36 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+#include <ar.h>
+#include <dirent.h>
+#include <err.h>
+
+#include "archive.h"
+
+CHDR chdr;
+u_int options;
+
+const char *archive, *envtmp, *posarg;
+const char *posname;
+void badoptions(char *);
+void usage(void);
+
+/*
+ * main --
+ * main basically uses getopt to parse options and calls the appropriate
+ * functions. Some hacks that let us be backward compatible with 4.3 ar
+ * option parsing and sanity checking.
+ */
+int
+main(int argc, char *argv[])
+{
+ extern char *__progname;
+ int c;
+ char *p;
+ int (*fcall)(char **);
+
+ fcall = NULL;
+ if (strcmp(__progname, "ranlib") == 0) {
+ if (argc < 2)
+ usage();
+
+ options |= AR_S;
+ while ((c = getopt(argc, argv, "t")) != -1)
+ switch(c) {
+ case 't':
+ options |= AR_T;
+ break;
+ default:
+ usage();
+ }
+ } else {
+ if (argc < 3)
+ usage();
+
+ /*
+ * Historic versions didn't require a '-' in front of the
+ * options. Fix it, if necessary.
+ */
+ if (*argv[1] != '-') {
+ size_t len;
+
+ len = (u_int)(strlen(argv[1]) + 2);
+ if (!(p = malloc(len)))
+ err(1, NULL);
+ *p = '-';
+ (void)strlcpy(p + 1, argv[1], len - 1);
+ argv[1] = p;
+ }
+ while ((c = getopt(argc, argv, "abcCdilmopqrsTtuvx")) != -1)
+ switch(c) {
+ case 'a':
+ options |= AR_A;
+ break;
+ case 'b':
+ case 'i':
+ options |= AR_B;
+ break;
+ case 'c':
+ options |= AR_C;
+ break;
+ case 'C':
+ options |= AR_CC;
+ break;
+ case 'd':
+ options |= AR_D;
+ fcall = delete;
+ break;
+ case 'l':
+ /*
+ * "local" tmp-files option;
+ * ignored for compatibility
+ */
+ break;
+ case 'm':
+ options |= AR_M;
+ fcall = move;
+ break;
+ case 'o':
+ options |= AR_O;
+ break;
+ case 'p':
+ options |= AR_P;
+ fcall = print;
+ break;
+ case 'q':
+ /* TODO optimise symdef generation for -c */
+ options |= AR_Q;
+ fcall = append;
+ break;
+ case 'r':
+ options |= AR_R;
+ fcall = replace;
+ break;
+ case 's':
+ options |= AR_S;
+ break;
+ case 'T':
+ options |= AR_TR;
+ break;
+ case 't':
+ options |= AR_T;
+ fcall = contents;
+ break;
+ case 'u':
+ options |= AR_U;
+ break;
+ case 'v':
+ options |= AR_V;
+ break;
+ case 'x':
+ options |= AR_X;
+ fcall = extract;
+ break;
+ default:
+ usage();
+ }
+ }
+
+ argv += optind;
+ argc -= optind;
+
+ /* single -s is a ranlib for the ar files given */
+ if (fcall == NULL && (options & AR_S))
+ exit(ranlib(argv));
+
+ /* One of -dmpqrtx required. */
+ if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_T|AR_X))) {
+ warnx("one of options -dmpqrtx is required");
+ usage();
+ }
+ /* Only one of -a and -bi allowed. */
+ if (options & AR_A && options & AR_B) {
+ warnx("only one of -a and -[bi] options allowed");
+ usage();
+ }
+ /* -ab require a position argument. */
+ if (options & (AR_A|AR_B)) {
+ if (!(posarg = *argv++)) {
+ warnx("no position operand specified");
+ usage();
+ }
+ posname = rname(posarg);
+ }
+ /* -d only valid with -sTv. */
+ if (options & AR_D && options & ~(AR_D|AR_TR|AR_S|AR_V))
+ badoptions("-d");
+ /* -m only valid with -abiTsv. */
+ if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_TR|AR_S|AR_V))
+ badoptions("-m");
+ /* -p only valid with -Tv. */
+ if (options & AR_P && options & ~(AR_P|AR_TR|AR_V))
+ badoptions("-p");
+ /* -q only valid with -csTv. */
+ if (options & AR_Q && options & ~(AR_C|AR_Q|AR_TR|AR_S|AR_V))
+ badoptions("-q");
+ /* -r only valid with -abcuTsv. */
+ if (options & AR_R &&
+ options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_TR|AR_S|AR_V))
+ badoptions("-r");
+ /* -t only valid with -Tv. */
+ if (options & AR_T && options & ~(AR_T|AR_TR|AR_V))
+ badoptions("-t");
+ /* -x only valid with -CouTv. */
+ if (options & AR_X && options & ~(AR_O|AR_U|AR_TR|AR_V|AR_X|AR_CC))
+ badoptions("-x");
+
+ if (!(archive = *argv++)) {
+ warnx("no archive specified");
+ usage();
+ }
+
+ exit((*fcall)(argv));
+}
+
+void
+badoptions(char *arg)
+{
+
+ warnx("illegal option combination for %s", arg);
+ usage();
+}
+
+void
+usage(void)
+{
+
+ fprintf(stderr, "usage: ar -d [-sTv] archive file ...\n"
+ "\tar -m [-sTv] archive file ...\n"
+ "\tar -m [-abisTv] position archive file ...\n"
+ "\tar -p [-Tv] archive [file ...]\n"
+ "\tar -q [-csTv] archive file ...\n"
+ "\tar -r [-cusTv] archive file ...\n"
+ "\tar -r [-abciusTv] position archive file ...\n"
+ "\tar -t [-Tv] archive [file ...]\n"
+ "\tar -x [-CouTv] archive [file ...]\n"
+ "\tranlib [-t] archive ...\n");
+ exit(1);
+}
389 ar/archive.c
@@ -0,0 +1,389 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)archive.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: archive.c,v 1.12 2011/02/07 13:45:41 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ar.h>
+#include <dirent.h>
+#include <errno.h>
+#include <err.h>
+
+#include "archive.h"
+
+typedef struct ar_hdr HDR;
+static char hb[sizeof(HDR) + 1]; /* real header */
+
+FILE *
+open_archive(int mode)
+{
+ FILE *fp;
+ int created, fd, nr;
+ char buf[SARMAG];
+
+ fd = -1;
+ created = 0;
+ if (mode & O_CREAT) {
+ mode |= O_EXCL;
+ if ((fd = open(archive, mode, DEFFILEMODE)) >= 0) {
+ /* POSIX.2 puts create message on stderr. */
+ if (!(options & AR_C))
+ warnx("creating archive %s", archive);
+ created = 1;
+ } else {
+ if (errno != EEXIST)
+ err(1, "open: %s", archive);
+ mode &= ~O_EXCL;
+ }
+ }
+
+ if (fd < 0 && (fd = open(archive, mode, DEFFILEMODE)) < 0)
+ err(1, "open: %s", archive);
+
+ /*
+ * Attempt to place a lock on the opened file - if we get an
+ * error then someone is already working on this library (or
+ * it's going across NFS).
+ */
+ if (flock(fd, LOCK_EX|LOCK_NB) && errno != EOPNOTSUPP)
+ err(1, "flock: %s", archive);
+
+ fp = fdopen(fd, mode & O_RDWR? "r+" : "r");
+
+ /*
+ * If not created, O_RDONLY|O_RDWR indicates that it has to be
+ * in archive format.
+ */
+ if (!created &&
+ ((mode & O_ACCMODE) == O_RDONLY || (mode & O_ACCMODE) == O_RDWR)) {
+ if (fread(buf, SARMAG, 1, fp) != 1)
+ err(1, "fread: %s", archive);
+ else if (bcmp(buf, ARMAG, SARMAG))
+ badfmt();
+ } else if (fwrite(ARMAG, SARMAG, 1, fp) != 1)
+ err(1, "fwrite: %s", archive);
+
+ return (fp);
+}
+
+void
+close_archive(FILE *fp)
+{
+ fclose(fp); /* Implicit unlock. */
+}
+
+/* Convert ar header field to an integer. */
+#define AR_ATOI(from, to, len, base) { \
+ memmove(buf, from, len); \
+ buf[len] = '\0'; \
+ to = strtol(buf, NULL, base); \
+}
+
+/*
+ * get_arobj --
+ * read the archive header for this member
+ */
+int
+get_arobj(FILE *fp)
+{
+ struct ar_hdr *hdr;
+ int i, len, nr;
+ char *p, *q, buf[20];
+
+ nr = fread(hb, sizeof(HDR), 1, fp);
+ if (nr != 1) {
+ if (feof(fp))
+ return (0);
+ if (ferror(fp))
+ err(1, "fread: %s", archive);
+ badfmt();
+ }
+
+ hdr = (struct ar_hdr *)hb;
+ if (strncmp(hdr->ar_fmag, ARFMAG, sizeof(ARFMAG) - 1))
+ badfmt();
+
+ /* Convert the header into the internal format. */
+#define DECIMAL 10
+#define OCTAL 8
+
+ AR_ATOI(hdr->ar_date, chdr.date, sizeof(hdr->ar_date), DECIMAL);
+ AR_ATOI(hdr->ar_uid, chdr.uid, sizeof(hdr->ar_uid), DECIMAL);
+ AR_ATOI(hdr->ar_gid, chdr.gid, sizeof(hdr->ar_gid), DECIMAL);
+ AR_ATOI(hdr->ar_mode, chdr.mode, sizeof(hdr->ar_mode), OCTAL);
+ AR_ATOI(hdr->ar_size, chdr.size, sizeof(hdr->ar_size), DECIMAL);
+
+ /* Leading spaces should never happen. */
+ if (hdr->ar_name[0] == ' ')
+ badfmt();
+
+ /*
+ * Long name support. Set the "real" size of the file, and the
+ * long name flag/size.
+ */
+ if (!bcmp(hdr->ar_name, AR_EFMT1, sizeof(AR_EFMT1) - 1)) {
+ chdr.lname = len = atoi(hdr->ar_name + sizeof(AR_EFMT1) - 1);
+ if (len <= 0 || len > MAXNAMLEN)
+ badfmt();
+ if (fread(chdr.name, len, 1, fp) != 1) {
+ if (ferror(fp))
+ err(1, "fread: %s", archive);
+ badfmt();
+ }
+ chdr.name[len] = 0;
+ chdr.size -= len;
+ } else if (hdr->ar_name[0] == '/' && isdigit(hdr->ar_name[1])) {
+ i = atol(&hdr->ar_name[1]);
+ /* XXX check overflow */
+ chdr.lname = 0;
+ for (p = chdr.name, q = &nametab[i]; *q != '/'; )
+ *p++ = *q++;
+ *p = '\0';
+ } else {
+ chdr.lname = 0;
+ memmove(chdr.name, hdr->ar_name, sizeof(hdr->ar_name));
+
+ /* Strip trailing spaces, null terminate. */
+ for (p = chdr.name + sizeof(hdr->ar_name) - 1; *p == ' '; --p);
+ if (p > chdr.name + 1 && *p == '/')
+ p--;
+ p[1] = '\0';
+ }
+
+ return (1);
+}
+
+static int already_written;
+
+/*
+ * put_arobj --
+ * Write an archive member to a file.
+ */
+void
+put_arobj(CF *cfp, struct stat *sb)
+{
+ off_t size;
+ const char *name;
+ struct ar_hdr *hdr;
+ int lname;
+ uid_t uid;
+ gid_t gid;
+
+ /*
+ * If passed an sb structure, reading a file from disk. Get stat(2)
+ * information, build a name and construct a header. (Files are named
+ * by their last component in the archive.) If not, then just write
+ * the last header read.
+ */
+ if (sb) {
+ name = rname(cfp->rname);
+ (void)fstat(fileno(cfp->rfp), sb);
+
+ /*
+ * If not truncating names and the name is too long or contains
+ * a space, use extended format 1 or 2 (.
+ */
+ lname = strlen(name);
+ uid = sb->st_uid;
+ gid = sb->st_gid;
+ if (uid > USHRT_MAX) {
+ warnx("warning: uid %u truncated to %u", uid,
+ USHRT_MAX);
+ uid = USHRT_MAX;
+ }
+ if (gid > USHRT_MAX) {
+ warnx("warning: gid %u truncated to %u", gid,
+ USHRT_MAX);
+ gid = USHRT_MAX;
+ }
+ if (options & AR_TR) {
+ if (lname > OLDARMAXNAME) {
+ (void)fflush(stdout);
+ warnx("warning: file name %s truncated to %.*s",
+ name, OLDARMAXNAME, name);
+ (void)fflush(stderr);
+ }
+ (void)snprintf(hb, sizeof hb,
+ HDR3, name, (long int)sb->st_mtimespec.tv_sec,
+ uid, gid, sb->st_mode, sb->st_size, ARFMAG);
+ lname = 0;
+ } else if (lname >= sizeof(hdr->ar_name) || strchr(name, ' ')) {
+ if (options & AR_S5) {
+ char *p = strstr(nametab, name);
+
+ if (!p || p[lname] != '/' ||
+ (p != nametab && p[-1] != '\n'))
+ errx(1, "corrupt nametab");
+
+ (void)snprintf(hb, sizeof hb, HDR0, p - nametab,
+ (long)sb->st_mtimespec.tv_sec, uid, gid,
+ sb->st_mode, sb->st_size, ARFMAG);
+
+ /* prevent BSD4.4 name prependition */
+ lname = 0;
+ } else
+ (void)snprintf(hb, sizeof hb, HDR1, AR_EFMT1,
+ lname, (long)sb->st_mtimespec.tv_sec,
+ uid, gid, sb->st_mode,
+ sb->st_size + lname, ARFMAG);
+ } else {
+ lname = 0;
+ (void)snprintf(hb, sizeof hb,
+ HDR2, name, (long int)sb->st_mtimespec.tv_sec,
+ uid, gid, sb->st_mode, sb->st_size, ARFMAG);
+ }
+ size = sb->st_size;
+ } else {
+ lname = chdr.lname;
+ name = chdr.name;
+ size = chdr.size;
+ }
+
+ if (fwrite(hb, sizeof(HDR), 1, cfp->wfp) != 1)
+ err(1, "fwrite: %s", cfp->wname);
+ if (lname) {
+ if (fwrite(name, lname, 1, cfp->wfp) != 1)
+ err(1, "fwrite: %s", cfp->wname);
+ already_written = lname;
+ }
+ copy_ar(cfp, size);
+ already_written = 0;
+}
+
+int
+get_namtab(FILE *afp)
+{
+ if (!(nametab = malloc(chdr.size + 1)))
+ err(1, "%s: alloc nametab", archive);
+
+ if (fread(nametab, chdr.size, 1, afp) != 1)
+ err(1, "%s: read nametab", archive);
+ nametab[chdr.size] = '\0';
+ if (nametab[chdr.size - 1] == '\n')
+ nametab[chdr.size - 1] = '\0';
+}
+
+int
+put_nametab(CF *cfp)
+{
+ size_t sz;
+ char pad = 0;
+
+ if (!nametab)
+ return 0;
+
+ if ((sz = strlen(nametab)) & 1) {
+ sz++;
+ pad = '\n';
+ }
+ (void)snprintf(hb, sizeof hb,
+ HDR4, AR_NAMTAB, "", "", "", "", (quad_t)sz, ARFMAG);
+
+ if (fwrite(hb, sizeof(HDR), 1, cfp->wfp) != 1)
+ err(1, "write: %s", cfp->wname);
+
+ if (pad)
+ sz--;
+ if (fwrite(nametab, sz, 1, cfp->wfp) != 1)
+ err(1, "write: %s", cfp->wname);
+
+ if (pad && fwrite(&pad, 1, 1, cfp->wfp) != 1)
+ err(1, "fwrite: %s", cfp->wname);
+
+ return 0;
+}
+
+/*
+ * copy_ar --
+ * Copy size bytes from one file to another - taking care to handle the
+ * extra byte (for odd size files) when reading archives and writing an
+ * extra byte if necessary when adding files to archive. The length of
+ * the object is the long name plus the object itself; the variable
+ * already_written gets set if a long name was written.
+ */
+void
+copy_ar(CF *cfp, off_t size)
+{
+ char buf[MAXBSIZE], pad = 0;
+ off_t sz;
+ int nr, nw, off;
+
+ if (!(sz = size))
+ return;
+
+ while (sz && (nr = fread(buf, 1, MIN(sz, sizeof buf), cfp->rfp)) > 0) {
+ sz -= nr;
+ for (off = 0; off < nr; nr -= off, off += nw)
+ if ((nw = fwrite(buf + off, 1, nr, cfp->wfp)) <= 0)
+ err(1, "fwrite: %s", cfp->wname);
+ }
+ if (sz) {
+ if (nr == 0)
+ badfmt();
+ err(1, "fread: %s", cfp->rname);
+ }
+ if ((size & 1)) {
+ if (fwrite(&pad, 1, 1, cfp->wfp) <= 0)
+ err(1, "fwrite: %s", cfp->wname);
+ if (fseek(cfp->rfp, 1, SEEK_CUR) < 0)
+ err(1, "fseek: %s", cfp->rname);
+ }
+}
+
+/*
+ * skip_arobj -
+ * Skip over an object -- taking care to skip the pad bytes.
+ */
+off_t
+skip_arobj(FILE *fp)
+{
+ int pad;
+
+ pad = chdr.size & 1;
+ if (fseeko(fp, chdr.size + pad, SEEK_CUR) == -1)
+ err(1, "fseeko: %s", archive);
+
+ return chdr.size + pad + sizeof(struct ar_hdr);
+}
122 ar/archive.h
@@ -0,0 +1,122 @@
+/*-
+ * Copyright (c) 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)archive.h 8.3 (Berkeley) 4/2/94
+ * @(#)extern.h 8.3 (Berkeley) 4/2/94
+ */
+
+/* Ar(1) options. */
+#define AR_A 0x00001
+#define AR_B 0x00002
+#define AR_C 0x00004
+#define AR_D 0x00008
+#define AR_M 0x00010
+#define AR_O 0x00020
+#define AR_P 0x00040
+#define AR_Q 0x00080
+#define AR_R 0x00100
+#define AR_S 0x00200
+#define AR_T 0x00400
+#define AR_TR 0x00800
+#define AR_U 0x01000
+#define AR_V 0x02000
+#define AR_X 0x04000
+#define AR_CC 0x08000
+#define AR_S5 0x10000
+extern u_int options;
+
+/* Set up file copy. */
+#define SETCF(from, fromname, to, toname, pad) { \
+ cf.rfp = from; \
+ cf.rname = fromname; \
+ cf.wfp = to; \
+ cf.wname = toname; \
+}
+
+/* File copy structure. */
+typedef struct {
+ FILE *rfp; /* read file descriptor */
+ const char *rname; /* read name */
+ FILE *wfp; /* write file descriptor */
+ const char *wname; /* write name */
+} CF;
+
+/* Header structure internal format. */
+typedef struct {
+ off_t size; /* size of the object in bytes */
+ time_t date; /* date */
+ int lname; /* size of the long name in bytes */
+ gid_t gid; /* group */
+ uid_t uid; /* owner */
+ u_short mode; /* permissions */
+ char name[MAXNAMLEN + 1]; /* name */
+} CHDR;
+
+/* Header format strings. */
+#define HDR0 "/%-15td%-12ld%-6u%-6u%-8o%-10qd%2s"
+#define HDR1 "%s/%-13d%-12ld%-6u%-6u%-8o%-10qd%2s"
+#define HDR2 "%-16.16s%-12ld%-6u%-6u%-8o%-10qd%2s"
+
+#define OLDARMAXNAME 15
+#define HDR3 "%-16.15s%-12ld%-6u%-6u%-8o%-10qd%2s"
+#define HDR4 "%-16.16s%-12s%-6s%-6s%-8s%-10qd%2s"
+
+struct stat;
+
+FILE *open_archive(int);
+void close_archive(FILE *);
+void copy_ar(CF *, off_t);
+int get_arobj(FILE *);
+void put_arobj(CF *, struct stat *);
+int get_namtab(FILE *);
+int put_nametab(CF *);
+off_t skip_arobj(FILE *);
+
+int append(char **);
+void badfmt(void);
+int compare(const char *);
+int contents(char **);
+int delete(char **);
+int extract(char **);
+char *files(char **argv);
+int move(char **);
+void orphans(char **argv);
+int print(char **);
+int replace(char **);
+const char *rname(const char *);
+FILE *tmp(void);
+int ranlib(char **);
+
+extern const char *archive;
+extern const char *posarg, *posname; /* positioning file name */
+extern const char tname[]; /* temporary file "name" */
+extern CHDR chdr; /* converted header */
+extern char *nametab; /* long name table */
102 ar/contents.c
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)contents.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: contents.c,v 1.4 2009/05/26 20:39:07 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <ar.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <tzfile.h>
+#include <unistd.h>
+
+#include "archive.h"
+
+/*
+ * contents --
+ * Handles t[v] option - opens the archive and then reads headers,
+ * skipping member contents.
+ */
+int
+contents(char **argv)
+{
+ off_t size;
+ FILE *afp;
+ struct tm *tp;
+ char *file, buf[25];
+ int all;
+
+ afp = open_archive(O_RDONLY);
+ for (all = !*argv; get_arobj(afp); skip_arobj(afp)) {
+ if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
+ size = ftello(afp);
+ get_namtab(afp);
+ (void)fseeko(afp, size, SEEK_SET);
+ continue;
+ }
+
+ if (all)
+ file = chdr.name;
+ else if (!(file = files(argv)))
+ continue;
+ if (options & AR_V) {
+ (void)strmode(chdr.mode, buf);
+ (void)printf("%s %6d/%-6d %8qd ",
+ buf + 1, chdr.uid, chdr.gid, chdr.size);
+ tp = localtime(&chdr.date);
+ (void)strftime(buf, sizeof(buf), "%b %e %H:%M %Y", tp);
+ (void)printf("%s %s\n", buf, file);
+ } else
+ (void)printf("%s\n", file);
+ if (!all && !*argv)
+ break;
+ }
+ close_archive(afp);
+
+ if (*argv) {
+ orphans(argv);
+ return (1);
+ }
+ return (0);
+}
106 ar/delete.c
@@ -0,0 +1,106 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)delete.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: delete.c,v 1.6 2011/01/31 13:33:06 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ar.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "archive.h"
+#include "pathnames.h"
+
+/*-
+ * delete --
+ * Deletes named members from the archive.
+ */
+int
+delete(char **argv)
+{
+ CF cf;
+ off_t size;
+ FILE *afp, *tfp;
+ char *file;
+
+ afp = open_archive(O_RDWR);
+ tfp = tmp();
+
+ /* Read and write to an archive; pad on both. */
+ SETCF(afp, archive, tfp, tname, 0);
+ while (get_arobj(afp)) {
+ if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
+ size = ftello(afp);
+ get_namtab(afp);
+ (void)fseeko(afp, size, SEEK_SET);
+ skip_arobj(afp);
+ continue;
+ }
+
+ if (*argv && (file = files(argv))) {
+ if (options & AR_V)
+ (void)printf("d - %s\n", file);
+ skip_arobj(afp);
+ continue;
+ }
+ put_arobj(&cf, NULL);
+ }
+
+ /* TODO update nametab */
+
+ size = ftello(tfp);
+ rewind(tfp);
+ (void)fseeko(afp, SARMAG, SEEK_SET);
+ SETCF(tfp, tname, afp, archive, NOPAD);
+ copy_ar(&cf, size);
+ (void)fclose(tfp);
+ fflush(afp);
+ (void)ftruncate(fileno(afp), size + SARMAG);
+ close_archive(afp);
+
+ if (*argv) {
+ orphans(argv);
+ return (1);
+ }
+ return (0);
+}
150 ar/extract.c
@@ -0,0 +1,150 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)extract.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: extract.c,v 1.5 2011/01/31 13:33:06 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ar.h>
+
+#include "archive.h"
+
+/*
+ * extract --
+ * Extract files from the named archive - if member names given only
+ * extract those members otherwise extract all members. If 'o' option
+ * selected modify date of newly created file to be same as archive
+ * members date otherwise date is time of extraction. Does not modify
+ * archive.
+ */
+int
+extract(char **argv)
+{
+ struct timeval tv[2];
+ struct stat sb;
+ CF cf;
+ off_t size;
+ FILE *afp;
+ char *file;
+ int all, eval, tfd;
+
+ eval = 0;
+ tv[0].tv_usec = tv[1].tv_usec = 0;
+
+ afp = open_archive(O_RDONLY);
+
+ /* Read from an archive, write to disk; pad on read. */
+ SETCF(afp, archive, 0, 0, 0);
+ for (all = !*argv; get_arobj(afp);) {
+ if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
+ size = ftello(afp);
+ get_namtab(afp);
+ (void)fseeko(afp, size, SEEK_SET);
+ skip_arobj(afp);
+ continue;
+ }
+
+ if (all)
+ file = chdr.name;
+ else if (!(file = files(argv))) {
+ skip_arobj(afp);
+ continue;
+ }
+
+ if (options & AR_U && !stat(file, &sb) &&
+ sb.st_mtime > chdr.date)
+ continue;
+
+ if (options & AR_CC) {
+ /* -C means do not overwrite existing files */
+ if ((tfd = open(file, O_WRONLY|O_CREAT|O_EXCL,
+ S_IWUSR)) < 0) {
+ skip_arobj(afp);
+ eval = 1;
+ continue;
+ }
+ } else {
+ if ((tfd = open(file, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IWUSR)) < 0) {
+ warn("open: %s", file);
+ skip_arobj(afp);
+ eval = 1;
+ continue;
+ }
+ }
+
+ if (options & AR_V)
+ (void)printf("x - %s\n", file);
+
+ if (!(cf.wfp = fdopen(tfd, "w")))
+ err(1, "fdopen: %s", file);
+ cf.wname = file;
+ copy_ar(&cf, chdr.size);
+
+ if (fchmod(tfd, (mode_t)chdr.mode)) {
+ warn("chmod: %s", file);
+ eval = 1;
+ }
+ if (options & AR_O) {
+ tv[0].tv_sec = tv[1].tv_sec = chdr.date;
+ if (futimes(tfd, tv)) {
+ warn("utimes: %s", file);
+ eval = 1;
+ }
+ }
+ (void)fclose(cf.wfp);
+ if (!all && !*argv)
+ break;
+ }
+ close_archive(afp);
+
+ if (*argv) {
+ orphans(argv);
+ return (1);
+ }
+ return (0);
+}
140 ar/misc.c
@@ -0,0 +1,140 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)misc.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: misc.c,v 1.4 2009/05/26 20:39:07 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <paths.h>
+
+#include "archive.h"
+#include "pathnames.h"
+
+const char tname[] = "temporary file"; /* temporary file "name" */
+
+FILE *
+tmp(void)
+{
+ extern char *envtmp;
+ char path[MAXPATHLEN];
+ FILE *fp;
+ sigset_t set, oset;
+ int fd;
+
+ if (!envtmp && !(envtmp = getenv("TMPDIR")))
+ envtmp = _PATH_TMP;
+
+ if (envtmp)
+ (void)snprintf(path, sizeof(path), "%s/%s", envtmp,
+ _NAME_ARTMP);
+ else
+ strlcpy(path, _PATH_ARTMP, sizeof(path));
+
+ sigfillset(&set);
+ (void)sigprocmask(SIG_BLOCK, &set, &oset);
+ if ((fd = mkstemp(path)) == -1)
+ err(1, "mkstemp: %s", tname);
+ (void)unlink(path);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
+
+ if (!(fp = fdopen(fd, "r+")))
+ err(1, "fdopen: %s", tname);
+ return (fp);
+}
+
+/*
+ * files --
+ * See if the current file matches any file in the argument list; if it
+ * does, remove it from the argument list.
+ */
+char *
+files(char **argv)
+{
+ char **list, *p;
+
+ for (list = argv; *list; ++list)
+ if (compare(*list)) {
+ p = *list;
+ for (; (list[0] = list[1]); ++list)
+ continue;
+ return (p);
+ }
+ return (NULL);
+}
+
+void
+orphans(char **argv)
+{
+
+ for (; *argv; ++argv)
+ warnx("%s: not found in archive", *argv);
+}
+
+const char *
+rname(const char *path)
+{
+ const char *ind;
+
+ return ((ind = strrchr(path, '/')) ? ind + 1 : path);
+}
+
+int
+compare(const char *dest)
+{
+
+ if (options & AR_TR)
+ return (!strncmp(chdr.name, rname(dest), OLDARMAXNAME));
+ return (!strcmp(chdr.name, rname(dest)));
+}
+
+void
+badfmt(void)
+{
+
+ errno = EFTYPE;
+ err(1, "%s", archive);
+}
141 ar/move.c
@@ -0,0 +1,141 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)move.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: move.c,v 1.4 2009/05/26 20:39:07 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <ar.h>
+#include <dirent.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "archive.h"
+#include "pathnames.h"
+
+/*
+ * move --
+ * Change location of named members in archive - if 'b' or 'i' option
+ * selected then named members are placed before 'posname'. If 'a'
+ * option selected members go after 'posname'. If no options, members
+ * are moved to end of archive.
+ */
+int
+move(char **argv)
+{
+ CF cf;
+ off_t size, tsize;
+ FILE *afp, *curfp, *tfp1, *tfp2, *tfp3;
+ char *file;
+ int mods;
+
+ afp = open_archive(O_RDWR);
+ mods = options & (AR_A|AR_B);
+
+ tfp1 = tmp(); /* Files before key file. */
+ tfp2 = tmp(); /* Files selected by user. */
+ tfp3 = tmp(); /* Files after key file. */
+
+ /*
+ * Break archive into three parts -- selected entries and entries
+ * before and after the key entry. If positioning before the key,
+ * place the key at the beginning of the after key entries and if
+ * positioning after the key, place the key at the end of the before
+ * key entries. Put it all back together at the end.
+ */
+
+ /* Read and write to an archive; pad on both. */
+ SETCF(afp, archive, 0, tname, 0);
+ for (curfp = tfp1; get_arobj(afp);) {
+ if (*argv && (file = files(argv))) {
+ if (options & AR_V)
+ (void)printf("m - %s\n", file);
+ cf.wfp = tfp2;
+ put_arobj(&cf, NULL);
+ continue;
+ }
+ if (mods && compare(posname)) {
+ mods = 0;
+ if (options & AR_B)
+ curfp = tfp3;
+ cf.wfp = curfp;
+ put_arobj(&cf, NULL);
+ if (options & AR_A)
+ curfp = tfp3;
+ } else {
+ cf.wfp = curfp;
+ put_arobj(&cf, NULL);
+ }
+ }
+
+ if (mods) {
+ warnx("%s: archive member not found", posarg);
+ close_archive(afp);
+ return (1);
+ }
+ (void)fseeko(afp, SARMAG, SEEK_SET);
+
+ SETCF(tfp1, tname, afp, archive, NOPAD);
+ tsize = size = ftello(tfp1);
+ rewind(tfp1);
+ copy_ar(&cf, size);
+
+ tsize += size = ftello(tfp2);
+ rewind(tfp2);
+ cf.rfp = tfp2;
+ copy_ar(&cf, size);
+
+ tsize += size = ftello(tfp3);
+ rewind(tfp3);
+ cf.rfp = tfp3;
+ copy_ar(&cf, size);
+
+ fflush(afp);
+ (void)ftruncate(fileno(afp), tsize + SARMAG);
+ close_archive(afp);
+
+ if (*argv) {
+ orphans(argv);
+ return (1);
+ }
+ return (0);
+}
36 ar/pathnames.h
@@ -0,0 +1,36 @@
+/*-
+ * Copyright (c) 1991, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)pathnames.h 8.1 (Berkeley) 6/6/93
+ */
+
+#define _NAME_ARTMP "ar.XXXXXXXXXX"
+#define _PATH_ARTMP "/tmp/ar.XXXXXXXXXX"
100 ar/print.c
@@ -0,0 +1,100 @@
+/*-
+ * Copyright (c) 1990, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Hugh Smith at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+#if 0
+static char sccsid[] = "@(#)print.c 8.3 (Berkeley) 4/2/94";
+#else
+static const char rcsid[] =
+ "$ABSD: print.c,v 1.5 2011/01/31 13:33:06 mickey Exp $";
+#endif
+#endif /* not lint */
+
+#include <sys/param.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <ar.h>
+
+#include "archive.h"
+
+/*
+ * print --
+ * Prints archive members on stdout - if member names given only
+ * print those members, otherwise print all members.
+ */
+int
+print(char **argv)
+{
+ off_t size;
+ CF cf;
+ FILE *afp;
+ char *file;
+ int all;
+
+ afp = open_archive(O_RDONLY);
+
+ /* Read from an archive, write to stdout; pad on read. */
+ SETCF(afp, archive, stdout, "stdout", 0);
+ for (all = !*argv; get_arobj(afp);) {
+ if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
+ size = ftello(afp);
+ get_namtab(afp);
+ (void)fseeko(afp, size, SEEK_SET);
+ skip_arobj(afp);
+ continue;
+ }
+
+ if (all)
+ file = chdr.name;
+ else if (!(file = files(argv))) {
+ skip_arobj(afp);
+ continue;
+ }
+ if (options & AR_V) {
+ (void)printf("\n<%s>\n\n", file);
+ (void)fflush(stdout);
+ }
+ copy_ar(&cf, chdr.size);
+ if (!all && !*argv)
+ break;
+ }
+ close_archive(afp);
+
+ if (*argv) {
+ orphans(argv);
+ return (1);
+ }
+ return (0);
+}
94 ar/ranlib.1
@@ -0,0 +1,94 @@
+.\"
+.\" Copyright (c) 1990 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)ranlib.1 6.7 (Berkeley) 5/9/91
+.\"
+.Dd $Mdocdate: April 3 2009 $
+.Dt RANLIB 1
+.Os
+.Sh NAME
+.Nm ranlib
+.Nd table-of-contents for archive libraries
+.Sh SYNOPSIS
+.Nm ranlib
+.Op Fl t
+.Ar file Op Ar ...
+.Sh DESCRIPTION
+.Nm ranlib
+creates an index of external references for archive libraries,
+normally used by the loader,
+.Xr ld 1 .
+This index file is named
+.Dq /
+or
+.Dq __.SYMDEF
+and is prepended to the archive.
+Files in the archive which are not executable and symbols which are
+uninteresting to the loader are ignored.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl t
+Set the modification time of the index file.
+This time is compared by the loader with the modification time of the
+archive to verify that the table is up-to-date with respect to the
+archive.
+If the modification time has been changed without any change to the
+archive (for example, by a
+.Xr cp 1 ) ,
+the
+.Fl t
+option can be used to
+.Dq touch
+the modification time so that it appears that the table is up-to-date.
+This is also useful after using the
+.Fl t
+option of
+.Xr make 1 .
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width TMPDIR
+.It Ev TMPDIR
+The pathname of the directory to use when creating temporary files.
+.El
+.Sh FILES
+.Bl -tag -width /tmp/ranlib.XXXXXXXXXX -compact
+.It Pa /tmp/ranlib.XXXXXXXXXX
+temporary files
+.El
+.Sh SEE ALSO
+.Xr ar 1 ,
+.Xr ld 1 ,
+.Xr lorder 1 ,
+.Xr nm 1 ,
+.Xr ranlib 5
+.Sh HISTORY
+A
+.Nm ranlib
+command appeared in
+.At v7 .
93 ar/ranlib.5
@@ -0,0 +1,93 @@
+.\"
+.\" Copyright (c) 1990, 1991 The Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)ranlib.5.5 5.2 (Berkeley) 5/10/91
+.\"
+.Dd $Mdocdate: April 3 2009 $
+.Dt RANLIB 5
+.Os
+.Sh NAME
+.Nm ranlib
+.Nd archive (library) table-of-contents format
+.Sh SYNOPSIS
+.Fd #include <ranlib.h>
+.Sh DESCRIPTION
+The archive table-of-contents command
+.Nm ranlib
+creates a table of contents for archives, containing object files, to
+be used by the link-editor
+.Xr ld 1 .
+It operates on archives created with the utility
+.Xr ar 1 .
+.Pp
+There are two slightely different formats for the table of contents.
+Traditionally
+.Xr a.out 5
+systems use
+.Dq __.SYMDEF
+format (described later) and
+.Xr elf 5
+systems another, simpler format.
+In this case file name is set to
+.Dq /
+and first integer specifies the number of entries in the first part
+of the archive file.
+Then followed by the array of integer offsets to the archive files
+for each of which there is a corresponding symbol name in the