ref: 73a6628e17cff58f721f995f3ce533432e6703fe
parent: f3d06fb5d6fc6d3540f693f883c90c50141fc6f1
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Thu Feb 15 17:31:40 EST 2018
[ar] Improve -m implementation This implementation should worl, but it is not tested and a lot of different things would happen.
--- a/ar/main.c
+++ b/ar/main.c
@@ -21,6 +21,7 @@
struct arop {
FILE *src;
FILE *dst;
+ FILE *tmp;
struct ar_hdr hdr;
char *fname;
long size;
@@ -144,20 +145,33 @@
}
static void
-copy(struct arop *op)
+cat(FILE *src1, FILE *src2, FILE *dst)
{
int c;
- long siz, n;
- struct ar_hdr *hdr = &op->hdr;
- fwrite(hdr, sizeof(*hdr), 1, op->dst);
- siz = op->size;
+ while ((c = getc(src1)) != EOF)
+ fputc(c, dst);
+ while ((c = getc(src2)) != EOF)
+ fputc(c, dst);
+ if (ferror(src1) || ferror(src2) || fclose(dst) == EOF) {
+ perror("ar:moving files in archive");
+ exit(1);
+ }
+}
+
+static void
+copy(struct ar_hdr *hdr, long siz, FILE *src, FILE *dst)
+{
+ int c;
+ long n;
+
+ fwrite(hdr, sizeof(*hdr), 1, dst);
if ((siz & 1) == 1)
siz++;
while (siz--) {
- if ((c = getc(op->src)) == EOF)
+ if ((c = getc(src)) == EOF)
break;
- fputc(c, op->dst);
+ fputc(c, dst);
}
}
@@ -200,8 +214,18 @@
}
static void
-filter(struct arop *op, char *list[])
+split(struct arop *op, char *files[])
{
+ char **l;
+
+ l = inlist(op->fname, files);
+ if (!l) {
+ copy(&op->hdr, op->size, op->src, op->dst);
+ return;
+ } else {
+ copy(&op->hdr, op->size, op->src, op->tmp);
+ rmlist(l);
+ }
}
static void
@@ -213,15 +237,15 @@
insert(struct arop *op, char *list[])
{
if (!posname || strcmp(op->fname, posname)) {
- copy(op);
+ copy(&op->hdr, op->size, op->src, op->dst);
return;
}
if (bflag || iflag) {
for ( ; *list; ++list)
archive(*list, op->dst, 'a');
- copy(op);
+ copy(&op->hdr, op->size, op->src, op->dst);
} else {
- copy(op);
+ copy(&op->hdr, op->size, op->src, op->dst);
for ( ; *list; ++list)
archive(*list, op->dst, 'a');
}
@@ -234,7 +258,7 @@
l = inlist(op->fname, files);
if (!l) {
- copy(op);
+ copy(&op->hdr, op->size, op->src, op->dst);
return;
}
archive(op->fname, op->dst, 'r');
@@ -321,7 +345,7 @@
printf("d - %s\n", op->fname);
return;
}
- copy(op);
+ copy(&op->hdr, op->size, op->src, op->dst);
}
static char *
@@ -389,6 +413,7 @@
op.src = fp;
op.dst = tmp1;
+ op.dst = tmp2;
while (!ferror(fp) && fread(&op.hdr, sizeof(op.hdr), 1, fp) == 1) {
fpos_t pos;
@@ -456,7 +481,7 @@
if (lflag) {
*dst = fname;
- tmp = fopen(fname, "wb");
+ tmp = fopen(fname, "w+b");
} else {
tmp = tmpfile();
}
@@ -481,7 +506,7 @@
{
int key, nkey = 0, pos = 0;
char *afile;
- FILE *fp, *tmp1, *tmp2;;
+ FILE *fp, *tmp1, *tmp2;
atexit(cleanup);
ARGBEGIN {
@@ -602,9 +627,22 @@
case 'm':
tmp1 = opentmp("ar.tmp1", &tmpafile1);
tmp2 = opentmp("ar.tmp2", &tmpafile2);
- run(fp, tmp1, NULL, argv, filter);
+ run(fp, tmp1, tmp2, argv, split);
+
+ if (*argv) {
+ fprintf(stderr, "ar: entry '%s' not found\n", *argv);
+ exit(1);
+ }
+ fp = openar(afile);
fseek(tmp1, SARMAG, SEEK_SET);
- run(tmp1, tmp2, NULL, NULL, merge);
+ fseek(tmp2, SARMAG, SEEK_SET);
+ if (!posname) {
+ cat(tmp1, tmp2, fp);
+ break;
+ }
+ run(tmp1, fp, tmp2, NULL, merge);
+ closetmp(tmp1, &tmpafile1, NULL);
+ closetmp(tmp2, &tmpafile2, NULL);
break;
}