ref: 458a063eb092b36470332d6418a3dde377e8e2be
parent: fe9bac1eb738478ab7335626802ae4b954454dc1
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Feb 13 09:42:29 EST 2018
[ar] Add extract key
--- a/ar/main.c
+++ b/ar/main.c
@@ -23,6 +23,7 @@
FILE *dst;
struct ar_hdr hdr;
char *fname;
+ long size;
};
static void
@@ -138,7 +139,7 @@
}
static void
-copymember(char *fname, struct ar_hdr *hdr, FILE *dst, FILE *src)
+copy(char *fname, struct ar_hdr *hdr, FILE *dst, FILE *src)
{
int c;
long siz, n;
@@ -210,6 +211,37 @@
}
static void
+extract(struct arop *op, char *files[])
+{
+ int c;
+ long siz;
+ FILE *fp;
+
+ if (*files && !inlist(op->fname, files))
+ return;
+ if (vflag)
+ printf("x - %s\n", op->fname);
+ siz = op->size;
+
+ if ((fp = fopen(op->fname, "wb")) == NULL)
+ goto error_file;
+ while (siz-- > 0 && (c = getc(op->src)) != EOF)
+ putc(c, fp);
+ fflush(fp);
+ if (ferror(op->src) || ferror(fp))
+ goto error_file;
+ fclose(fp);
+
+ /* TODO: set attributes */
+ return;
+
+
+error_file:
+ perror("ar:error extracting file");
+ exit(1);
+}
+
+static void
print(struct arop *op, char *files[])
{
long siz;
@@ -219,11 +251,7 @@
return;
if (vflag)
printf("\n<%s>\n\n", op->fname);
- siz = atol(op->hdr.ar_size);
- if (siz < 0) {
- fputs("ar:corrupted member\n", stderr);
- exit(1);
- }
+ siz = op->size;
while (siz-- > 0 && (c = getc(op->src)) != EOF)
putchar(c);
}
@@ -264,7 +292,7 @@
{
if (inlist(op->fname, files))
return;
- copymember(op->fname, &op->hdr, op->dst, op->src);
+ copy(op->fname, &op->hdr, op->dst, op->src);
}
static char *
@@ -292,11 +320,9 @@
op.dst = tmp;
while (!ferror(fp) && fread(&op.hdr, sizeof(op.hdr), 1, fp) == 1) {
fpos_t pos;
- long len;
- char *fname;
if (strncmp(op.hdr.ar_fmag, ARFMAG, sizeof(op.hdr.ar_fmag)) ||
- (len = atol(op.hdr.ar_size)) < 0) {
+ (op.size = atol(op.hdr.ar_size)) < 0) {
fputs("ar:corrupted member\n", stderr);
exit(1);
}
@@ -304,7 +330,7 @@
fgetpos(fp, &pos);
(*fun)(&op, files);
fsetpos(fp, &pos);
- fseek(fp, len+1 & ~1, SEEK_CUR);
+ fseek(fp, op.size+1 & ~1, SEEK_CUR);
}
if (ferror(fp)) {
perror("ar:reading members");
@@ -472,9 +498,13 @@
case 'p':
tmp = NULL;
fun = print;
+ break;
+ case 'x':
+ tmp = NULL;
+ fun = extract;
+ break;
case 'r':
case 'm':
- case 'x':
/* TODO */
;
}