summaryrefslogtreecommitdiffstats
path: root/usr.bin/ar
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/ar')
-rw-r--r--usr.bin/ar/Makefile17
-rw-r--r--usr.bin/ar/acplex.l78
-rw-r--r--usr.bin/ar/acpyacc.y662
-rw-r--r--usr.bin/ar/ar.1406
-rw-r--r--usr.bin/ar/ar.c387
-rw-r--r--usr.bin/ar/ar.h125
-rw-r--r--usr.bin/ar/read.c204
-rw-r--r--usr.bin/ar/util.c86
-rw-r--r--usr.bin/ar/write.c879
9 files changed, 0 insertions, 2844 deletions
diff --git a/usr.bin/ar/Makefile b/usr.bin/ar/Makefile
deleted file mode 100644
index 533f931..0000000
--- a/usr.bin/ar/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# $FreeBSD$
-
-PROG= ar
-SRCS= ar.c acplex.l acpyacc.y read.c util.c write.c y.tab.h
-
-WARNS?= 5
-
-DPADD= ${LIBARCHIVE} ${LIBBZ2} ${LIBZ} ${LIBELF}
-LDADD= -larchive -lbz2 -lz -lelf
-
-CFLAGS+=-I. -I${.CURDIR}
-
-NO_SHARED?= yes
-LINKS= ${BINDIR}/ar ${BINDIR}/ranlib
-MLINKS= ar.1 ranlib.1
-
-.include <bsd.prog.mk>
diff --git a/usr.bin/ar/acplex.l b/usr.bin/ar/acplex.l
deleted file mode 100644
index 3186d17..0000000
--- a/usr.bin/ar/acplex.l
+++ /dev/null
@@ -1,78 +0,0 @@
-%{
-/*-
- * Copyright (c) 2008 Kai Wang
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <err.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <sysexits.h>
-
-#include "y.tab.h"
-
-#define YY_NO_UNPUT
-int lineno = 1;
-
-int yylex(void);
-
-%}
-
-%option noyywrap
-
-%%
-
-ADDLIB|addlib { return (ADDLIB); }
-ADDMOD|addmod { return (ADDMOD); }
-CLEAR|clear { return (CLEAR); }
-CREATE|create { return (CREATE); }
-DELETE|delete { return (DELETE); }
-DIRECTORY|directory { return (DIRECTORY); }
-END|end { return (END); }
-EXTRACT|extract { return (EXTRACT); }
-LIST|list { return (LIST); }
-OPEN|open { return (OPEN); }
-REPLACE|replace { return (REPLACE); }
-VERBOSE|verbose { return (VERBOSE); }
-SAVE|save { return (SAVE); }
-"(" { return (LP); }
-")" { return (RP); }
-"," { return (COMMA); }
-
-[-_A-Za-z0-9/:$.\\]+ {
- yylval.str = strdup(yytext);
- if (yylval.str == NULL)
- errc(EX_SOFTWARE, errno, "strdup failed");
- return (FNAME);
-}
-
-[ \t] /* whitespace */
-"*".* /* comment */
-";".* /* comment */
-"+\n" { lineno++; /* '+' is line continuation char */ }
-"\n" { lineno++; return (EOL); }
diff --git a/usr.bin/ar/acpyacc.y b/usr.bin/ar/acpyacc.y
deleted file mode 100644
index bc25b62..0000000
--- a/usr.bin/ar/acpyacc.y
+++ /dev/null
@@ -1,662 +0,0 @@
-%{
-/*-
- * Copyright (c) 2008 Kai Wang
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <archive.h>
-#include <archive_entry.h>
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "ar.h"
-
-#define TEMPLATE "arscp.XXXXXXXX"
-
-struct list {
- char *str;
- struct list *next;
-};
-
-
-extern int yylex(void);
-extern int yyparse(void);
-
-static void yyerror(const char *);
-static void arscp_addlib(char *archive, struct list *list);
-static void arscp_addmod(struct list *list);
-static void arscp_clear(void);
-static int arscp_copy(int ifd, int ofd);
-static void arscp_create(char *in, char *out);
-static void arscp_delete(struct list *list);
-static void arscp_dir(char *archive, struct list *list, char *rlt);
-static void arscp_end(int eval);
-static void arscp_extract(struct list *list);
-static void arscp_free_argv(void);
-static void arscp_free_mlist(struct list *list);
-static void arscp_list(void);
-static struct list *arscp_mlist(struct list *list, char *str);
-static void arscp_mlist2argv(struct list *list);
-static int arscp_mlist_len(struct list *list);
-static void arscp_open(char *fname);
-static void arscp_prompt(void);
-static void arscp_replace(struct list *list);
-static void arscp_save(void);
-static int arscp_target_exist(void);
-
-extern int lineno;
-
-static struct bsdar *bsdar;
-static char *target;
-static char *tmpac;
-static int interactive;
-static int verbose;
-
-%}
-
-%token ADDLIB
-%token ADDMOD
-%token CLEAR
-%token CREATE
-%token DELETE
-%token DIRECTORY
-%token END
-%token EXTRACT
-%token LIST
-%token OPEN
-%token REPLACE
-%token VERBOSE
-%token SAVE
-%token LP
-%token RP
-%token COMMA
-%token EOL
-%token <str> FNAME
-%type <list> mod_list
-
-%union {
- char *str;
- struct list *list;
-}
-
-%%
-
-begin
- : { arscp_prompt(); } ar_script
- ;
-
-ar_script
- : cmd_list
- |
- ;
-
-mod_list
- : FNAME { $$ = arscp_mlist(NULL, $1); }
- | mod_list separator FNAME { $$ = arscp_mlist($1, $3); }
- ;
-
-separator
- : COMMA
- |
- ;
-
-cmd_list
- : rawcmd
- | cmd_list rawcmd
- ;
-
-rawcmd
- : cmd EOL { arscp_prompt(); }
- ;
-
-cmd
- : addlib_cmd
- | addmod_cmd
- | clear_cmd
- | create_cmd
- | delete_cmd
- | directory_cmd
- | end_cmd
- | extract_cmd
- | list_cmd
- | open_cmd
- | replace_cmd
- | verbose_cmd
- | save_cmd
- | invalid_cmd
- | empty_cmd
- | error
- ;
-
-addlib_cmd
- : ADDLIB FNAME LP mod_list RP { arscp_addlib($2, $4); }
- | ADDLIB FNAME { arscp_addlib($2, NULL); }
- ;
-
-addmod_cmd
- : ADDMOD mod_list { arscp_addmod($2); }
- ;
-
-clear_cmd
- : CLEAR { arscp_clear(); }
- ;
-
-create_cmd
- : CREATE FNAME { arscp_create(NULL, $2); }
- ;
-
-delete_cmd
- : DELETE mod_list { arscp_delete($2); }
- ;
-
-directory_cmd
- : DIRECTORY FNAME { arscp_dir($2, NULL, NULL); }
- | DIRECTORY FNAME LP mod_list RP { arscp_dir($2, $4, NULL); }
- | DIRECTORY FNAME LP mod_list RP FNAME { arscp_dir($2, $4, $6); }
- ;
-
-end_cmd
- : END { arscp_end(EX_OK); }
- ;
-
-extract_cmd
- : EXTRACT mod_list { arscp_extract($2); }
- ;
-
-list_cmd
- : LIST { arscp_list(); }
- ;
-
-open_cmd
- : OPEN FNAME { arscp_open($2); }
- ;
-
-replace_cmd
- : REPLACE mod_list { arscp_replace($2); }
- ;
-
-save_cmd
- : SAVE { arscp_save(); }
- ;
-
-verbose_cmd
- : VERBOSE { verbose = !verbose; }
- ;
-
-empty_cmd
- :
- ;
-
-invalid_cmd
- : FNAME { yyerror(NULL); }
- ;
-
-%%
-
-/* ARGSUSED */
-static void
-yyerror(const char *s)
-{
-
- (void) s;
- printf("Syntax error in archive script, line %d\n", lineno);
-}
-
-/*
- * arscp_open first open an archive and check its validity. If the archive
- * format is valid, it calls arscp_create to create a temporary copy of
- * the archive.
- */
-static void
-arscp_open(char *fname)
-{
- struct archive *a;
- struct archive_entry *entry;
- int r;
-
- if ((a = archive_read_new()) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed");
- archive_read_support_compression_all(a);
- archive_read_support_format_all(a);
- AC(archive_read_open_file(a, fname, DEF_BLKSZ));
- if ((r = archive_read_next_header(a, &entry)))
- bsdar_warnc(bsdar, 0, "%s", archive_error_string(a));
- AC(archive_read_close(a));
- AC(archive_read_finish(a));
- if (r != ARCHIVE_OK)
- return;
- arscp_create(fname, fname);
-}
-
-/*
- * Create archive. in != NULL indicate it's a OPEN cmd, and resulting
- * archive is based on modification of an existing one. If in == NULL,
- * we are in CREATE cmd and a new empty archive will be created.
- */
-static void
-arscp_create(char *in, char *out)
-{
- struct archive *a;
- int ifd, ofd;
-
- /* Delete previously created temporary archive, if any. */
- if (tmpac) {
- if (unlink(tmpac) < 0)
- bsdar_errc(bsdar, EX_IOERR, errno, "unlink failed");
- free(tmpac);
- }
-
- tmpac = strdup(TEMPLATE);
- if (tmpac == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed");
- if ((ofd = mkstemp(tmpac)) < 0)
- bsdar_errc(bsdar, EX_IOERR, errno, "mkstemp failed");
-
- if (in) {
- /*
- * Command OPEN creates a temporary copy of the
- * input archive.
- */
- if ((ifd = open(in, O_RDONLY)) < 0) {
- bsdar_warnc(bsdar, errno, "open failed");
- return;
- }
- if (arscp_copy(ifd, ofd)) {
- bsdar_warnc(bsdar, 0, "arscp_copy failed");
- return;
- }
- close(ifd);
- close(ofd);
- } else {
- /*
- * Command CREATE creates an "empty" archive.
- * (archive with only global header)
- */
- if ((a = archive_write_new()) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, 0,
- "archive_write_new failed");
- archive_write_set_format_ar_svr4(a);
- AC(archive_write_open_fd(a, ofd));
- AC(archive_write_close(a));
- AC(archive_write_finish(a));
- }
-
- /* Override previous target, if any. */
- if (target)
- free(target);
-
- target = out;
- bsdar->filename = tmpac;
-}
-
-/* A file copying implementation using mmap. */
-static int
-arscp_copy(int ifd, int ofd)
-{
- struct stat sb;
- char *buf, *p;
- ssize_t w;
- size_t bytes;
-
- if (fstat(ifd, &sb) < 0) {
- bsdar_warnc(bsdar, errno, "fstate failed");
- return (1);
- }
- if ((p = mmap(NULL, sb.st_size, PROT_READ, MAP_SHARED, ifd,
- (off_t)0)) == MAP_FAILED) {
- bsdar_warnc(bsdar, errno, "mmap failed");
- return (1);
- }
- for (buf = p, bytes = sb.st_size; bytes > 0; bytes -= w) {
- w = write(ofd, buf, bytes);
- if (w <= 0) {
- bsdar_warnc(bsdar, errno, "write failed");
- break;
- }
- }
- if (munmap(p, sb.st_size) < 0)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "munmap failed");
- if (bytes > 0)
- return (1);
-
- return (0);
-}
-
-/*
- * Add all modules of archive to current archive, if list != NULL,
- * only those modules speicifed in 'list' will be added.
- */
-static void
-arscp_addlib(char *archive, struct list *list)
-{
-
- if (!arscp_target_exist())
- return;
- arscp_mlist2argv(list);
- bsdar->addlib = archive;
- ar_mode_A(bsdar);
- arscp_free_argv();
- arscp_free_mlist(list);
-}
-
-/* Add modules into current archive. */
-static void
-arscp_addmod(struct list *list)
-{
-
- if (!arscp_target_exist())
- return;
- arscp_mlist2argv(list);
- ar_mode_q(bsdar);
- arscp_free_argv();
- arscp_free_mlist(list);
-}
-
-/* Delete modules from current archive. */
-static void
-arscp_delete(struct list *list)
-{
-
- if (!arscp_target_exist())
- return;
- arscp_mlist2argv(list);
- ar_mode_d(bsdar);
- arscp_free_argv();
- arscp_free_mlist(list);
-}
-
-/* Extract modules from current archive. */
-static void
-arscp_extract(struct list *list)
-{
-
- if (!arscp_target_exist())
- return;
- arscp_mlist2argv(list);
- ar_mode_x(bsdar);
- arscp_free_argv();
- arscp_free_mlist(list);
-}
-
-/* List modules of archive. (Simple Mode) */
-static void
-arscp_list()
-{
-
- if (!arscp_target_exist())
- return;
- bsdar->argc = 0;
- bsdar->argv = NULL;
- /* Always verbose. */
- bsdar->options |= AR_V;
- ar_mode_t(bsdar);
- bsdar->options &= ~AR_V;
-}
-
-/* List modules of archive. (Advance Mode) */
-static void
-arscp_dir(char *archive, struct list *list, char *rlt)
-{
- FILE *out;
-
- /* If rlt != NULL, redirect output to it */
- out = NULL;
- if (rlt) {
- out = stdout;
- if ((stdout = fopen(rlt, "w")) == NULL)
- bsdar_errc(bsdar, EX_IOERR, errno,
- "fopen %s failed", rlt);
- }
-
- bsdar->filename = archive;
- if (list)
- arscp_mlist2argv(list);
- else {
- bsdar->argc = 0;
- bsdar->argv = NULL;
- }
- if (verbose)
- bsdar->options |= AR_V;
- ar_mode_t(bsdar);
- bsdar->options &= ~AR_V;
-
- if (rlt) {
- if (fclose(stdout) == EOF)
- bsdar_errc(bsdar, EX_IOERR, errno,
- "fclose %s failed", rlt);
- stdout = out;
- free(rlt);
- }
- free(archive);
- bsdar->filename = tmpac;
- arscp_free_argv();
- arscp_free_mlist(list);
-}
-
-
-/* Replace modules of current archive. */
-static void
-arscp_replace(struct list *list)
-{
-
- if (!arscp_target_exist())
- return;
- arscp_mlist2argv(list);
- ar_mode_r(bsdar);
- arscp_free_argv();
- arscp_free_mlist(list);
-}
-
-/* Rename the temporary archive to the target archive. */
-static void
-arscp_save()
-{
- mode_t mask;
-
- if (target) {
- if (rename(tmpac, target) < 0)
- bsdar_errc(bsdar, EX_IOERR, errno, "rename failed");
- /*
- * mkstemp creates temp files with mode 0600, here we
- * set target archive mode per process umask.
- */
- mask = umask(0);
- umask(mask);
- if (chmod(target, 0666 & ~mask) < 0)
- bsdar_errc(bsdar, EX_IOERR, errno, "chmod failed");
- free(tmpac);
- free(target);
- tmpac = NULL;
- target= NULL;
- bsdar->filename = NULL;
- } else
- bsdar_warnc(bsdar, 0, "no open output archive");
-}
-
-/*
- * Discard all the contents of current archive. This is achieved by
- * invoking CREATE cmd on current archive.
- */
-static void
-arscp_clear()
-{
- char *new_target;
-
- if (target) {
- new_target = strdup(target);
- if (new_target == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed");
- arscp_create(NULL, new_target);
- }
-}
-
-/*
- * Quit ar(1). Note that END cmd will not SAVE current archive
- * before exit.
- */
-static void
-arscp_end(int eval)
-{
-
- if (target)
- free(target);
- if (tmpac) {
- if (unlink(tmpac) == -1)
- bsdar_errc(bsdar, EX_IOERR, errno, "unlink %s failed",
- tmpac);
- free(tmpac);
- }
-
- exit(eval);
-}
-
-/*
- * Check if target spcified, i.e, whether OPEN or CREATE has been
- * issued by user.
- */
-static int
-arscp_target_exist()
-{
-
- if (target)
- return (1);
-
- bsdar_warnc(bsdar, 0, "no open output archive");
- return (0);
-}
-
-/* Construct module list. */
-static struct list *
-arscp_mlist(struct list *list, char *str)
-{
- struct list *l;
-
- l = malloc(sizeof(*l));
- if (l == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- l->str = str;
- l->next = list;
-
- return (l);
-}
-
-/* Calculate the length of a mlist. */
-static int
-arscp_mlist_len(struct list *list)
-{
- int len;
-
- for(len = 0; list; list = list->next)
- len++;
-
- return (len);
-}
-
-/* Free the space allocated for mod_list. */
-static void
-arscp_free_mlist(struct list *list)
-{
- struct list *l;
-
- /* Note that list->str was freed in arscp_free_argv. */
- for(; list; list = l) {
- l = list->next;
- free(list);
- }
-}
-
-/* Convert mlist to argv array. */
-static void
-arscp_mlist2argv(struct list *list)
-{
- char **argv;
- int i, n;
-
- n = arscp_mlist_len(list);
- argv = malloc(n * sizeof(*argv));
- if (argv == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
-
- /* Note that module names are stored in reverse order in mlist. */
- for(i = n - 1; i >= 0; i--, list = list->next) {
- if (list == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "invalid mlist");
- argv[i] = list->str;
- }
-
- bsdar->argc = n;
- bsdar->argv = argv;
-}
-
-/* Free space allocated for argv array and its elements. */
-static void
-arscp_free_argv()
-{
- int i;
-
- for(i = 0; i < bsdar->argc; i++)
- free(bsdar->argv[i]);
-
- free(bsdar->argv);
-}
-
-/* Show a prompt if we are in interactive mode */
-static void
-arscp_prompt()
-{
-
- if (interactive) {
- printf("AR >");
- fflush(stdout);
- }
-}
-
-/* Main function for ar script mode. */
-void
-ar_mode_script(struct bsdar *ar)
-{
-
- bsdar = ar;
- interactive = isatty(fileno(stdin));
- while(yyparse()) {
- if (!interactive)
- arscp_end(1);
- }
-
- /* Script ends without END */
- arscp_end(EX_OK);
-}
diff --git a/usr.bin/ar/ar.1 b/usr.bin/ar/ar.1
deleted file mode 100644
index cb9414e..0000000
--- a/usr.bin/ar/ar.1
+++ /dev/null
@@ -1,406 +0,0 @@
-.\" Copyright (c) 2007 Joseph Koshy. 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.
-.\"
-.\" This software is provided by Joseph Koshy ``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 Joseph Koshy 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.
-.\"
-.\" $FreeBSD$
-.\"
-.Dd August 31, 2007
-.Os
-.Dt AR 1
-.Sh NAME
-.Nm ar ,
-.Nm ranlib
-.Nd manage archives
-.Sh SYNOPSIS
-.Nm
-.Fl d
-.Op Fl T
-.Op Fl j
-.Op Fl v
-.Op Fl z
-.Ar archive
-.Ar files ...
-.Nm
-.Fl m
-.Op Fl T
-.Op Fl a Ar position-after
-.Op Fl b Ar position-before
-.Op Fl i Ar position-before
-.Op Fl j
-.Op Fl s
-.Op Fl z
-.Ar archive
-.Ar files ...
-.Nm
-.Fl p
-.Op Fl T
-.Op Fl v
-.Ar archive
-.Op Ar files ...
-.Nm
-.Fl r
-.Op Fl T
-.Op Fl a Ar position-after
-.Op Fl b Ar position-before
-.Op Fl c
-.Op Fl i Ar position-before
-.Op Fl j
-.Op Fl s
-.Op Fl u
-.Op Fl v
-.Op Fl z
-.Ar archive
-.Ar files ...
-.Nm
-.Fl s
-.Op Fl j
-.Op Fl z
-.Ar archive
-.Nm
-.Fl t
-.Op Fl T
-.Op Fl v
-.Ar archive
-.Op Ar files ...
-.Nm
-.Fl x
-.Op Fl C
-.Op Fl T
-.Op Fl o
-.Op Fl u
-.Op Fl v
-.Ar archive
-.Op Ar files ...
-.Nm ranlib
-.Ar archive ...
-.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 to it, and
-existing files can be extracted, deleted or replaced.
-.Pp
-Files are named in the archive by their last file name component,
-so if a file referenced by a path containing a
-.Dq /
-is archived, it will be named by the last component of the path.
-Similarly 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
-The normal use of
-.Nm
-is for the creation and maintenance of libraries suitable for use
-with the link editor
-.Xr ld 1 ,
-although it is not restricted to this purpose.
-The
-.Nm
-utility can create and manage an archive symbol table (see
-.Xr ar 5 )
-used to speed up link editing operations.
-If a symbol table is present in an archive, it will be
-kept up-to-date by subsequent operations on the archive (excepting
-the quick update specified by the
-.Fl q
-option).
-.Pp
-The
-.Nm ranlib
-utility is used to add an archive symbol table
-to an existing archive.
-.Sh OPTIONS
-The
-.Nm
-utility supports the following options:
-.Bl -tag -width indent
-.It Fl a Ar member-after
-When used with option
-.Fl m
-this option specifies that the archive members specified by
-arguments
-.Ar files ...
-are moved to after the archive member named by argument
-.Ar member-after .
-When used with option
-.Fl r
-this option specifies that the files specified by arguments
-.Ar files ...
-are added after the archive member named by argument
-.Ar member-after .
-.It Fl b Ar member-before
-When used with option
-.Fl m
-this option specifies that the archive members specified by
-arguments
-.Ar files ...
-are moved to before the archive member named by argument
-.Ar member-before .
-When used with option
-.Fl r
-this option specifies that the files specified by arguments
-.Ar files ...
-are added before the archive member named by argument
-.Ar member-before .
-.It Fl c
-Suppress the informational message printed when a new archive is
-created using the
-.Fl r
-and
-.Fl q
-options.
-.It Fl C
-Prevent extracted files from replacing like-named files
-in the file system.
-.It Fl d
-Delete the members named by arguments
-.Ar files ...
-from the archive specified by argument
-.Ar archive .
-The archive's symbol table, if present, is updated to reflect
-the new contents of the archive.
-.It Fl f
-Synonymous with option
-.Fl T .
-.It Fl i Ar member-before
-Synonymous with option
-.Fl b .
-.It Fl j
-Compress the resulting archive with
-.Xr bzip2 1 .
-.It Fl m
-Move archive members specified by arguments
-.Ar files ...
-within the archive.
-If a position has been specified by one of the
-.Fl a ,
-.Fl b
-or
-.Fl i
-options, the members are moved to before or after the specified
-position.
-If no position has been specified, the specified members are moved
-to the end of the archive.
-If the archive has a symbol table, it is updated to reflect the
-new contents of the archive.
-.It Fl o
-Preserve the original modification times of members when extracting
-them.
-.It Fl p
-Write the contents of the specified archive members named by
-arguments
-.Ar files ...
-to standard output.
-If no members were specified, the contents of all the files in the
-archive are written in the order they appear in the archive.
-.It Fl q
-Append the files specified by arguments
-.Ar files ...
-to the archive specified by argument
-.Ar archive
-without checking if the files already exist in the archive and
-without updating the archive's symbol table.
-If the archive file
-.Ar archive
-does not already exist, a new archive is created.
-However, to be compatible with GNU
-.Nm ,
-option
-.Fl q
-will update the archive's symbol table.
-.It Fl r
-Replace (add) the files specified by arguments
-.Ar files ...
-in the archive specified by argument
-.Ar archive ,
-creating the archive if necessary.
-Files that replace existing files do not change the order of files
-within the archive.
-If a file named in arguments
-.Ar files ...
-does not exist, existing members in the archive that match that
-name are not changed.
-New files are added to the end of the archive unless one of the
-positioning options
-.Fl a ,
-.Fl b
-or
-.Fl i
-is specified.
-The archive symbol table, if it exists, is updated to reflect the
-new state of the archive.
-.It Fl s
-Add an archive symbol table (see
-.Xr ar 5 )
-to the archive specified by argument
-.Ar archive .
-Invoking
-.Nm
-with the
-.Fl s
-option alone is equivalent to invoking
-.Nm ranlib .
-.It Fl t
-List the files specified by arguments
-.Ar files ...
-in the order in which they appear in the archive, one per line.
-If no files are specified, all files in the archive are listed.
-.It Fl T
-Use only the first fifteen characters of the archive member name or
-command line file name argument when naming archive members.
-.It Fl u
-Conditionally update the archive or extract members.
-When used with the
-.Fl r
-option, files named by arguments
-.Ar files ...
-will be replaced in the archive if they are newer than their
-archived versions.
-When used with the
-.Fl x
-option, the members specified by arguments
-.Ar files ...
-will be extracted only if they are newer than the corresponding
-files in the file system.
-.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 being
-performed, which consists of three white-space seperated fields:
-the option letter, a dash
-.Dq "-" ,
-and the file name.
-When used with the
-.Fl r
-option,
-.Nm
-displays the description as above, but the initial letter is an
-.Dq a
-if the file is added to the archive, or an
-.Dq r
-if the file replaces a file already in the archive.
-When used with the
-.Fl p
-option, the name of the file enclosed in
-.Dq <
-and
-.Dq >
-characters is written to standard output preceded by a single newline
-character and followed by two newline characters.
-The contents of the named file follow the file name.
-When used with the
-.Fl t
-option,
-.Nm
-displays eight whitespace separated fields:
-the file permissions as displayed by
-.Xr strmode 3 ,
-decimal user and group IDs separated by a slash (
-.Dq / Ns ) ,
-the file size in bytes, the file modification time in
-.Xr strftime 3
-format
-.Dq "%b %e %H:%M %Y" ,
-and the name of the file.
-.It Fl x
-Extract archive members specified by arguments
-.Ar files ...
-into the current directory.
-If no members have been specified, extract all members of the archive.
-If the file corresponding to an extracted member does not exist it
-will be created.
-If the file corresponding to an extracted member does exist, its owner
-and group will not be changed while its contents will be overwritten
-and its permissions will set to that entered in the archive.
-The file's access and modification time would be that of the time
-of extraction unless the
-.Fl o
-option was specified.
-.It Fl z
-Compress the resulting archive with
-.Xr gzip 1 .
-.El
-.Sh EXAMPLES
-To create a new archive
-.Pa ex.a
-containing three files
-.Pa ex1.o ,
-.Pa ex2.o
-and
-.Pa ex3.o ,
-use:
-.Dl "ar -rc ex.a ex1.o ex2.o ex3.o"
-.Pp
-To add an archive symbol table to an existing archive
-.Pa ex.a ,
-use:
-.Dl "ar -s ex.a"
-.Pp
-To delete file
-.Pa ex1.o
-from archive
-.Pa ex.a ,
-use:
-.D1 "ar -d ex.a ex1.o"
-.Pp
-To verbosely list the contents of archive
-.Pa ex.a ,
-use:
-.D1 "ar -tv ex.a"
-.Sh DIAGNOSTICS
-.Ex -std
-.Sh SEE ALSO
-.Xr ld 1 ,
-.Xr archive 3 ,
-.Xr elf 3 ,
-.Xr strftime 3 ,
-.Xr strmode 3 ,
-.Xr ar 5
-.\" .Sh COMPATIBILITY
-.\" .Nm
-.\" is expected to be compatible with GNU and SVR4
-.\" .Nm .
-.\" .Sh STANDARDS
-.\" Do the POSIX/SuSv3 standards have anything to say about AR(1)?
-.Sh HISTORY
-An
-.Nm
-command first appeared in AT&T UNIX Version 1.
-In
-.Fx 8.0 ,
-.An "Kai Wang" Aq kaiw@FreeBSD.org
-reimplemented
-.Nm
-and
-.Nm ranlib
-using the
-.Lb libarchive
-and the
-.Lb libelf .
diff --git a/usr.bin/ar/ar.c b/usr.bin/ar/ar.c
deleted file mode 100644
index e910e30..0000000
--- a/usr.bin/ar/ar.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*-
- * Copyright (c) 2007 Kai Wang
- * Copyright (c) 2007 Tim Kientzle
- * Copyright (c) 2007 Joseph Koshy
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- */
-
-/*-
- * 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <archive.h>
-#include <errno.h>
-#include <getopt.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-
-#include "ar.h"
-
-enum options
-{
- OPTION_HELP
-};
-
-static struct option longopts[] =
-{
- {"help", no_argument, NULL, OPTION_HELP},
- {"version", no_argument, NULL, 'V'},
- {NULL, 0, NULL, 0}
-};
-
-static void bsdar_usage(void);
-static void ranlib_usage(void);
-static void set_mode(struct bsdar *bsdar, char opt);
-static void only_mode(struct bsdar *bsdar, const char *opt,
- const char *valid_modes);
-static void bsdar_version(void);
-static void ranlib_version(void);
-
-int
-main(int argc, char **argv)
-{
- struct bsdar *bsdar, bsdar_storage;
- char *p;
- size_t len;
- int i, opt;
-
- bsdar = &bsdar_storage;
- memset(bsdar, 0, sizeof(*bsdar));
-
- if ((bsdar->progname = getprogname()) == NULL)
- bsdar->progname = "ar";
-
- if (strcmp(bsdar->progname, "ranlib") == 0 ||
- strcmp(bsdar->progname, "bsdranlib") == 0) {
- while ((opt = getopt_long(argc, argv, "tV", longopts,
- NULL)) != -1) {
- switch(opt) {
- case 't':
- /* Ignored. */
- break;
- case 'V':
- ranlib_version();
- break;
- case OPTION_HELP:
- ranlib_usage();
- default:
- ranlib_usage();
- }
- }
- argv += optind;
- argc -= optind;
-
- if (*argv == NULL)
- ranlib_usage();
-
- bsdar->options |= AR_S;
- for (;(bsdar->filename = *argv++) != NULL;)
- ar_mode_s(bsdar);
-
- exit(EX_OK);
- } else {
- if (argc < 2)
- bsdar_usage();
-
- if (*argv[1] != '-') {
- len = strlen(argv[1]) + 2;
- if ((p = malloc(len)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno,
- "malloc failed");
- *p = '-';
- (void)strlcpy(p + 1, argv[1], len - 1);
- argv[1] = p;
- }
- }
-
- while ((opt = getopt_long(argc, argv, "abCcdfijlMmopqrSsTtuVvxz",
- longopts, NULL)) != -1) {
- switch(opt) {
- case 'a':
- bsdar->options |= AR_A;
- break;
- case 'b':
- case 'i':
- bsdar->options |= AR_B;
- break;
- case 'C':
- bsdar->options |= AR_CC;
- break;
- case 'c':
- bsdar->options |= AR_C;
- break;
- case 'd':
- set_mode(bsdar, opt);
- break;
- case 'f':
- case 'T':
- bsdar->options |= AR_TR;
- break;
- case 'j':
- bsdar->options |= AR_J;
- break;
- case 'l':
- /* ignored, for GNU ar comptibility */
- break;
- case 'M':
- set_mode(bsdar, opt);
- break;
- case 'm':
- set_mode(bsdar, opt);
- break;
- case 'o':
- bsdar->options |= AR_O;
- break;
- case 'p':
- set_mode(bsdar, opt);
- break;
- case 'q':
- set_mode(bsdar, opt);
- break;
- case 'r':
- set_mode(bsdar, opt);
- break;
- case 'S':
- bsdar->options |= AR_SS;
- break;
- case 's':
- bsdar->options |= AR_S;
- break;
- case 't':
- set_mode(bsdar, opt);
- break;
- case 'u':
- bsdar->options |= AR_U;
- break;
- case 'V':
- bsdar_version();
- break;
- case 'v':
- bsdar->options |= AR_V;
- break;
- case 'x':
- set_mode(bsdar, opt);
- break;
- case 'z':
- bsdar->options |= AR_Z;
- break;
- case OPTION_HELP:
- bsdar_usage();
- default:
- bsdar_usage();
- }
- }
-
- argv += optind;
- argc -= optind;
-
- if (*argv == NULL && bsdar->mode != 'M')
- bsdar_usage();
-
- if (bsdar->options & AR_A && bsdar->options & AR_B)
- bsdar_errc(bsdar, EX_USAGE, 0,
- "only one of -a and -[bi] options allowed");
-
- if (bsdar->options & AR_J && bsdar->options & AR_Z)
- bsdar_errc(bsdar, EX_USAGE, 0,
- "only one of -j and -z options allowed");
-
- if (bsdar->options & AR_S && bsdar->options & AR_SS)
- bsdar_errc(bsdar, EX_USAGE, 0,
- "only one of -s and -S options allowed");
-
- if (bsdar->options & (AR_A | AR_B)) {
- if ((bsdar->posarg = *argv) == NULL)
- bsdar_errc(bsdar, EX_USAGE, 0,
- "no position operand specified");
- if ((bsdar->posarg = basename(bsdar->posarg)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno,
- "basename failed");
- argc--;
- argv++;
- }
-
- if (bsdar->options & AR_A)
- only_mode(bsdar, "-a", "mqr");
- if (bsdar->options & AR_B)
- only_mode(bsdar, "-b", "mqr");
- if (bsdar->options & AR_C)
- only_mode(bsdar, "-c", "qr");
- if (bsdar->options & AR_CC)
- only_mode(bsdar, "-C", "x");
- if (bsdar->options & AR_O)
- only_mode(bsdar, "-o", "x");
- if (bsdar->options & AR_SS)
- only_mode(bsdar, "-S", "mqr");
- if (bsdar->options & AR_U)
- only_mode(bsdar, "-u", "qrx");
-
- if (bsdar->mode == 'M') {
- ar_mode_script(bsdar);
- exit(EX_OK);
- }
-
- if ((bsdar->filename = *argv) == NULL)
- bsdar_usage();
-
- bsdar->argc = --argc;
- bsdar->argv = ++argv;
-
- if ((!bsdar->mode || strchr("ptx", bsdar->mode)) &&
- bsdar->options & AR_S) {
- ar_mode_s(bsdar);
- if (!bsdar->mode)
- exit(EX_OK);
- }
-
- switch(bsdar->mode) {
- case 'd':
- ar_mode_d(bsdar);
- break;
- case 'm':
- ar_mode_m(bsdar);
- break;
- case 'p':
- ar_mode_p(bsdar);
- break;
- case 'q':
- ar_mode_q(bsdar);
- break;
- case 'r':
- ar_mode_r(bsdar);
- break;
- case 't':
- ar_mode_t(bsdar);
- break;
- case 'x':
- ar_mode_x(bsdar);
- break;
- default:
- bsdar_usage();
- /* NOTREACHED */
- }
-
- for (i = 0; i < bsdar->argc; i++)
- if (bsdar->argv[i] != NULL)
- bsdar_warnc(bsdar, 0, "%s: not found in archive",
- bsdar->argv[i]);
-
- exit(EX_OK);
-}
-
-static void
-set_mode(struct bsdar *bsdar, char opt)
-{
-
- if (bsdar->mode != '\0' && bsdar->mode != opt)
- bsdar_errc(bsdar, EX_USAGE, 0,
- "Can't specify both -%c and -%c", opt, bsdar->mode);
- bsdar->mode = opt;
-}
-
-static void
-only_mode(struct bsdar *bsdar, const char *opt, const char *valid_modes)
-{
-
- if (strchr(valid_modes, bsdar->mode) == NULL)
- bsdar_errc(bsdar, EX_USAGE, 0,
- "Option %s is not permitted in mode -%c", opt, bsdar->mode);
-}
-
-static void
-bsdar_usage()
-{
-
- (void)fprintf(stderr, "usage: ar -d [-Tjsvz] archive file ...\n");
- (void)fprintf(stderr, "\tar -m [-Tjsvz] archive file ...\n");
- (void)fprintf(stderr, "\tar -m [-Tabijsvz] position archive file ...\n");
- (void)fprintf(stderr, "\tar -p [-Tv] archive [file ...]\n");
- (void)fprintf(stderr, "\tar -q [-Tcjsvz] archive file ...\n");
- (void)fprintf(stderr, "\tar -r [-Tcjsuvz] archive file ...\n");
- (void)fprintf(stderr, "\tar -r [-Tabcijsuvz] position archive file ...\n");
- (void)fprintf(stderr, "\tar -s [-jz] archive\n");
- (void)fprintf(stderr, "\tar -t [-Tv] archive [file ...]\n");
- (void)fprintf(stderr, "\tar -x [-CTouv] archive [file ...]\n");
- (void)fprintf(stderr, "\tar -V\n");
- exit(EX_USAGE);
-}
-
-static void
-ranlib_usage()
-{
-
- (void)fprintf(stderr, "usage: ranlib [-t] archive ...\n");
- (void)fprintf(stderr, "\tranlib -V\n");
- exit(EX_USAGE);
-}
-
-static void
-bsdar_version()
-{
- (void)printf("BSD ar %s - %s\n", BSDAR_VERSION, archive_version());
- exit(EX_OK);
-}
-
-static void
-ranlib_version()
-{
- (void)printf("ranlib %s - %s\n", BSDAR_VERSION, archive_version());
- exit(EX_OK);
-}
diff --git a/usr.bin/ar/ar.h b/usr.bin/ar/ar.h
deleted file mode 100644
index 111f944..0000000
--- a/usr.bin/ar/ar.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-
- * Copyright (c) 2007 Kai Wang
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- *
- * $FreeBSD$
- */
-
-#define BSDAR_VERSION "1.1.0"
-
-/*
- * ar(1) options.
- */
-#define AR_A 0x0001 /* position-after */
-#define AR_B 0x0002 /* position-before */
-#define AR_C 0x0004 /* creating new archive */
-#define AR_CC 0x0008 /* do not overwrite when extracting */
-#define AR_J 0x0010 /* bzip2 compression */
-#define AR_O 0x0020 /* preserve original mtime when extracting */
-#define AR_S 0x0040 /* write archive symbol table */
-#define AR_SS 0x0080 /* do not write archive symbol table */
-#define AR_TR 0x0100 /* only keep first 15 chars for member name */
-#define AR_U 0x0200 /* only extract or update newer members.*/
-#define AR_V 0x0400 /* verbose mode */
-#define AR_Z 0x0800 /* gzip compression */
-
-#define DEF_BLKSZ 10240 /* default block size */
-
-/*
- * Convenient wrapper for general libarchive error handling.
- */
-#define AC(CALL) do { \
- if ((CALL)) \
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "%s", \
- archive_error_string(a)); \
-} while (0)
-
-/*
- * In-memory representation of archive member(object).
- */
-struct ar_obj {
- char *name; /* member name */
- void *maddr; /* mmap start address */
- uid_t uid; /* user id */
- gid_t gid; /* group id */
- mode_t md; /* octal file permissions */
- size_t size; /* member size */
- time_t mtime; /* modification time */
- int fd; /* file descriptor */
- dev_t dev; /* inode's device */
- ino_t ino; /* inode's number */
-
- TAILQ_ENTRY(ar_obj) objs;
-};
-
-/*
- * Structure encapsulates the "global" data for "ar" program.
- */
-struct bsdar {
- const char *filename; /* archive name. */
- const char *addlib; /* target of ADDLIB. */
- const char *posarg; /* position arg for modifiers -a, -b. */
- char mode; /* program mode */
- char compression; /* compression mode */
- int options; /* command line options */
-
- const char *progname; /* program name */
- int argc;
- char **argv;
-
- /*
- * Fields for the archive string table.
- */
- char *as; /* buffer for archive string table. */
- size_t as_sz; /* current size of as table. */
- size_t as_cap; /* capacity of as table buffer. */
-
- /*
- * Fields for the archive symbol table.
- */
- uint32_t s_cnt; /* current number of symbols. */
- uint32_t *s_so; /* symbol offset table. */
- size_t s_so_cap; /* capacity of so table buffer. */
- char *s_sn; /* symbol name table */
- size_t s_sn_cap; /* capacity of sn table buffer. */
- size_t s_sn_sz; /* current size of sn table. */
- /* Current member's offset (relative to the end of pseudo members.) */
- off_t rela_off;
-
- TAILQ_HEAD(, ar_obj) v_obj; /* object(member) list */
-};
-
-void bsdar_errc(struct bsdar *, int _eval, int _code,
- const char *fmt, ...);
-void bsdar_warnc(struct bsdar *, int _code, const char *fmt, ...);
-void ar_mode_d(struct bsdar *bsdar);
-void ar_mode_m(struct bsdar *bsdar);
-void ar_mode_p(struct bsdar *bsdar);
-void ar_mode_q(struct bsdar *bsdar);
-void ar_mode_r(struct bsdar *bsdar);
-void ar_mode_s(struct bsdar *bsdar);
-void ar_mode_t(struct bsdar *bsdar);
-void ar_mode_x(struct bsdar *bsdar);
-void ar_mode_A(struct bsdar *bsdar);
-void ar_mode_script(struct bsdar *ar);
diff --git a/usr.bin/ar/read.c b/usr.bin/ar/read.c
deleted file mode 100644
index a9e2ed1..0000000
--- a/usr.bin/ar/read.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*-
- * Copyright (c) 2007 Kai Wang
- * Copyright (c) 2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <archive.h>
-#include <archive_entry.h>
-#include <errno.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <string.h>
-#include <sysexits.h>
-
-#include "ar.h"
-
-static void read_archive(struct bsdar *bsdar, char mode);
-
-void
-ar_mode_p(struct bsdar *bsdar)
-{
-
- read_archive(bsdar, 'p');
-}
-
-void
-ar_mode_t(struct bsdar *bsdar)
-{
-
- read_archive(bsdar, 't');
-}
-
-void
-ar_mode_x(struct bsdar *bsdar)
-{
-
- read_archive(bsdar, 'x');
-}
-
-/*
- * Handle read modes: 'x', 't' and 'p'.
- */
-static void
-read_archive(struct bsdar *bsdar, char mode)
-{
- struct archive *a;
- struct archive_entry *entry;
- struct stat sb;
- struct tm *tp;
- const char *bname;
- const char *name;
- mode_t md;
- size_t size;
- time_t mtime;
- uid_t uid;
- gid_t gid;
- char **av;
- char buf[25];
- char find;
- int flags, r, i;
-
- if ((a = archive_read_new()) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed");
- archive_read_support_compression_all(a);
- archive_read_support_format_all(a);
- AC(archive_read_open_file(a, bsdar->filename, DEF_BLKSZ));
-
- for (;;) {
- r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
- r == ARCHIVE_FATAL)
- bsdar_warnc(bsdar, 0, "%s", archive_error_string(a));
- if (r == ARCHIVE_EOF || r == ARCHIVE_FATAL)
- break;
- if (r == ARCHIVE_RETRY) {
- bsdar_warnc(bsdar, 0, "Retrying...");
- continue;
- }
-
- name = archive_entry_pathname(entry);
-
- /* Skip pseudo members. */
- if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0)
- continue;
-
- if (bsdar->argc > 0) {
- find = 0;
- for(i = 0; i < bsdar->argc; i++) {
- av = &bsdar->argv[i];
- if (*av == NULL)
- continue;
- if ((bname = basename(*av)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno,
- "basename failed");
- if (strcmp(bname, name) != 0)
- continue;
-
- *av = NULL;
- find = 1;
- break;
- }
- if (!find)
- continue;
- }
-
- if (mode == 't') {
- if (bsdar->options & AR_V) {
- md = archive_entry_mode(entry);
- uid = archive_entry_uid(entry);
- gid = archive_entry_gid(entry);
- size = archive_entry_size(entry);
- mtime = archive_entry_mtime(entry);
- (void)strmode(md, buf);
- (void)fprintf(stdout, "%s %6d/%-6d %8ju ",
- buf + 1, uid, gid, (uintmax_t)size);
- tp = localtime(&mtime);
- (void)strftime(buf, sizeof(buf),
- "%b %e %H:%M %Y", tp);
- (void)fprintf(stdout, "%s %s", buf, name);
- } else
- (void)fprintf(stdout, "%s", name);
- r = archive_read_data_skip(a);
- if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY ||
- r == ARCHIVE_FATAL) {
- (void)fprintf(stdout, "\n");
- bsdar_warnc(bsdar, 0, "%s",
- archive_error_string(a));
- }
-
- if (r == ARCHIVE_FATAL)
- break;
-
- (void)fprintf(stdout, "\n");
- } else {
- /* mode == 'x' || mode = 'p' */
- if (mode == 'p') {
- if (bsdar->options & AR_V) {
- (void)fprintf(stdout, "\n<%s>\n\n",
- name);
- fflush(stdout);
- }
- r = archive_read_data_into_fd(a, 1);
- } else {
- /* mode == 'x' */
- if (stat(name, &sb) != 0) {
- if (errno != ENOENT) {
- bsdar_warnc(bsdar, 0,
- "stat %s failed",
- bsdar->filename);
- continue;
- }
- } else {
- /* stat success, file exist */
- if (bsdar->options & AR_CC)
- continue;
- if (bsdar->options & AR_U &&
- archive_entry_mtime(entry) <=
- sb.st_mtime)
- continue;
- }
-
- if (bsdar->options & AR_V)
- (void)fprintf(stdout, "x - %s\n", name);
- flags = 0;
- if (bsdar->options & AR_O)
- flags |= ARCHIVE_EXTRACT_TIME;
-
- r = archive_read_extract(a, entry, flags);
- }
-
- if (r)
- bsdar_warnc(bsdar, 0, "%s",
- archive_error_string(a));
- }
- }
- AC(archive_read_close(a));
- AC(archive_read_finish(a));
-}
diff --git a/usr.bin/ar/util.c b/usr.bin/ar/util.c
deleted file mode 100644
index e1230e3..0000000
--- a/usr.bin/ar/util.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*-
- * Copyright (c) 2003-2007 Tim Kientzle
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ar.h"
-
-static void bsdar_vwarnc(struct bsdar *, int code,
- const char *fmt, va_list ap);
-static void bsdar_verrc(struct bsdar *bsdar, int code,
- const char *fmt, va_list ap);
-
-static void
-bsdar_vwarnc(struct bsdar *bsdar, int code, const char *fmt, va_list ap)
-{
-
- fprintf(stderr, "%s: warning: ", bsdar->progname);
- vfprintf(stderr, fmt, ap);
- if (code != 0)
- fprintf(stderr, ": %s", strerror(code));
- fprintf(stderr, "\n");
-}
-
-void
-bsdar_warnc(struct bsdar *bsdar, int code, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- bsdar_vwarnc(bsdar, code, fmt, ap);
- va_end(ap);
-}
-
-static void
-bsdar_verrc(struct bsdar *bsdar, int code, const char *fmt, va_list ap)
-{
-
- fprintf(stderr, "%s: fatal: ", bsdar->progname);
- vfprintf(stderr, fmt, ap);
- if (code != 0)
- fprintf(stderr, ": %s", strerror(code));
- fprintf(stderr, "\n");
-}
-
-void
-bsdar_errc(struct bsdar *bsdar, int eval, int code, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- bsdar_verrc(bsdar, code, fmt, ap);
- va_end(ap);
- exit(eval);
-}
diff --git a/usr.bin/ar/write.c b/usr.bin/ar/write.c
deleted file mode 100644
index 3d4f93d..0000000
--- a/usr.bin/ar/write.c
+++ /dev/null
@@ -1,879 +0,0 @@
-/*-
- * Copyright (c) 2007 Kai Wang
- * 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
- * in this position and unchanged.
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/endian.h>
-#include <sys/mman.h>
-#include <sys/queue.h>
-#include <sys/stat.h>
-#include <archive.h>
-#include <archive_entry.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <gelf.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-
-#include "ar.h"
-
-#define _ARMAG_LEN 8 /* length of ar magic string */
-#define _ARHDR_LEN 60 /* length of ar header */
-#define _INIT_AS_CAP 128 /* initial archive string table size */
-#define _INIT_SYMOFF_CAP (256*(sizeof(uint32_t))) /* initial so table size */
-#define _INIT_SYMNAME_CAP 1024 /* initial sn table size */
-#define _MAXNAMELEN_SVR4 15 /* max member name length in svr4 variant */
-#define _TRUNCATE_LEN 15 /* number of bytes to keep for member name */
-
-static void add_to_ar_str_table(struct bsdar *bsdar, const char *name);
-static void add_to_ar_sym_table(struct bsdar *bsdar, const char *name);
-static struct ar_obj *create_obj_from_file(struct bsdar *bsdar,
- const char *name, time_t mtime);
-static void create_symtab_entry(struct bsdar *bsdar, void *maddr,
- size_t size);
-static void insert_obj(struct bsdar *bsdar, struct ar_obj *obj,
- struct ar_obj *pos);
-static void read_objs(struct bsdar *bsdar, const char *archive,
- int checkargv);
-static void write_archive(struct bsdar *bsdar, char mode);
-static void write_cleanup(struct bsdar *bsdar);
-static void write_data(struct bsdar *bsdar, struct archive *a,
- const void *buf, size_t s);
-static void write_objs(struct bsdar *bsdar);
-
-void
-ar_mode_d(struct bsdar *bsdar)
-{
-
- write_archive(bsdar, 'd');
-}
-
-void
-ar_mode_m(struct bsdar *bsdar)
-{
-
- write_archive(bsdar, 'm');
-}
-
-void
-ar_mode_q(struct bsdar *bsdar)
-{
-
- write_archive(bsdar, 'q');
-}
-
-void
-ar_mode_r(struct bsdar *bsdar)
-{
-
- write_archive(bsdar, 'r');
-}
-
-void
-ar_mode_s(struct bsdar *bsdar)
-{
-
- write_archive(bsdar, 's');
-}
-
-void
-ar_mode_A(struct bsdar *bsdar)
-{
-
- write_archive(bsdar, 'A');
-}
-
-/*
- * Create object from file, return created obj upon success, or NULL
- * when an error occurs or the member is not newer than existing
- * one while -u is specifed.
- */
-static struct ar_obj *
-create_obj_from_file(struct bsdar *bsdar, const char *name, time_t mtime)
-{
- struct ar_obj *obj;
- struct stat sb;
- const char *bname;
-
- if (name == NULL)
- return (NULL);
-
- obj = malloc(sizeof(struct ar_obj));
- if (obj == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- if ((obj->fd = open(name, O_RDONLY, 0)) < 0) {
- bsdar_warnc(bsdar, errno, "can't open file: %s", name);
- free(obj);
- return (NULL);
- }
-
- if ((bname = basename(name)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "basename failed");
- if (bsdar->options & AR_TR && strlen(bname) > _TRUNCATE_LEN) {
- if ((obj->name = malloc(_TRUNCATE_LEN + 1)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- (void)strncpy(obj->name, bname, _TRUNCATE_LEN);
- obj->name[_TRUNCATE_LEN] = '\0';
- } else
- if ((obj->name = strdup(bname)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed");
-
- if (fstat(obj->fd, &sb) < 0) {
- bsdar_warnc(bsdar, errno, "can't fstat file: %s", obj->name);
- goto giveup;
- }
- if (!S_ISREG(sb.st_mode)) {
- bsdar_warnc(bsdar, 0, "%s is not an ordinary file", obj->name);
- goto giveup;
- }
-
- /*
- * When option '-u' is specified and member is not newer than the
- * existing one, the replace will not happen. While if mtime == 0,
- * which indicates that this is to "replace a none exist member",
- * the replace will proceed regardless of '-u'.
- */
- if (mtime != 0 && bsdar->options & AR_U && sb.st_mtime <= mtime)
- goto giveup;
-
- obj->uid = sb.st_uid;
- obj->gid = sb.st_gid;
- obj->md = sb.st_mode;
- obj->size = sb.st_size;
- obj->mtime = sb.st_mtime;
- obj->dev = sb.st_dev;
- obj->ino = sb.st_ino;
-
- if (obj->size == 0) {
- obj->maddr = NULL;
- return (obj);
- }
-
- if ((obj->maddr = mmap(NULL, obj->size, PROT_READ,
- MAP_PRIVATE, obj->fd, (off_t)0)) == MAP_FAILED) {
- bsdar_warnc(bsdar, errno, "can't mmap file: %s", obj->name);
- goto giveup;
- }
- if (close(obj->fd) < 0)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "close failed: %s",
- obj->name);
-
- return (obj);
-
-giveup:
- if (close(obj->fd) < 0)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "close failed: %s",
- obj->name);
- free(obj->name);
- free(obj);
- return (NULL);
-}
-
-/*
- * Insert obj to the tail, or before/after the pos obj.
- */
-static void
-insert_obj(struct bsdar *bsdar, struct ar_obj *obj, struct ar_obj *pos)
-{
- if (obj == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "try to insert a null obj");
-
- if (pos == NULL || obj == pos)
- /*
- * If the object to move happens to be the posistion obj,
- * or if there is not a pos obj, move it to tail.
- */
- goto tail;
-
- if (bsdar->options & AR_B) {
- TAILQ_INSERT_BEFORE(pos, obj, objs);
- return;
- }
- if (bsdar->options & AR_A) {
- TAILQ_INSERT_AFTER(&bsdar->v_obj, pos, obj, objs);
- return;
- }
-
-tail:
- TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs);
-
-}
-
-/*
- * Read objects from archive into v_obj list. Note that checkargv is
- * set when read_objs is used to read objects from the target of
- * ADDLIB command (ar script mode), in this case argv array possibly
- * specifies the members ADDLIB want.
- */
-static void
-read_objs(struct bsdar *bsdar, const char *archive, int checkargv)
-{
- struct archive *a;
- struct archive_entry *entry;
- struct ar_obj *obj;
- const char *name;
- const char *bname;
- char *buff;
- char **av;
- size_t size;
- int i, r, find;
-
- if ((a = archive_read_new()) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_read_new failed");
- archive_read_support_compression_all(a);
- archive_read_support_format_ar(a);
- AC(archive_read_open_filename(a, archive, DEF_BLKSZ));
- for (;;) {
- r = archive_read_next_header(a, &entry);
- if (r == ARCHIVE_FATAL)
- bsdar_errc(bsdar, EX_DATAERR, 0, "%s",
- archive_error_string(a));
- if (r == ARCHIVE_EOF)
- break;
- if (r == ARCHIVE_WARN || r == ARCHIVE_RETRY)
- bsdar_warnc(bsdar, 0, "%s", archive_error_string(a));
- if (r == ARCHIVE_RETRY) {
- bsdar_warnc(bsdar, 0, "Retrying...");
- continue;
- }
-
- /*
- * Remember the compression mode of existing archive.
- * If neither -j nor -z is specified, this mode will
- * be used for resulting archive.
- */
- bsdar->compression = archive_compression(a);
-
- name = archive_entry_pathname(entry);
-
- /*
- * skip pseudo members.
- */
- if (strcmp(name, "/") == 0 || strcmp(name, "//") == 0)
- continue;
-
- /*
- * If checkargv is set, only read those members specified
- * in argv.
- */
- if (checkargv && bsdar->argc > 0) {
- find = 0;
- for(i = 0; i < bsdar->argc; i++) {
- av = &bsdar->argv[i];
- if (*av == NULL)
- continue;
- if ((bname = basename(*av)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno,
- "basename failed");
- if (strcmp(bname, name) != 0)
- continue;
-
- *av = NULL;
- find = 1;
- break;
- }
- if (!find)
- continue;
- }
-
- size = archive_entry_size(entry);
-
- if (size > 0) {
- if ((buff = malloc(size)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno,
- "malloc failed");
- if (archive_read_data(a, buff, size) != (ssize_t)size) {
- bsdar_warnc(bsdar, 0, "%s",
- archive_error_string(a));
- free(buff);
- continue;
- }
- } else
- buff = NULL;
-
- obj = malloc(sizeof(struct ar_obj));
- if (obj == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- obj->maddr = buff;
- if ((obj->name = strdup(name)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "strdup failed");
- obj->size = size;
- obj->uid = archive_entry_uid(entry);
- obj->gid = archive_entry_gid(entry);
- obj->md = archive_entry_mode(entry);
- obj->mtime = archive_entry_mtime(entry);
- obj->dev = 0;
- obj->ino = 0;
-
- /*
- * Objects from archive have obj->fd set to -1,
- * for the ease of cleaning up.
- */
- obj->fd = -1;
- TAILQ_INSERT_TAIL(&bsdar->v_obj, obj, objs);
- }
- AC(archive_read_close(a));
- AC(archive_read_finish(a));
-}
-
-/*
- * Determine the constitution of resulting archive.
- */
-static void
-write_archive(struct bsdar *bsdar, char mode)
-{
- struct ar_obj *nobj, *obj, *obj_temp, *pos;
- struct stat sb;
- const char *bname;
- char **av;
- int i;
-
- TAILQ_INIT(&bsdar->v_obj);
- nobj = NULL;
- pos = NULL;
- memset(&sb, 0, sizeof(sb));
-
- /* By default, no compression is assumed. */
- bsdar->compression = ARCHIVE_COMPRESSION_NONE;
-
- /*
- * Test if the specified archive exists, to figure out
- * whether we are creating one here.
- */
- if (stat(bsdar->filename, &sb) != 0) {
- if (errno != ENOENT) {
- bsdar_warnc(bsdar, 0, "stat %s failed",
- bsdar->filename);
- return;
- }
-
- /* We do not create archive in mode 'd', 'm' and 's'. */
- if (mode != 'r' && mode != 'q') {
- bsdar_warnc(bsdar, 0, "%s: no such file",
- bsdar->filename);
- return;
- }
-
- /* Issue a warning if -c is not specified when creating. */
- if (!(bsdar->options & AR_C))
- bsdar_warnc(bsdar, 0, "creating %s", bsdar->filename);
- goto new_archive;
- }
-
- /*
- * First read members from existing archive.
- */
- read_objs(bsdar, bsdar->filename, 0);
-
- /*
- * For mode 's', no member will be moved, deleted or replaced.
- */
- if (mode == 's')
- goto write_objs;
-
- /*
- * For mode 'q', we don't need to adjust existing members either.
- * Also, -a, -b and -i are ignored in this mode. New members are
- * always inserted at tail.
- */
- if (mode == 'q')
- goto new_archive;
-
- /*
- * Mode 'A' adds the contents of another archive to the tail of
- * current archive. Note that mode 'A' is a special mode for the
- * ADDLIB command of the ar script mode. Currently there is no
- * access to this function from the ar command line mode.
- */
- if (mode == 'A') {
- /*
- * Read objects from the target archive of ADDLIB command.
- * If there are members spcified in argv, read those members
- * only, otherwise the entire archive will be read.
- */
- read_objs(bsdar, bsdar->addlib, 1);
- goto write_objs;
- }
-
- /*
- * Try to find the position member specified by user.
- */
- if (bsdar->options & AR_A || bsdar->options & AR_B) {
- TAILQ_FOREACH(obj, &bsdar->v_obj, objs) {
- if (strcmp(obj->name, bsdar->posarg) == 0) {
- pos = obj;
- break;
- }
- }
-
- /*
- * If can't find `pos' specified by user,
- * sliently insert objects at tail.
- */
- if (pos == NULL)
- bsdar->options &= ~(AR_A | AR_B);
- }
-
- for (i = 0; i < bsdar->argc; i++) {
- av = &bsdar->argv[i];
-
- TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) {
- if ((bname = basename(*av)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno,
- "basename failed");
- if (bsdar->options & AR_TR) {
- if (strncmp(bname, obj->name, _TRUNCATE_LEN))
- continue;
- } else
- if (strcmp(bname, obj->name) != 0)
- continue;
-
- if (mode == 'r') {
- /*
- * if the new member is not qualified
- * to replace the old one, skip it.
- */
- nobj = create_obj_from_file(bsdar, *av,
- obj->mtime);
- if (nobj == NULL)
- goto skip_obj;
- }
-
- if (bsdar->options & AR_V)
- (void)fprintf(stdout, "%c - %s\n", mode,
- *av);
-
- TAILQ_REMOVE(&bsdar->v_obj, obj, objs);
- if (mode == 'd' || mode == 'r') {
- free(obj->maddr);
- free(obj->name);
- free(obj);
- }
-
- if (mode == 'm')
- insert_obj(bsdar, obj, pos);
- if (mode == 'r')
- insert_obj(bsdar, nobj, pos);
-
- skip_obj:
- *av = NULL;
- break;
- }
-
- }
-
-new_archive:
- /*
- * When operating in mode 'r', directly add those user specified
- * objects which do not exist in current archive. When operating
- * in mode 'q', all objects specified in command line args are
- * appended to the archive, without comparing with existing ones.
- */
- for (i = 0; i < bsdar->argc; i++) {
- av = &bsdar->argv[i];
- if (*av != NULL && (mode == 'r' || mode == 'q')) {
- nobj = create_obj_from_file(bsdar, *av, 0);
- if (nobj != NULL)
- insert_obj(bsdar, nobj, pos);
- if (bsdar->options & AR_V && nobj != NULL)
- (void)fprintf(stdout, "a - %s\n", *av);
- *av = NULL;
- }
- }
-
-write_objs:
- write_objs(bsdar);
- write_cleanup(bsdar);
-}
-
-/*
- * Memory cleaning up.
- */
-static void
-write_cleanup(struct bsdar *bsdar)
-{
- struct ar_obj *obj, *obj_temp;
-
- TAILQ_FOREACH_SAFE(obj, &bsdar->v_obj, objs, obj_temp) {
- if (obj->fd == -1)
- free(obj->maddr);
- else
- if (obj->maddr != NULL && munmap(obj->maddr, obj->size))
- bsdar_warnc(bsdar, errno,
- "can't munmap file: %s", obj->name);
- TAILQ_REMOVE(&bsdar->v_obj, obj, objs);
- free(obj->name);
- free(obj);
- }
-
- free(bsdar->as);
- free(bsdar->s_so);
- free(bsdar->s_sn);
- bsdar->as = NULL;
- bsdar->s_so = NULL;
- bsdar->s_sn = NULL;
-}
-
-/*
- * Wrapper for archive_write_data().
- */
-static void
-write_data(struct bsdar *bsdar, struct archive *a, const void *buf, size_t s)
-{
- if (archive_write_data(a, buf, s) != (ssize_t)s)
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "%s",
- archive_error_string(a));
-}
-
-/*
- * Write the resulting archive members.
- */
-static void
-write_objs(struct bsdar *bsdar)
-{
- struct ar_obj *obj;
- struct archive *a;
- struct archive_entry *entry;
- size_t s_sz; /* size of archive symbol table. */
- size_t pm_sz; /* size of pseudo members */
- int i, nr;
-
- if (elf_version(EV_CURRENT) == EV_NONE)
- bsdar_errc(bsdar, EX_SOFTWARE, 0,
- "ELF library initialization failed: %s", elf_errmsg(-1));
-
- bsdar->rela_off = 0;
-
- /* Create archive symbol table and archive string table, if need. */
- TAILQ_FOREACH(obj, &bsdar->v_obj, objs) {
- if (!(bsdar->options & AR_SS) && obj->maddr != NULL)
- create_symtab_entry(bsdar, obj->maddr, obj->size);
- if (strlen(obj->name) > _MAXNAMELEN_SVR4)
- add_to_ar_str_table(bsdar, obj->name);
- bsdar->rela_off += _ARHDR_LEN + obj->size + obj->size % 2;
- }
-
- /*
- * Pad the symbol name string table. It is treated specially because
- * symbol name table should be padded by a '\0', not the common '\n'
- * for other members. The size of sn table includes the pad bit.
- */
- if (bsdar->s_cnt != 0 && bsdar->s_sn_sz % 2 != 0)
- bsdar->s_sn[bsdar->s_sn_sz++] = '\0';
-
- /*
- * Archive string table is padded by a "\n" as the normal members.
- * The difference is that the size of archive string table counts
- * in the pad bit, while normal members' size fileds do not.
- */
- if (bsdar->as != NULL && bsdar->as_sz % 2 != 0)
- bsdar->as[bsdar->as_sz++] = '\n';
-
- /*
- * If there is a symbol table, calculate the size of pseudo members,
- * convert previously stored relative offsets to absolute ones, and
- * then make them Big Endian.
- *
- * absolute_offset = htobe32(relative_offset + size_of_pseudo_members)
- */
-
- if (bsdar->s_cnt != 0) {
- s_sz = (bsdar->s_cnt + 1) * sizeof(uint32_t) + bsdar->s_sn_sz;
- pm_sz = _ARMAG_LEN + (_ARHDR_LEN + s_sz);
- if (bsdar->as != NULL)
- pm_sz += _ARHDR_LEN + bsdar->as_sz;
- for (i = 0; (size_t)i < bsdar->s_cnt; i++)
- *(bsdar->s_so + i) = htobe32(*(bsdar->s_so + i) +
- pm_sz);
- }
-
- if ((a = archive_write_new()) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, 0, "archive_write_new failed");
-
- archive_write_set_format_ar_svr4(a);
-
- /* The compression mode of the existing archive is used
- * for the result archive or if creating a new archive, we
- * do not compress archive by default. This default behavior can
- * be overrided by compression mode specified explicitly
- * through command line option `-j' or `-z'.
- */
- if (bsdar->options & AR_J)
- bsdar->compression = ARCHIVE_COMPRESSION_BZIP2;
- if (bsdar->options & AR_Z)
- bsdar->compression = ARCHIVE_COMPRESSION_GZIP;
- if (bsdar->compression == ARCHIVE_COMPRESSION_BZIP2)
- archive_write_set_compression_bzip2(a);
- else if (bsdar->compression == ARCHIVE_COMPRESSION_GZIP)
- archive_write_set_compression_gzip(a);
- else
- archive_write_set_compression_none(a);
-
- AC(archive_write_open_filename(a, bsdar->filename));
-
- /*
- * write the archive symbol table, if there is one.
- * If options -s is explicitly specified or we are invoked
- * as ranlib, write the symbol table even if it is empty.
- */
- if ((bsdar->s_cnt != 0 && !(bsdar->options & AR_SS)) ||
- bsdar->options & AR_S) {
- entry = archive_entry_new();
- archive_entry_copy_pathname(entry, "/");
- archive_entry_set_mtime(entry, time(NULL), 0);
- archive_entry_set_size(entry, (bsdar->s_cnt + 1) *
- sizeof(uint32_t) + bsdar->s_sn_sz);
- AC(archive_write_header(a, entry));
- nr = htobe32(bsdar->s_cnt);
- write_data(bsdar, a, &nr, sizeof(uint32_t));
- write_data(bsdar, a, bsdar->s_so, sizeof(uint32_t) *
- bsdar->s_cnt);
- write_data(bsdar, a, bsdar->s_sn, bsdar->s_sn_sz);
- archive_entry_free(entry);
- }
-
- /* write the archive string table, if any. */
- if (bsdar->as != NULL) {
- entry = archive_entry_new();
- archive_entry_copy_pathname(entry, "//");
- archive_entry_set_size(entry, bsdar->as_sz);
- AC(archive_write_header(a, entry));
- write_data(bsdar, a, bsdar->as, bsdar->as_sz);
- archive_entry_free(entry);
- }
-
- /* write normal members. */
- TAILQ_FOREACH(obj, &bsdar->v_obj, objs) {
- entry = archive_entry_new();
- archive_entry_copy_pathname(entry, obj->name);
- archive_entry_set_uid(entry, obj->uid);
- archive_entry_set_gid(entry, obj->gid);
- archive_entry_set_mode(entry, obj->md);
- archive_entry_set_size(entry, obj->size);
- archive_entry_set_mtime(entry, obj->mtime, 0);
- archive_entry_set_dev(entry, obj->dev);
- archive_entry_set_ino(entry, obj->ino);
- archive_entry_set_filetype(entry, AE_IFREG);
- AC(archive_write_header(a, entry));
- write_data(bsdar, a, obj->maddr, obj->size);
- archive_entry_free(entry);
- }
-
- AC(archive_write_close(a));
- AC(archive_write_finish(a));
-}
-
-/*
- * Extract global symbols from ELF binary members.
- */
-static void
-create_symtab_entry(struct bsdar *bsdar, void *maddr, size_t size)
-{
- Elf *e;
- Elf_Scn *scn;
- GElf_Shdr shdr;
- GElf_Sym sym;
- Elf_Data *data;
- char *name;
- size_t n, shstrndx;
- int elferr, tabndx, len, i;
-
- if ((e = elf_memory(maddr, size)) == NULL) {
- bsdar_warnc(bsdar, 0, "elf_memory() failed: %s",
- elf_errmsg(-1));
- return;
- }
- if (elf_kind(e) != ELF_K_ELF) {
- /* Sliently ignore non-elf member. */
- elf_end(e);
- return;
- }
- if (elf_getshstrndx(e, &shstrndx) == 0) {
- bsdar_warnc(bsdar, EX_SOFTWARE, 0, "elf_getshstrndx failed: %s",
- elf_errmsg(-1));
- elf_end(e);
- return;
- }
-
- tabndx = -1;
- scn = NULL;
- while ((scn = elf_nextscn(e, scn)) != NULL) {
- if (gelf_getshdr(scn, &shdr) != &shdr) {
- bsdar_warnc(bsdar, 0,
- "elf_getshdr failed: %s", elf_errmsg(-1));
- continue;
- }
- if ((name = elf_strptr(e, shstrndx, shdr.sh_name)) == NULL) {
- bsdar_warnc(bsdar, 0,
- "elf_strptr failed: %s", elf_errmsg(-1));
- continue;
- }
- if (strcmp(name, ".strtab") == 0) {
- tabndx = elf_ndxscn(scn);
- break;
- }
- }
- elferr = elf_errno();
- if (elferr != 0)
- bsdar_warnc(bsdar, 0, "elf_nextscn failed: %s",
- elf_errmsg(elferr));
- if (tabndx == -1) {
- bsdar_warnc(bsdar, 0, "can't find .strtab section");
- elf_end(e);
- return;
- }
-
- scn = NULL;
- while ((scn = elf_nextscn(e, scn)) != NULL) {
- if (gelf_getshdr(scn, &shdr) != &shdr) {
- bsdar_warnc(bsdar, EX_SOFTWARE, 0,
- "elf_getshdr failed: %s", elf_errmsg(-1));
- continue;
- }
- if (shdr.sh_type != SHT_SYMTAB)
- continue;
-
- data = NULL;
- n = 0;
- while (n < shdr.sh_size &&
- (data = elf_getdata(scn, data)) != NULL) {
- len = data->d_size / shdr.sh_entsize;
- for (i = 0; i < len; i++) {
- if (gelf_getsym(data, i, &sym) != &sym) {
- bsdar_warnc(bsdar, EX_SOFTWARE, 0,
- "gelf_getsym failed: %s",
- elf_errmsg(-1));
- continue;
- }
-
- /* keep only global or weak symbols */
- if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL &&
- GELF_ST_BIND(sym.st_info) != STB_WEAK)
- continue;
-
- /* keep only defined symbols */
- if (sym.st_shndx == SHN_UNDEF)
- continue;
-
- if ((name = elf_strptr(e, tabndx,
- sym.st_name)) == NULL) {
- bsdar_warnc(bsdar, EX_SOFTWARE, 0,
- "elf_strptr failed: %s",
- elf_errmsg(-1));
- continue;
- }
-
- add_to_ar_sym_table(bsdar, name);
- }
- }
- }
- elferr = elf_errno();
- if (elferr != 0)
- bsdar_warnc(bsdar, EX_SOFTWARE, 0, "elf_nextscn failed: %s",
- elf_errmsg(elferr));
-
- elf_end(e);
-}
-
-/*
- * Append to the archive string table buffer.
- */
-static void
-add_to_ar_str_table(struct bsdar *bsdar, const char *name)
-{
-
- if (bsdar->as == NULL) {
- bsdar->as_cap = _INIT_AS_CAP;
- bsdar->as_sz = 0;
- if ((bsdar->as = malloc(bsdar->as_cap)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- }
-
- /*
- * The space required for holding one member name in as table includes:
- * strlen(name) + (1 for '/') + (1 for '\n') + (possibly 1 for padding).
- */
- while (bsdar->as_sz + strlen(name) + 3 > bsdar->as_cap) {
- bsdar->as_cap *= 2;
- bsdar->as = realloc(bsdar->as, bsdar->as_cap);
- if (bsdar->as == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "realloc failed");
- }
- strncpy(&bsdar->as[bsdar->as_sz], name, strlen(name));
- bsdar->as_sz += strlen(name);
- bsdar->as[bsdar->as_sz++] = '/';
- bsdar->as[bsdar->as_sz++] = '\n';
-}
-
-/*
- * Append to the archive symbol table buffer.
- */
-static void
-add_to_ar_sym_table(struct bsdar *bsdar, const char *name)
-{
-
- if (bsdar->s_so == NULL) {
- if ((bsdar->s_so = malloc(_INIT_SYMOFF_CAP)) ==
- NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- bsdar->s_so_cap = _INIT_SYMOFF_CAP;
- bsdar->s_cnt = 0;
- }
-
- if (bsdar->s_sn == NULL) {
- if ((bsdar->s_sn = malloc(_INIT_SYMNAME_CAP)) == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "malloc failed");
- bsdar->s_sn_cap = _INIT_SYMNAME_CAP;
- bsdar->s_sn_sz = 0;
- }
-
- if (bsdar->s_cnt * sizeof(uint32_t) >= bsdar->s_so_cap) {
- bsdar->s_so_cap *= 2;
- bsdar->s_so = realloc(bsdar->s_so, bsdar->s_so_cap);
- if (bsdar->s_so == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "realloc failed");
- }
- bsdar->s_so[bsdar->s_cnt] = bsdar->rela_off;
- bsdar->s_cnt++;
-
- /*
- * The space required for holding one symbol name in sn table includes:
- * strlen(name) + (1 for '\n') + (possibly 1 for padding).
- */
- while (bsdar->s_sn_sz + strlen(name) + 2 > bsdar->s_sn_cap) {
- bsdar->s_sn_cap *= 2;
- bsdar->s_sn = realloc(bsdar->s_sn, bsdar->s_sn_cap);
- if (bsdar->s_sn == NULL)
- bsdar_errc(bsdar, EX_SOFTWARE, errno, "realloc failed");
- }
- strncpy(&bsdar->s_sn[bsdar->s_sn_sz], name, strlen(name));
- bsdar->s_sn_sz += strlen(name);
- bsdar->s_sn[bsdar->s_sn_sz++] = '\0';
-}
OpenPOWER on IntegriCloud