GNU ar did NOT implment option -q as a synonym of -r as the manual

page stated, thus BSD ar(1) option -q, which was implemented based on
the GNU ar manual page, turns out to be incompatible with GNU ar -q.

This change will make BSD ar(1) -q a *REAL* GNU ar -q:

1. It will update symbol table. (same as unfixed version)
2. It will NOT compare new members spcified in the command line args
   with existing members, instead, append them directly.

Reported by:	  Johannes 5 Joemann <joemann@beefree.free.de>
Reported by:	  Timothy Bourke <timbob@bigpond.com>
Tested by:	  Johannes 5 Joemann <joemann@beefree.free.de>
Reviewed by:	  jkoshy
Approved by:	  jkoshy (mentor)
This commit is contained in:
Kai Wang 2008-03-11 18:35:51 +00:00
parent 8c3ec67375
commit cb0dad38e4
4 changed files with 25 additions and 6 deletions

View File

@ -225,9 +225,9 @@ If the archive file
does not already exist, a new archive is created.
However, to be compatible with GNU
.Nm ,
option
.Fl q
is implemented as a synonym for
.Fl r .
will update the archive's symbol table.
.It Fl r
Replace (add) the files specified by arguments
.Ar files ...

View File

@ -294,7 +294,7 @@ main(int argc, char **argv)
ar_mode_p(bsdar);
break;
case 'q':
ar_mode_r(bsdar);
ar_mode_q(bsdar);
break;
case 'r':
ar_mode_r(bsdar);
@ -345,6 +345,7 @@ bsdar_usage()
(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");

View File

@ -115,6 +115,7 @@ 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);

View File

@ -80,6 +80,13 @@ 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)
{
@ -247,7 +254,7 @@ write_archive(struct bsdar *bsdar, char mode)
}
/* We do not create archive in mode 'd', 'm' and 's'. */
if (mode != 'r') {
if (mode != 'r' && mode != 'q') {
bsdar_warnc(bsdar, 0, "%s: no such file",
bsdar->filename);
return;
@ -341,6 +348,14 @@ write_archive(struct bsdar *bsdar, char mode)
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;
/*
* Try to find the position member specified by user.
*/
@ -411,11 +426,13 @@ write_archive(struct bsdar *bsdar, char mode)
new_archive:
/*
* When operating in mode 'r', directly add those user specified
* objects which do not exist in current archive.
* 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') {
if (*av != NULL && (mode == 'r' || mode == 'q')) {
nobj = create_obj_from_file(bsdar, *av, 0);
if (nobj != NULL)
insert_obj(bsdar, nobj, pos);