Whoever wrote the tar command line argument parsing code didn't realize

that the order of arguments is different if the command flags are specified
without a `-'.  I've integrated getoldopt.c from John Gilmore's pdtar which
handles argument parsing correctly.
This commit is contained in:
jtc 1994-06-14 01:16:02 +00:00
parent cb16e0c4cc
commit eb06615913
3 changed files with 84 additions and 30 deletions

View File

@ -1,5 +1,5 @@
# from: @(#)Makefile 8.1 (Berkeley) 5/31/93
# $Id: Makefile,v 1.2 1994/06/13 16:33:34 jtc Exp $
# $Id: Makefile,v 1.3 1994/06/14 01:16:02 jtc Exp $
# To install on versions prior to BSD 4.4 the following may have to be
# defined with CFLAGS +=
@ -27,7 +27,7 @@
PROG= pax
SRCS= ar_io.c ar_subs.c buf_subs.c cache.c cpio.c file_subs.c ftree.c\
gen_subs.c options.c pat_rep.c pax.c sel_subs.c tables.c tar.c\
tty_subs.c
gen_subs.c getoldopt.c options.c pat_rep.c pax.c sel_subs.c tables.c\
tar.c tty_subs.c
.include <bsd.prog.mk>

69
bin/pax/getoldopt.c Normal file
View File

@ -0,0 +1,69 @@
/*
* Plug-compatible replacement for getopt() for parsing tar-like
* arguments. If the first argument begins with "-", it uses getopt;
* otherwise, it uses the old rules used by tar, dump, and ps.
*
* Written 25 August 1985 by John Gilmore (ihnp4!hoptoad!gnu) and placed
* in the Pubic Domain for your edification and enjoyment.
*/
#ifndef lint
static char *rcsid = "$Id: getoldopt.c,v 1.1 1994/06/14 01:16:07 jtc Exp $";
#endif /* not lint */
#include <stdio.h>
#include <string.h>
int
getoldopt(argc, argv, optstring)
int argc;
char **argv;
char *optstring;
{
extern char *optarg; /* Points to next arg */
extern int optind; /* Global argv index */
static char *key; /* Points to next keyletter */
static char use_getopt; /* !=0 if argv[1][0] was '-' */
char c;
char *place;
optarg = NULL;
if (key == NULL) { /* First time */
if (argc < 2) return EOF;
key = argv[1];
if (*key == '-')
use_getopt++;
else
optind = 2;
}
if (use_getopt)
return getopt(argc, argv, optstring);
c = *key++;
if (c == '\0') {
key--;
return EOF;
}
place = strchr(optstring, c);
if (place == NULL || c == ':') {
fprintf(stderr, "%s: unknown option %c\n", argv[0], c);
return('?');
}
place++;
if (*place == ':') {
if (optind < argc) {
optarg = argv[optind];
optind++;
} else {
fprintf(stderr, "%s: %c argument missing\n",
argv[0], c);
return('?');
}
}
return(c);
}

View File

@ -37,7 +37,7 @@
#ifndef lint
/*static char sccsid[] = "from: @(#)options.c 8.2 (Berkeley) 4/18/94";*/
static char *rcsid = "$Id: options.c,v 1.3 1994/06/14 00:42:47 mycroft Exp $";
static char *rcsid = "$Id: options.c,v 1.4 1994/06/14 01:16:10 jtc Exp $";
#endif /* not lint */
#include <sys/types.h>
@ -583,35 +583,23 @@ tar_options(argc, argv)
register char **argv;
#endif
{
register char *cp;
register int c;
int fstdin = 0;
if (argc < 2)
tar_usage();
/*
* process option flags
*/
++argv;
for (cp = *argv++; *cp != '\0'; ++cp) {
switch (*cp) {
case '-':
/*
* skip over -
*/
break;
while ((c = getoldopt(argc, argv, "b:cef:moprutvwxBHLPX014578"))
!= EOF) {
switch(c) {
case 'b':
/*
* specify blocksize
*/
if (*argv == (char *)NULL) {
warn(1,"blocksize must be specified with 'b'");
if ((wrblksz = (int)str_offt(optarg)) <= 0) {
warn(1, "Invalid block size %s", optarg);
tar_usage();
}
if ((wrblksz = (int)str_offt(*argv)) <= 0) {
warn(1, "Invalid block size %s", *argv);
tar_usage();
}
++argv;
break;
case 'c':
/*
@ -629,21 +617,16 @@ tar_options(argc, argv)
/*
* filename where the archive is stored
*/
if (*argv == (char *)NULL) {
warn(1, "filename must be specified with 'f'");
tar_usage();
}
if ((argv[0][0] == '-') && (argv[0][1]== '\0')) {
if ((optarg[0] == '-') && (optarg[1]== '\0')) {
/*
* treat a - as stdin
*/
++argv;
++fstdin;
fstdin = 1;
arcname = (char *)0;
break;
}
fstdin = 0;
arcname = *argv++;
arcname = optarg;
break;
case 'm':
/*
@ -748,6 +731,8 @@ tar_options(argc, argv)
break;
}
}
argc -= optind;
argv += optind;
/*
* if we are writing (ARCHIVE) specify tar, otherwise run like pax