shithub: scc

Download patch

ref: d9e5a799f09e39fed6619ece999d9419fbba6880
parent: 7d55e1d54dde85955f717157deb8797b89e4f1e4
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Fri Nov 24 09:58:15 EST 2017

[ar] Add functions to write ar files

At this moment this functions are placed in the
library but maybe the own ar source code is a
better place since they are not expected to be
used in any other place.

--- a/ar/main.c
+++ b/ar/main.c
@@ -7,6 +7,9 @@
 
 #include <stat.h>
 
+#include "../inc/scc.h"
+#include "../inc/ar.h"
+
 int
 main(int argc, char *argv[])
 {
@@ -15,6 +18,7 @@
 	FILE *fp, *arfile;
 	char *fname, *arname = "lib.a";
 	struct stat st;
+	struct arhdr hdr;
 
 	if ((arfile = fopen(arname, "wb")) == NULL) {
 		perror("ar:error opening library file");
@@ -21,41 +25,24 @@
 		exit(1);
 	}
 
-	fputs("!<arch>\n", arfile);
+	fputs(ARMAGIC, arfile);
 	while ((fname = *++argv) != NULL) {
-		if ((n = strlen(fname)) > 16) {
-			fprintf(stderr, "ar:too long file name '%s'\n", fname);
-			exit(3);
-		}
-		if (stat(fname, &st) < 0) {
-			fprintf(stderr,
-			        "ar:error opening object file '%s':%s\n",
-			        fname, strerror(errno));
-			exit(2);
-		}
-		fprintf(arfile,
-		        "%-16s%-12llu%-6u%-6u%-8o%-10llu`\n",
-		        fname,
-		        (unsigned long long) st.st_atime,
-		        (int) st.st_uid, (int) st.st_gid,
-		        (int) st.st_mode,
-		        (unsigned long long) st.st_size);
-		if ((fp = fopen(fname, "rb")) == NULL) {
-			fprintf(stderr,
-			        "ar: error opening file '%s':%s\n",
-			        fname, strerror(errno));
-			exit(3);
-		}
-		while ((c = getc(fp)) != EOF)
-			putc(c, arfile);
-		if (st.st_size & 1)
-			putc('\n', arfile);
-		if (fclose(fp)) {
-			fprintf(stderr,
-			        "ar:error reading from input file '%s':%s\n",
-			        fname, strerror(errno));
-			exit(4);
-		}
+		if ((n = strlen(fname)) > ARNAME_SIZ)
+			die("ar: %s: too long file name", fname);
+		if (stat(fname, &st) < 0)
+			goto member_error;
+
+		strcpy(hdr.name, fname);
+		hdr.time = st.st_atime;
+		hdr.uid = st.st_uid;
+		hdr.gid = st.st_gid;
+		hdr.mode = st.st_mode;
+		hdr.size = st.st_mode;
+
+		if (wrarhdr(arfile, &hdr) < 0)
+			goto member_error;
+		if (wrarfile(arfile, &hdr) < 0)
+			goto member_error;
 	}
 
 	if (fclose(arfile)) {
@@ -65,4 +52,7 @@
 	}
 
 	return 0;
+
+member_error:
+	die("ar: %s: %s", fname, strerror(errno));
 }
--- a/inc/ar.h
+++ b/inc/ar.h
@@ -1,3 +1,20 @@
 
 #define ARMAGIC       "!<arch>\n"
 #define ARMAGIC_SIZ   8
+
+struct arhdr {
+	char name[17];
+	unsigned long long time;
+	int uid;
+	int gid;
+	int mode;
+	unsigned long long size;
+};
+
+#define ARHDR_SIZ      60
+#define ARNAME_SIZ     16
+#define ARMAGIC        "!<arch>\n"
+#define ARMAGIC_SIZ    8
+
+extern int wrarhdr(FILE *fp, struct arhdr *hdr);
+extern int wrarfile(FILE *fp, struct arhdr *hdr);
--- a/lib/scc/libdep.mk
+++ b/lib/scc/libdep.mk
@@ -11,3 +11,4 @@
           $(LIBDIR)/lpack.o \
           $(LIBDIR)/wmyro.o \
           $(LIBDIR)/rmyro.o \
+          $(LIBDIR)/war.o \
--- /dev/null
+++ b/lib/scc/war.c
@@ -1,0 +1,38 @@
+static char sccsid[] = "@(#) ./lib/scc/war.c";
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "../../inc/ar.h"
+
+int
+wrarhdr(FILE *fp, struct arhdr *hdr)
+{
+	int len;
+
+	len = fprintf(fp,
+	              "%-16s%-12llu%-6u%-6u%-8o%-10llu`\n",
+	              hdr->name,
+	              hdr->time,
+	              hdr->uid, hdr->gid,
+	              hdr->mode,
+	              hdr->size);
+	assert(len== ARHDR_SIZ);
+
+	return (feof(fp)) ? EOF : len;
+}
+
+int
+wrarfile(FILE *fo, struct arhdr *hdr)
+{
+	FILE *fi;
+	int c;
+
+	if ((fi = fopen(hdr->name, "rb")) == NULL)
+		return -1;
+	while ((c = getc(fi)) != EOF)
+		putc(c, fo);
+	if (hdr->size & 1)
+		putc('\n', fo);
+	return (fclose(fi) == EOF) ? -1 : 0;
+}