commit 077526434528bec1791fc554bcbec556a6c21088
parent 355c64cd5eeb10a365b65b89e51384c61f55cadf
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Fri, 24 Nov 2017 14:58:15 +0000
[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.
Diffstat:
4 files changed, 80 insertions(+), 34 deletions(-)
diff --git a/ar/main.c b/ar/main.c
@@ -7,6 +7,9 @@ static char sccsid[] = "@(#) ./ar/main.c";
#include <stat.h>
+#include "../inc/scc.h"
+#include "../inc/ar.h"
+
int
main(int argc, char *argv[])
{
@@ -15,47 +18,31 @@ main(int argc, char *argv[])
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");
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 @@ main(int argc, char *argv[])
}
return 0;
+
+member_error:
+ die("ar: %s: %s", fname, strerror(errno));
}
diff --git 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);
diff --git a/lib/scc/libdep.mk b/lib/scc/libdep.mk
@@ -11,3 +11,4 @@ LIB-OBJ = $(LIBDIR)/debug.o \
$(LIBDIR)/lpack.o \
$(LIBDIR)/wmyro.o \
$(LIBDIR)/rmyro.o \
+ $(LIBDIR)/war.o \
diff --git a/lib/scc/war.c b/lib/scc/war.c
@@ -0,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;
+}