shithub: scc

Download patch

ref: eeec7382051ef8c9e894e7c229dfe0dfb2ea2921
parent: 039acf988f466547db782f2d96a4c0a2a251e9e7
parent: 040a49dbae747a2b7bd56c50e65a4ccc08af1253
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Feb 16 03:24:19 EST 2018

Merge branch 'master' of ssh://simple-cc.org:/var/gitrepos/scc

--- 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;
@@ -49,7 +50,6 @@
 {
 	FILE *fp;
 	char magic[SARMAG+1];
-	struct stat st;
 
 	if ((fp = fopen(afile,"rb")) == NULL) {
 		if (!cflag)
@@ -111,7 +111,7 @@
 	        st.st_uid,
 	        st.st_gid,
 	        st.st_mode,
-	        st.st_size);
+	        (unsigned long long) st.st_size);
 	for (n = 0; (c = getc(from)) != EOF; n++)
 		putc(c, to);
 	if (n & 1)
@@ -144,20 +144,32 @@
 }
 
 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;
+
+	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 +212,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 +235,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 +256,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');
@@ -290,7 +312,6 @@
 static void
 list(struct arop *op, char *files[])
 {
-	long long val;
 	time_t t;
 	struct ar_hdr *hdr = &op->hdr;
 	char mtime[30];
@@ -297,14 +318,12 @@
 
 	if (*files && !inlist(op->fname, files))
 		return;
-	if (!print)
-		return;
 	if (!vflag) {
 		printf("%s\n", op->fname);
 	} else {
 		t = totime(op->date);
 		strftime(mtime, sizeof(mtime), "%c", localtime(&t));
-		printf("%s %d/%d\t%s %s\n",
+		printf("%s %ld/%ld\t%s %s\n",
 		       perms(op),
 		       atol(hdr->ar_uid),
 		       atol(hdr->ar_gid),
@@ -321,7 +340,7 @@
 			printf("d - %s\n", op->fname);
 		return;
 	}
-	copy(op);
+	copy(&op->hdr, op->size, op->src, op->dst);
 }
 
 static char *
@@ -389,6 +408,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 +476,7 @@
 
 	if (lflag) {
 		*dst = fname;
-		tmp = fopen(fname, "wb");
+		tmp = fopen(fname, "w+b");
 	} else {
 		tmp = tmpfile();
 	}
@@ -529,11 +549,25 @@
 	case 'm':
 		tmp1 = opentmp("ar.tmp1", &tmpafile1);
 		tmp2 = opentmp("ar.tmp2", &tmpafile2);
-		run(fp, tmp1, NULL, flist, filter);
+		run(fp, tmp1, tmp2, flist, split);
+
+		if (*flist) {
+			fprintf(stderr, "ar: entry '%s' not found\n", *flist);
+			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;
 	}
+
 }
 
 int
@@ -541,7 +575,6 @@
 {
 	int key, nkey = 0, pos = 0;
 	char *afile;
-	FILE *fp;
 
 	atexit(cleanup);
 	ARGBEGIN {