#ifndef lint
#if 0
static char copyright[] =
"@(#) Copyright (c) 1990, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid[] = "@(#)ar.c 8.3 (Berkeley) 4/2/94";
static char rcsid[] = "$OpenBSD: ar.c,v 1.3 1997/01/15 23:42:11 millert Exp $";
#endif
#endif
#include <sys/param.h>
#include <ar.h>
#include <dirent.h>
#include <err.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "archive.h"
#include "extern.h"
#include "stuff/execute.h"
#include "stuff/unix_standard_mode.h"
CHDR chdr;
u_int options;
char *archive, *envtmp, *posarg, *posname;
static void badoptions __P((char *));
static void usage __P((void));
char *progname;
int
main(argc, argv)
int argc;
char **argv;
{
int c, retval, verbose, run_ranlib;
char *p;
int (*fcall) __P((char **));
fcall = 0;
verbose = 0;
progname = argv[0];
run_ranlib = 1;
if (argc < 3)
usage();
if (*argv[1] != '-') {
if (!(p = malloc((u_int)(strlen(argv[1]) + 2))))
err(1, NULL);
*p = '-';
(void)strcpy(p + 1, argv[1]);
argv[1] = p;
}
while ((c = getopt(argc, argv, "abcdilLmopqrSsTtuVvx")) != -1) {
switch(c) {
case 'a':
options |= AR_A;
break;
case 'b':
case 'i':
options |= AR_B;
break;
case 'c':
options |= AR_C;
break;
case 'd':
options |= AR_D;
fcall = delete;
break;
case 'l':
envtmp = ".";
break;
case 'L':
options &= ~AR_TR;
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':
options |= AR_Q;
fcall = append;
break;
case 'r':
options |= AR_R;
fcall = replace;
break;
case 's':
options |= AR_S;
break;
case 'S':
options &= ~AR_S;
run_ranlib = 0;
break;
case 'T':
options |= AR_TR;
break;
case 't':
options |= AR_T;
fcall = contents;
break;
case 'u':
options |= AR_U;
break;
case 'V':
verbose = 1;
break;
case 'v':
options |= AR_V;
break;
case 'x':
options |= AR_X;
fcall = extract;
break;
default:
usage();
}
}
argv += optind;
argc -= optind;
if (!(options & (AR_D|AR_M|AR_P|AR_Q|AR_R|AR_S|AR_T|AR_X))) {
warnx("one of options -dmpqrtsx is required");
usage();
}
if (options & AR_A && options & AR_B) {
warnx("only one of -a and -[bi] options allowed");
usage();
}
if (options & (AR_A|AR_B)) {
if (!(posarg = *argv++)) {
warnx("no position operand specified");
usage();
}
posname = rname(posarg);
}
if (options & AR_D && options & ~(AR_D|AR_TR|AR_S|AR_V))
badoptions("-d");
if (options & AR_M && options & ~(AR_A|AR_B|AR_M|AR_TR|AR_S|AR_V))
badoptions("-m");
if (options & AR_P && options & ~(AR_P|AR_TR|AR_S|AR_V))
badoptions("-p");
if (options & AR_Q && options & ~(AR_C|AR_Q|AR_TR|AR_S|AR_V))
badoptions("-q");
if (options & AR_R && options & ~(AR_A|AR_B|AR_C|AR_R|AR_U|AR_TR|AR_S|AR_V))
badoptions("-r");
if (options & AR_T && options & ~(AR_T|AR_TR|AR_S|AR_V))
badoptions("-t");
if (options & AR_X && options & ~(AR_O|AR_U|AR_TR|AR_S|AR_V|AR_X))
badoptions("-x");
if (!(archive = *argv++)) {
warnx("no archive specified");
usage();
}
if (options & (AR_D|AR_M|AR_Q|AR_R) && !*argv) {
warnx("no archive members specified");
usage();
}
if(fcall != 0){
retval = (*fcall)(argv);
if(retval != EXIT_SUCCESS ||
((options & AR_S) != AR_S &&
(get_unix_standard_mode() == FALSE ||
archive_opened_for_writing == 0)))
exit(retval);
}
if(run_ranlib){
reset_execute_list();
add_execute_list_with_prefix("ranlib");
if(options & AR_S)
add_execute_list("-f");
else
add_execute_list("-q");
add_execute_list(archive);
if(execute_list(verbose) == 0){
(void)fprintf(stderr, "%s: internal ranlib command failed\n",
progname);
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
static void
badoptions(arg)
char *arg;
{
warnx("illegal option combination for %s", arg);
usage();
}
static void
usage()
{
(void)fprintf(stderr, "usage: ar -d [-TLsv] archive file ...\n");
(void)fprintf(stderr, "\tar -m [-TLsv] archive file ...\n");
(void)fprintf(stderr, "\tar -m [-abiTLsv] position archive file ...\n");
(void)fprintf(stderr, "\tar -p [-TLsv] archive [file ...]\n");
(void)fprintf(stderr, "\tar -q [-cTLsv] archive file ...\n");
(void)fprintf(stderr, "\tar -r [-cuTLsv] archive file ...\n");
(void)fprintf(stderr, "\tar -r [-abciuTLsv] position archive file ...\n");
(void)fprintf(stderr, "\tar -t [-TLsv] archive [file ...]\n");
(void)fprintf(stderr, "\tar -x [-ouTLsv] archive [file ...]\n");
exit(1);
}