URL
https://opencores.org/ocsvn/eco32/eco32/trunk
Subversion Repositories eco32
Compare Revisions
- This comparison shows the changes necessary to convert path
/eco32/tags/eco32-0.22/binutils/ar
- from Rev 20 to Rev 21
- ↔ Reverse comparison
Rev 20 → Rev 21
/test1/text.a
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
test1/text.a
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test1/text
===================================================================
--- test1/text (nonexistent)
+++ test1/text (revision 21)
@@ -0,0 +1 @@
+This is a well-defined text.
Index: test2/stdio.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/stdio.o
===================================================================
--- test2/stdio.o (nonexistent)
+++ test2/stdio.o (revision 21)
test2/stdio.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/eos32lib.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/eos32lib.o
===================================================================
--- test2/eos32lib.o (nonexistent)
+++ test2/eos32lib.o (revision 21)
test2/eos32lib.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/ctype.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/ctype.o
===================================================================
--- test2/ctype.o (nonexistent)
+++ test2/ctype.o (revision 21)
test2/ctype.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/errno.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/errno.o
===================================================================
--- test2/errno.o (nonexistent)
+++ test2/errno.o (revision 21)
test2/errno.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/math.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/math.o
===================================================================
--- test2/math.o (nonexistent)
+++ test2/math.o (revision 21)
test2/math.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/libc.a
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/libc.a
===================================================================
--- test2/libc.a (nonexistent)
+++ test2/libc.a (revision 21)
test2/libc.a
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/time.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/time.o
===================================================================
--- test2/time.o (nonexistent)
+++ test2/time.o (revision 21)
test2/time.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/date.a
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/date.a
===================================================================
--- test2/date.a (nonexistent)
+++ test2/date.a (revision 21)
test2/date.a
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/assert.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/assert.o
===================================================================
--- test2/assert.o (nonexistent)
+++ test2/assert.o (revision 21)
test2/assert.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/string.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/string.o
===================================================================
--- test2/string.o (nonexistent)
+++ test2/string.o (revision 21)
test2/string.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/ttt.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/ttt.o
===================================================================
--- test2/ttt.o (nonexistent)
+++ test2/ttt.o (revision 21)
test2/ttt.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/small1.a
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/small1.a
===================================================================
--- test2/small1.a (nonexistent)
+++ test2/small1.a (revision 21)
test2/small1.a
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/small2.a
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/small2.a
===================================================================
--- test2/small2.a (nonexistent)
+++ test2/small2.a (revision 21)
test2/small2.a
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/signal.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/signal.o
===================================================================
--- test2/signal.o (nonexistent)
+++ test2/signal.o (revision 21)
test2/signal.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/stdlib.o
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: test2/stdlib.o
===================================================================
--- test2/stdlib.o (nonexistent)
+++ test2/stdlib.o (revision 21)
test2/stdlib.o
Property changes :
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Index: test2/ttt.s
===================================================================
--- test2/ttt.s (nonexistent)
+++ test2/ttt.s (revision 21)
@@ -0,0 +1,5 @@
+ .code
+ .export L12345
+
+L12345:
+ add $1,$2,$3
Index: endian.c
===================================================================
--- endian.c (nonexistent)
+++ endian.c (revision 21)
@@ -0,0 +1,38 @@
+/*
+ * endian.c -- endianness conversions
+ */
+
+
+#include "endian.h"
+
+
+unsigned int read4FromEco(unsigned char *p) {
+ return (unsigned int) p[0] << 24 |
+ (unsigned int) p[1] << 16 |
+ (unsigned int) p[2] << 8 |
+ (unsigned int) p[3] << 0;
+}
+
+
+void write4ToEco(unsigned char *p, unsigned int data) {
+ p[0] = data >> 24;
+ p[1] = data >> 16;
+ p[2] = data >> 8;
+ p[3] = data >> 0;
+}
+
+
+void conv4FromEcoToNative(unsigned char *p) {
+ unsigned int data;
+
+ data = read4FromEco(p);
+ * (unsigned int *) p = data;
+}
+
+
+void conv4FromNativeToEco(unsigned char *p) {
+ unsigned int data;
+
+ data = * (unsigned int *) p;
+ write4ToEco(p, data);
+}
Index: ar.c
===================================================================
--- ar.c (nonexistent)
+++ ar.c (revision 21)
@@ -0,0 +1,865 @@
+/*
+ * ar.c -- archiver
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "endian.h"
+#include "ranlib.h"
+#include "../include/ar.h"
+
+
+/**************************************************************/
+
+
+#define BUFSIZE 512
+
+#define SKIP 0x01
+#define IODD 0x02
+#define OODD 0x04
+#define HEAD 0x08
+
+
+char *com = "drqtpmx";
+char *opt = "vuabcls";
+
+int signums[] = { SIGHUP, SIGINT, SIGQUIT, 0 };
+
+void (*comfun)(void);
+int flg[26];
+
+char *arnam;
+int af;
+
+char **namv;
+int namc;
+
+int baState;
+char *posName;
+
+char tmp0nam[20];
+char tmp1nam[20];
+char tmp2nam[20];
+char *tf0nam;
+char *tf1nam;
+char *tf2nam;
+int tf0;
+int tf1;
+int tf2;
+int qf;
+
+char *file;
+char name[MAX_NAME];
+
+struct stat stbuf;
+ArHeader arbuf;
+unsigned char buf[BUFSIZE];
+
+
+/**************************************************************/
+
+
+#define IFMT 070000
+#define SUID 004000
+#define SGID 002000
+#define STXT 001000
+#define ROWN 000400
+#define WOWN 000200
+#define XOWN 000100
+#define RGRP 000040
+#define WGRP 000020
+#define XGRP 000010
+#define ROTH 000004
+#define WOTH 000002
+#define XOTH 000001
+
+
+int m1[] = { 1, ROWN, 'r', '-' };
+int m2[] = { 1, WOWN, 'w', '-' };
+int m3[] = { 2, SUID, 's', XOWN, 'x', '-' };
+int m4[] = { 1, RGRP, 'r', '-' };
+int m5[] = { 1, WGRP, 'w', '-' };
+int m6[] = { 2, SGID, 's', XGRP, 'x', '-' };
+int m7[] = { 1, ROTH, 'r', '-' };
+int m8[] = { 1, WOTH, 'w', '-' };
+int m9[] = { 2, STXT, 't', XOTH, 'x', '-' };
+
+int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9 };
+
+
+void selectChar(int *pairp) {
+ int *ap;
+ int n;
+
+ ap = pairp;
+ n = *ap++;
+ while (--n >= 0 && (arbuf.mode & *ap++) == 0) {
+ ap++;
+ }
+ putchar(*ap);
+}
+
+
+void printMode(void) {
+ int **mp;
+
+ for (mp = &m[0]; mp < &m[9]; mp++) {
+ selectChar(*mp);
+ }
+}
+
+
+void showAttributes(void) {
+ char *cp;
+
+ printMode();
+ printf("%4d/%4d", arbuf.uid, arbuf.gid);
+ printf("%8ld", arbuf.size);
+ cp = ctime(&arbuf.date);
+ printf(" %-12.12s %-4.4s ", cp + 4, cp + 20);
+}
+
+
+/**************************************************************/
+
+
+void mesg(int c) {
+ if (flg['v' - 'a']) {
+ printf("%c - %s\n", c, file);
+ }
+}
+
+
+char *trim(char *s) {
+ char *p1;
+ char *p2;
+
+ for (p1 = s; *p1 != '\0'; p1++) ;
+ while (p1 > s) {
+ if (*--p1 != '/') {
+ break;
+ }
+ *p1 = '\0';
+ }
+ p2 = s;
+ for (p1 = s; *p1 != '\0'; p1++) {
+ if (*p1 == '/') {
+ p2 = p1 + 1;
+ }
+ }
+ return p2;
+}
+
+
+int notFound(void) {
+ int n;
+ int i;
+
+ n = 0;
+ for (i = 0; i < namc; i++) {
+ if (namv[i] != NULL) {
+ fprintf(stderr, "ar: %s not found\n", namv[i]);
+ n++;
+ }
+ }
+ return n;
+}
+
+
+int moreFiles(void) {
+ int n;
+ int i;
+
+ n = 0;
+ for (i = 0; i < namc; i++) {
+ if (namv[i] != NULL) {
+ n++;
+ }
+ }
+ return n;
+}
+
+
+void unlinkTempFiles(void) {
+ if (tf0nam != NULL) {
+ unlink(tf0nam);
+ }
+ if (tf1nam != NULL) {
+ unlink(tf1nam);
+ }
+ if (tf2nam != NULL) {
+ unlink(tf2nam);
+ }
+}
+
+
+void done(int c) {
+ unlinkTempFiles();
+ exit(c);
+}
+
+
+void sigDone(int signum) {
+ done(100);
+}
+
+
+void noArchive(void) {
+ fprintf(stderr, "ar: %s does not exist\n", arnam);
+ done(1);
+}
+
+
+void writeError(void) {
+ perror("ar write error");
+ done(1);
+}
+
+
+void phaseError(void) {
+ fprintf(stderr, "ar: phase error on %s\n", file);
+}
+
+
+int stats(void) {
+ int f;
+
+ f = open(file, O_RDONLY);
+ if (f < 0) {
+ return f;
+ }
+ if (fstat(f, &stbuf) < 0) {
+ close(f);
+ return -1;
+ }
+ return f;
+}
+
+
+int match(void) {
+ int i;
+
+ for (i = 0; i < namc; i++) {
+ if (namv[i] == NULL) {
+ continue;
+ }
+ if (strcmp(trim(namv[i]), file) == 0) {
+ file = namv[i];
+ namv[i] = NULL;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+void baMatch(void) {
+ int f;
+
+ if (baState == 1) {
+ if (strcmp(file, posName) != 0) {
+ return;
+ }
+ baState = 2;
+ if (flg['a' - 'a']) {
+ return;
+ }
+ }
+ if (baState == 2) {
+ baState = 0;
+ tf1nam = mktemp(tmp1nam);
+ close(creat(tf1nam, 0600));
+ f = open(tf1nam, O_RDWR);
+ if (f < 0) {
+ fprintf(stderr, "ar: cannot create second temp file\n");
+ return;
+ }
+ tf1 = tf0;
+ tf0 = f;
+ }
+}
+
+
+/**************************************************************/
+
+
+void init(void) {
+ unsigned int mbuf;
+
+ write4ToEco((unsigned char *) &mbuf, AR_MAGIC);
+ tf0nam = mktemp(tmp0nam);
+ close(creat(tf0nam, 0600));
+ tf0 = open(tf0nam, O_RDWR);
+ if (tf0 < 0) {
+ fprintf(stderr, "ar: cannot create temp file\n");
+ done(1);
+ }
+ if (write(tf0, &mbuf, sizeof(mbuf)) != sizeof(mbuf)) {
+ writeError();
+ }
+}
+
+
+int getArchive(void) {
+ unsigned int mbuf;
+
+ af = open(arnam, O_RDONLY);
+ if (af < 0) {
+ return 1;
+ }
+ if (read(af, &mbuf, sizeof(mbuf)) != sizeof(mbuf) ||
+ read4FromEco((unsigned char *) &mbuf) != AR_MAGIC) {
+ fprintf(stderr, "ar: %s not in archive format\n", arnam);
+ done(1);
+ }
+ return 0;
+}
+
+
+void getQuick(void) {
+ unsigned int mbuf;
+
+ qf = open(arnam, O_RDWR);
+ if (qf < 0) {
+ if (!flg['c' - 'a']) {
+ fprintf(stderr, "ar: creating %s\n", arnam);
+ }
+ close(creat(arnam, 0666));
+ qf = open(arnam, O_RDWR);
+ if (qf < 0) {
+ fprintf(stderr, "ar: cannot create %s\n", arnam);
+ done(1);
+ }
+ write4ToEco((unsigned char *) &mbuf, AR_MAGIC);
+ if (write(qf, &mbuf, sizeof(mbuf)) != sizeof(mbuf)) {
+ writeError();
+ }
+ } else
+ if (read(qf, &mbuf, sizeof(mbuf)) != sizeof(mbuf) ||
+ read4FromEco((unsigned char *) &mbuf) != AR_MAGIC) {
+ fprintf(stderr, "ar: %s not in archive format\n", arnam);
+ done(1);
+ }
+}
+
+
+int getMember(void) {
+ int i;
+
+ i = read(af, &arbuf, sizeof(arbuf));
+ if (i != sizeof(arbuf)) {
+ if (tf1nam != NULL) {
+ i = tf0;
+ tf0 = tf1;
+ tf1 = i;
+ }
+ return 1;
+ }
+ conv4FromEcoToNative((unsigned char *) &arbuf.date);
+ conv4FromEcoToNative((unsigned char *) &arbuf.uid);
+ conv4FromEcoToNative((unsigned char *) &arbuf.gid);
+ conv4FromEcoToNative((unsigned char *) &arbuf.mode);
+ conv4FromEcoToNative((unsigned char *) &arbuf.size);
+ for (i = 0; i < MAX_NAME; i++) {
+ name[i] = arbuf.name[i];
+ }
+ file = name;
+ return 0;
+}
+
+
+void copyFile(int fi, int fo, int flags) {
+ int pe;
+ int icount, ocount;
+ int pad;
+
+ if (flags & HEAD) {
+ conv4FromNativeToEco((unsigned char *) &arbuf.date);
+ conv4FromNativeToEco((unsigned char *) &arbuf.uid);
+ conv4FromNativeToEco((unsigned char *) &arbuf.gid);
+ conv4FromNativeToEco((unsigned char *) &arbuf.mode);
+ conv4FromNativeToEco((unsigned char *) &arbuf.size);
+ if (write(fo, &arbuf, sizeof(arbuf)) != sizeof(arbuf)) {
+ writeError();
+ }
+ conv4FromEcoToNative((unsigned char *) &arbuf.date);
+ conv4FromEcoToNative((unsigned char *) &arbuf.uid);
+ conv4FromEcoToNative((unsigned char *) &arbuf.gid);
+ conv4FromEcoToNative((unsigned char *) &arbuf.mode);
+ conv4FromEcoToNative((unsigned char *) &arbuf.size);
+ }
+ pe = 0;
+ while (arbuf.size > 0) {
+ icount = ocount = BUFSIZE;
+ if (arbuf.size < icount) {
+ icount = ocount = arbuf.size;
+ pad = -icount & 0x03;
+ if (flags & IODD) {
+ icount += pad;
+ }
+ if (flags & OODD) {
+ ocount += pad;
+ }
+ }
+ if (read(fi, buf, icount) != icount) {
+ pe++;
+ }
+ if ((flags & SKIP) == 0) {
+ if (write(fo, buf, ocount) != ocount) {
+ writeError();
+ }
+ }
+ arbuf.size -= BUFSIZE;
+ }
+ if (pe != 0) {
+ phaseError();
+ }
+}
+
+
+void moveFile(int f) {
+ char *cp;
+ int i;
+
+ cp = trim(file);
+ for (i = 0; i < MAX_NAME; i++) {
+ if ((arbuf.name[i] = *cp) != '\0') {
+ cp++;
+ }
+ }
+ arbuf.size = stbuf.st_size;
+ arbuf.date = stbuf.st_mtime;
+ arbuf.uid = stbuf.st_uid;
+ arbuf.gid = stbuf.st_gid;
+ arbuf.mode = stbuf.st_mode;
+ copyFile(f, tf0, OODD | HEAD);
+ close(f);
+}
+
+
+void install(void) {
+ int i;
+
+ for (i = 0; signums[i] != 0; i++) {
+ signal(signums[i], SIG_IGN);
+ }
+ if (af < 0) {
+ if (!flg['c' - 'a']) {
+ fprintf(stderr, "ar: creating %s\n", arnam);
+ }
+ }
+ close(af);
+ af = creat(arnam, 0666);
+ if (af < 0) {
+ fprintf(stderr, "ar: cannot create %s\n", arnam);
+ done(1);
+ }
+ if (tf0nam != NULL) {
+ lseek(tf0, 0, SEEK_SET);
+ while ((i = read(tf0, buf, BUFSIZE)) > 0) {
+ if (write(af, buf, i) != i) {
+ writeError();
+ }
+ }
+ }
+ if (tf2nam != NULL) {
+ lseek(tf2, 0, SEEK_SET);
+ while ((i = read(tf2, buf, BUFSIZE)) > 0) {
+ if (write(af, buf, i) != i) {
+ writeError();
+ }
+ }
+ }
+ if (tf1nam != NULL) {
+ lseek(tf1, 0, SEEK_SET);
+ while ((i = read(tf1, buf, BUFSIZE)) > 0) {
+ if (write(af, buf, i) != i) {
+ writeError();
+ }
+ }
+ }
+}
+
+
+void cleanup(void) {
+ int i;
+ int f;
+
+ for (i = 0; i < namc; i++) {
+ file = namv[i];
+ if (file == NULL) {
+ continue;
+ }
+ namv[i] = NULL;
+ mesg('a');
+ f = stats();
+ if (f < 0) {
+ fprintf(stderr, "ar: cannot open %s\n", file);
+ continue;
+ }
+ moveFile(f);
+ }
+}
+
+
+/**************************************************************/
+
+
+void dCmd(void) {
+ init();
+ if (getArchive()) {
+ noArchive();
+ }
+ while (!getMember()) {
+ if (match()) {
+ mesg('d');
+ copyFile(af, -1, IODD | SKIP);
+ continue;
+ }
+ mesg('c');
+ copyFile(af, tf0, IODD | OODD | HEAD);
+ }
+ install();
+}
+
+
+void rCmd(void) {
+ int f;
+
+ init();
+ getArchive();
+ while (!getMember()) {
+ baMatch();
+ if (namc == 0 || match()) {
+ f = stats();
+ if (f < 0) {
+ if (namc != 0) {
+ fprintf(stderr, "ar: cannot open %s\n", file);
+ }
+ goto cp;
+ }
+ if (flg['u' - 'a']) {
+ if (stbuf.st_mtime <= arbuf.date) {
+ close(f);
+ goto cp;
+ }
+ }
+ mesg('r');
+ copyFile(af, -1, IODD | SKIP);
+ moveFile(f);
+ continue;
+ }
+cp:
+ mesg('c');
+ copyFile(af, tf0, IODD | OODD | HEAD);
+ }
+ cleanup();
+ install();
+}
+
+
+void qCmd(void) {
+ int i;
+ int f;
+
+ if (flg['a' - 'a'] || flg['b' - 'a']) {
+ fprintf(stderr, "ar: [ab] not allowed with -q\n");
+ done(1);
+ }
+ getQuick();
+ for (i = 0; signums[i] != 0; i++) {
+ signal(signums[i], SIG_IGN);
+ }
+ lseek(qf, 0, SEEK_END);
+ for (i = 0; i < namc; i++) {
+ file = namv[i];
+ if (file == NULL) {
+ continue;
+ }
+ namv[i] = NULL;
+ mesg('q');
+ f = stats();
+ if (f < 0) {
+ fprintf(stderr, "ar: cannot open %s\n", file);
+ continue;
+ }
+ tf0 = qf;
+ moveFile(f);
+ qf = tf0;
+ }
+}
+
+
+void tCmd(void) {
+ if (getArchive()) {
+ noArchive();
+ }
+ while (!getMember()) {
+ if (namc == 0 || match()) {
+ if (flg['v' - 'a']) {
+ showAttributes();
+ }
+ printf("%s\n", trim(file));
+ }
+ copyFile(af, -1, IODD | SKIP);
+ }
+}
+
+
+void pCmd(void) {
+ if (getArchive()) {
+ noArchive();
+ }
+ while (!getMember()) {
+ if (namc == 0 || match()) {
+ if (flg['v' - 'a']) {
+ printf("\n<%s>\n\n", file);
+ fflush(stdout);
+ }
+ copyFile(af, 1, IODD);
+ continue;
+ }
+ copyFile(af, -1, IODD | SKIP);
+ }
+}
+
+
+void mCmd(void) {
+ init();
+ if (getArchive()) {
+ noArchive();
+ }
+ tf2nam = mktemp(tmp2nam);
+ close(creat(tf2nam, 0600));
+ tf2 = open(tf2nam, O_RDWR);
+ if (tf2 < 0) {
+ fprintf(stderr, "ar: cannot create third temp file\n");
+ done(1);
+ }
+ while (!getMember()) {
+ baMatch();
+ if (match()) {
+ mesg('m');
+ copyFile(af, tf2, IODD | OODD | HEAD);
+ continue;
+ }
+ mesg('c');
+ copyFile(af, tf0, IODD | OODD | HEAD);
+ }
+ install();
+}
+
+
+void xCmd(void) {
+ int f;
+
+ if (getArchive()) {
+ noArchive();
+ }
+ while (!getMember()) {
+ if (namc == 0 || match()) {
+ f = creat(file, arbuf.mode & 0777);
+ if (f < 0) {
+ fprintf(stderr, "ar: cannot create %s\n", file);
+ goto sk;
+ }
+ mesg('x');
+ copyFile(af, f, IODD);
+ close(f);
+ continue;
+ }
+sk:
+ mesg('c');
+ copyFile(af, -1, IODD | SKIP);
+ if (namc > 0 && !moreFiles()) {
+ done(0);
+ }
+ }
+}
+
+
+/**************************************************************/
+
+/* specialized r command for updating symbols */
+
+
+int exec_rCmd(int create, char *args[]) {
+ int i;
+ int res;
+
+ /* reset all global variables */
+ comfun = NULL;
+ for (i = 0; i < 26; i++) {
+ flg[i] = 0;
+ }
+ arnam = NULL;
+ af = 0;
+ namv = NULL;
+ namc = 0;
+ baState = 0;
+ posName = NULL;
+ for (i = 0; i < 20; i++) {
+ tmp0nam[i] = '\0';
+ tmp1nam[i] = '\0';
+ tmp2nam[i] = '\0';
+ }
+ tf0nam = NULL;
+ tf1nam = NULL;
+ tf2nam = NULL;
+ tf0 = 0;
+ tf1 = 0;
+ tf2 = 0;
+ qf = 0;
+ file = NULL;
+ for (i = 0; i < MAX_NAME; i++) {
+ name[i] = '\0';
+ }
+ /* prepare arguments, call r command, cleanup */
+ comfun = rCmd;
+ flg['l' - 'a'] = 1;
+ strcpy(tmp0nam, "v0XXXXXX");
+ strcpy(tmp1nam, "v1XXXXXX");
+ strcpy(tmp2nam, "v2XXXXXX");
+ if (create) {
+ /* ar -rlb firstName archive TEMP_NAME */
+ flg['b' - 'a'] = 1;
+ baState = 1;
+ posName = trim(args[0]);
+ arnam = args[1];
+ namv = &args[2];
+ namc = 1;
+ } else {
+ /* ar -rl archive TEMP_NAME */
+ arnam = args[0];
+ namv = &args[1];
+ namc = 1;
+ }
+ (*comfun)();
+ res = notFound();
+ unlinkTempFiles();
+ return res;
+}
+
+
+/**************************************************************/
+
+
+void usage(void) {
+ printf("usage: ar -[%s][%s] archive files ...\n", com, opt);
+ done(1);
+}
+
+
+void setcom(void (*fun)(void)) {
+ if (comfun != NULL) {
+ fprintf(stderr, "ar: only one of [%s] allowed\n", com);
+ done(1);
+ }
+ comfun = fun;
+}
+
+
+int cmdCanChangeSymbols(void) {
+ return comfun == dCmd ||
+ comfun == rCmd ||
+ comfun == mCmd;
+}
+
+
+int main(int argc, char *argv[]) {
+ int i;
+ char *cp;
+ int res;
+
+ for (i = 0; signums[i] != 0; i++) {
+ if (signal(signums[i], SIG_IGN) != SIG_IGN) {
+ signal(signums[i], sigDone);
+ }
+ }
+ strcpy(tmp0nam, "/tmp/v0XXXXXX");
+ strcpy(tmp1nam, "/tmp/v1XXXXXX");
+ strcpy(tmp2nam, "/tmp/v2XXXXXX");
+ if (argc < 3 || *argv[1] != '-') {
+ usage();
+ }
+ for (cp = argv[1] + 1; *cp != '\0'; cp++) {
+ switch (*cp) {
+ case 'd':
+ setcom(dCmd);
+ break;
+ case 'r':
+ setcom(rCmd);
+ break;
+ case 'q':
+ setcom(qCmd);
+ break;
+ case 't':
+ setcom(tCmd);
+ break;
+ case 'p':
+ setcom(pCmd);
+ break;
+ case 'm':
+ setcom(mCmd);
+ break;
+ case 'x':
+ setcom(xCmd);
+ break;
+ case 'v':
+ case 'u':
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'l':
+ case 's':
+ flg[*cp - 'a'] = 1;
+ break;
+ default:
+ fprintf(stderr, "ar: bad option '%c'\n", *cp);
+ done(1);
+ }
+ }
+ if (flg['l' - 'a']) {
+ strcpy(tmp0nam, "v0XXXXXX");
+ strcpy(tmp1nam, "v1XXXXXX");
+ strcpy(tmp2nam, "v2XXXXXX");
+ }
+ if (flg['a' - 'a'] || flg['b' - 'a']) {
+ baState = 1;
+ posName = trim(argv[2]);
+ argv++;
+ argc--;
+ if (argc < 3) {
+ usage();
+ }
+ }
+ arnam = argv[2];
+ namv = argv + 3;
+ namc = argc - 3;
+ if (comfun == NULL && !flg['s' - 'a']) {
+ fprintf(stderr, "ar: one of [%ss] must be specified\n", com);
+ done(1);
+ }
+ res = 0;
+ if (comfun != NULL) {
+ (*comfun)();
+ res = notFound();
+ unlinkTempFiles();
+ if (res != 0) {
+ return res;
+ }
+ }
+ if (flg['s' - 'a'] ||
+ (cmdCanChangeSymbols() && hasSymbols(arnam))) {
+ res = updateSymbols(arnam, flg['v' - 'a']);
+ }
+ return res;
+}
Index: endian.h
===================================================================
--- endian.h (nonexistent)
+++ endian.h (revision 21)
@@ -0,0 +1,16 @@
+/*
+ * endian.h -- endianness conversions
+ */
+
+
+#ifndef _ENDIAN_H_
+#define _ENDIAN_H_
+
+
+unsigned int read4FromEco(unsigned char *p);
+void write4ToEco(unsigned char *p, unsigned int data);
+void conv4FromEcoToNative(unsigned char *p);
+void conv4FromNativeToEco(unsigned char *p);
+
+
+#endif /* _ENDIAN_H_ */
Index: ranlib.c
===================================================================
--- ranlib.c (nonexistent)
+++ ranlib.c (revision 21)
@@ -0,0 +1,367 @@
+/*
+ * ranlib.c -- archive index generator
+ */
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "endian.h"
+#include "ranlib.h"
+#include "../include/ar.h"
+#include "../include/a.out.h"
+
+
+#define TEMP_NAME "__.SYMDEF"
+
+#define STRING_SIZE_INIT 1024
+#define STRING_SIZE_GROW 2
+
+#define MAX_SYM_ENTRIES 1000
+
+#define MSB ((unsigned int) 1 << (sizeof(unsigned int) * 8 - 1))
+
+
+typedef struct {
+ unsigned int name; /* name of symbol (as offset into string space) */
+ off_t position; /* position of member which defines the symbol */
+ /* (as file offset to the member's ArHeader) */
+} Entry;
+
+
+FILE *fi;
+FILE *fo;
+
+off_t nxtOff; /* file offset to next member */
+off_t curOff;
+
+Entry table[MAX_SYM_ENTRIES];
+int numEntries;
+
+int createIndex;
+char firstName[MAX_NAME];
+
+ArHeader arhdr;
+ExecHeader exhdr;
+
+
+/**************************************************************/
+
+
+char *stringArea = NULL;
+unsigned int sizeAllocated = 0;
+unsigned int sizeUsed = 0;
+
+
+unsigned int getStringPos(void) {
+ return sizeUsed;
+}
+
+
+void storeCharacter(char c) {
+ unsigned int newSize;
+ char *newArea;
+
+ if (sizeUsed + 1 > sizeAllocated) {
+ if (sizeAllocated == 0) {
+ newSize = STRING_SIZE_INIT;
+ } else {
+ newSize = STRING_SIZE_GROW * sizeAllocated;
+ }
+ newArea = malloc(newSize);
+ if (newArea == NULL) {
+ fprintf(stderr, "ar: cannot allocate string area\n");
+ exit(1);
+ }
+ if (stringArea != NULL) {
+ memcpy(newArea, stringArea, sizeUsed);
+ free(stringArea);
+ }
+ stringArea = newArea;
+ sizeAllocated = newSize;
+ }
+ stringArea[sizeUsed++] = c;
+}
+
+
+/**************************************************************/
+
+
+int nextMember(void) {
+ int pad;
+
+ curOff = nxtOff;
+ fseek(fi, nxtOff, SEEK_SET);
+ if (fread(&arhdr, sizeof(arhdr), 1, fi) != 1) {
+ return 0;
+ }
+ conv4FromEcoToNative((unsigned char *) &arhdr.date);
+ conv4FromEcoToNative((unsigned char *) &arhdr.uid);
+ conv4FromEcoToNative((unsigned char *) &arhdr.gid);
+ conv4FromEcoToNative((unsigned char *) &arhdr.mode);
+ conv4FromEcoToNative((unsigned char *) &arhdr.size);
+ pad = -arhdr.size & 0x03;
+ arhdr.size += pad;
+ nxtOff = ftell(fi) + arhdr.size;
+ return 1;
+}
+
+
+void addSymbol(unsigned int nameOffset) {
+ off_t curPos;
+ int c;
+
+ if (numEntries >= MAX_SYM_ENTRIES) {
+ fprintf(stderr, "ar: symbol table overflow\n");
+ exit(1);
+ }
+ table[numEntries].name = getStringPos();
+ table[numEntries].position = curOff;
+ numEntries++;
+ curPos = ftell(fi);
+ fseek(fi, curOff + sizeof(arhdr) + nameOffset, SEEK_SET);
+ do {
+ c = fgetc(fi);
+ storeCharacter(c);
+ } while (c != 0) ;
+ fseek(fi, curPos, SEEK_SET);
+}
+
+
+void fixSize(void) {
+ off_t deltaOff;
+ int pad;
+ int i;
+
+ deltaOff = sizeof(arhdr) + sizeof(int) +
+ numEntries * sizeof(Entry) + getStringPos();
+ pad = -deltaOff & 0x03;
+ deltaOff += pad;
+ nxtOff = sizeof(unsigned int);
+ nextMember();
+ if(strncmp(arhdr.name, TEMP_NAME, MAX_NAME) == 0) {
+ /* there is an index already present */
+ createIndex = 0;
+ deltaOff -= sizeof(arhdr) + arhdr.size;
+ } else {
+ /* no index yet present, create new one */
+ createIndex = 1;
+ strncpy(firstName, arhdr.name, MAX_NAME);
+ }
+ for (i = 0; i < numEntries; i++) {
+ table[i].position += deltaOff;
+ }
+}
+
+
+/**************************************************************/
+
+
+void showSymdefs(char *symdefs) {
+ FILE *in;
+ int numSymbols;
+ int i;
+ Entry e;
+ off_t curPos;
+ off_t pos;
+ int c;
+
+ in = fopen(symdefs, "r");
+ if (in == NULL) {
+ printf("error: cannot open symdef file '%s'\n", symdefs);
+ exit(1);
+ }
+ if (fread(&numSymbols, sizeof(int), 1, in) != 1) {
+ printf("cannot read symdef file\n");
+ exit(1);
+ }
+ conv4FromEcoToNative((unsigned char *) &numSymbols);
+ printf("%d symbols\n", numSymbols);
+ for (i = 0; i < numSymbols; i++) {
+ if (fread(&e, sizeof(e), 1, in) != 1) {
+ printf("cannot read symdef file\n");
+ exit(1);
+ }
+ conv4FromEcoToNative((unsigned char *) &e.name);
+ conv4FromEcoToNative((unsigned char *) &e.position);
+ printf("%4d: name = 0x%08X, position = 0x%08lX, string = '",
+ i, e.name, e.position);
+ curPos = ftell(in);
+ pos = sizeof(int) + numSymbols * sizeof(Entry) + e.name;
+ fseek(in, pos, SEEK_SET);
+ while (1) {
+ c = fgetc(in);
+ if (c == EOF) {
+ printf("\nerror: unexpected end of file\n");
+ exit(1);
+ }
+ if (c == 0) {
+ break;
+ }
+ printf("%c", c);
+ }
+ printf("'\n");
+ fseek(in, curPos, SEEK_SET);
+ }
+ fclose(in);
+}
+
+
+/**************************************************************/
+
+
+int hasSymbols(char *archive) {
+ unsigned int arMagic;
+ int res;
+
+ fi = fopen(archive, "r");
+ if (fi == NULL) {
+ return 0;
+ }
+ nxtOff = sizeof(unsigned int);
+ if (fread(&arMagic, sizeof(arMagic), 1, fi) != 1 ||
+ read4FromEco((unsigned char *) &arMagic) != AR_MAGIC) {
+ fclose(fi);
+ return 0;
+ }
+ fseek(fi, 0, SEEK_SET);
+ if (nextMember() == 0) {
+ fclose(fi);
+ return 0;
+ }
+ fclose(fi);
+ res = (strncmp(arhdr.name, TEMP_NAME, MAX_NAME) == 0);
+ return res;
+}
+
+
+int updateSymbols(char *archive, int verbose) {
+ unsigned int arMagic;
+ unsigned int skip;
+ int numSymbols;
+ unsigned int stringStart;
+ SymbolRecord symbol;
+ int i;
+ char *args[3];
+ int res;
+
+ if (verbose) {
+ printf("ar: updating symbols in %s\n", archive);
+ }
+ fi = fopen(archive, "r");
+ if (fi == NULL) {
+ fprintf(stderr, "ar: cannot re-open %s\n", archive);
+ return 1;
+ }
+ nxtOff = sizeof(unsigned int);
+ if (fread(&arMagic, sizeof(arMagic), 1, fi) != 1 ||
+ read4FromEco((unsigned char *) &arMagic) != AR_MAGIC) {
+ fprintf(stderr, "ar: %s not in archive format\n", archive);
+ fclose(fi);
+ return 1;
+ }
+ fseek(fi, 0, SEEK_SET);
+ numEntries = 0;
+ if (nextMember() == 0) {
+ fclose(fi);
+ return 0;
+ }
+ /* iterate over archive members */
+ do {
+ if (fread(&exhdr, sizeof(exhdr), 1, fi) != 1 ||
+ read4FromEco((unsigned char *) &exhdr.magic) != EXEC_MAGIC) {
+ /* archive member not in proper format - skip */
+ continue;
+ }
+ conv4FromEcoToNative((unsigned char *) &exhdr.magic);
+ conv4FromEcoToNative((unsigned char *) &exhdr.csize);
+ conv4FromEcoToNative((unsigned char *) &exhdr.dsize);
+ conv4FromEcoToNative((unsigned char *) &exhdr.bsize);
+ conv4FromEcoToNative((unsigned char *) &exhdr.crsize);
+ conv4FromEcoToNative((unsigned char *) &exhdr.drsize);
+ conv4FromEcoToNative((unsigned char *) &exhdr.symsize);
+ conv4FromEcoToNative((unsigned char *) &exhdr.strsize);
+ skip = exhdr.csize + exhdr.dsize + exhdr.crsize + exhdr.drsize;
+ fseek(fi, skip, SEEK_CUR);
+ numSymbols = exhdr.symsize / sizeof(SymbolRecord);
+ if (numSymbols == 0) {
+ fprintf(stderr,
+ "ar: symbol table of %s is empty\n",
+ arhdr.name);
+ continue;
+ }
+ stringStart = sizeof(exhdr) + skip + exhdr.symsize;
+ /* iterate over symbols */
+ while (--numSymbols >= 0) {
+ if (fread(&symbol, sizeof(symbol), 1, fi) != 1) {
+ fprintf(stderr, "ar: cannot read archive\n");
+ break;
+ }
+ conv4FromEcoToNative((unsigned char *) &symbol.name);
+ conv4FromEcoToNative((unsigned char *) &symbol.type);
+ conv4FromEcoToNative((unsigned char *) &symbol.value);
+ if ((symbol.type & MSB) == 0) {
+ /* this is an exported symbol */
+ addSymbol(stringStart + symbol.name);
+ }
+ }
+ } while (nextMember() != 0) ;
+ fixSize();
+ fclose(fi);
+ fo = fopen(TEMP_NAME, "w");
+ if (fo == NULL) {
+ fprintf(stderr, "ar: can't create temporary file\n");
+ return 1;
+ }
+ conv4FromNativeToEco((unsigned char *) &numEntries);
+ if (fwrite(&numEntries, sizeof(numEntries), 1, fo) != 1) {
+ fprintf(stderr, "ar: can't write temporary file\n");
+ fclose(fo);
+ unlink(TEMP_NAME);
+ return 1;
+ }
+ conv4FromEcoToNative((unsigned char *) &numEntries);
+ for (i = 0; i < numEntries; i++) {
+ conv4FromNativeToEco((unsigned char *) &table[i].name);
+ conv4FromNativeToEco((unsigned char *) &table[i].position);
+ }
+ if (fwrite(table, sizeof(Entry), numEntries, fo) != numEntries) {
+ fprintf(stderr, "ar: can't write temporary file\n");
+ fclose(fo);
+ unlink(TEMP_NAME);
+ return 1;
+ }
+ for (i = 0; i < numEntries; i++) {
+ conv4FromEcoToNative((unsigned char *) &table[i].name);
+ conv4FromEcoToNative((unsigned char *) &table[i].position);
+ }
+ if (fwrite(stringArea, 1, getStringPos(), fo) != getStringPos()) {
+ fprintf(stderr, "ar: can't write temporary file\n");
+ fclose(fo);
+ unlink(TEMP_NAME);
+ return 1;
+ }
+ fclose(fo);
+ if (verbose) {
+ showSymdefs(TEMP_NAME);
+ }
+ if (createIndex) {
+ /* ar -rlb firstName archive TEMP_NAME */
+ args[0] = firstName;
+ args[1] = archive;
+ args[2] = TEMP_NAME;
+ res = exec_rCmd(1, args);
+ } else {
+ /* ar -rl archive TEMP_NAME */
+ args[0] = archive;
+ args[1] = TEMP_NAME;
+ args[2] = NULL;
+ res = exec_rCmd(0, args);
+ }
+ unlink(TEMP_NAME);
+ return res;
+}
Index: ranlib.h
===================================================================
--- ranlib.h (nonexistent)
+++ ranlib.h (revision 21)
@@ -0,0 +1,16 @@
+/*
+ * ranlib.c - archive index generator
+ */
+
+
+#ifndef _RANLIB_H_
+#define _RANLIB_H_
+
+
+int hasSymbols(char *archive);
+int updateSymbols(char *archive, int verbose);
+
+int exec_rCmd(int create, char *args[]);
+
+
+#endif /* _RANLIB_H_ */
Index: Makefile
===================================================================
--- Makefile (nonexistent)
+++ Makefile (revision 21)
@@ -0,0 +1,36 @@
+#
+# Makefile for ECO32 archiver
+#
+
+BUILD = ../../build
+
+CC = gcc -m32
+CFLAGS = -g -Wall
+LDFLAGS = -g
+LDLIBS = -lm
+
+SRCS = ar.c ranlib.c endian.c
+OBJS = $(patsubst %.c,%.o,$(SRCS))
+BIN = ar
+
+.PHONY: all install clean
+
+all: $(BIN)
+
+install: $(BIN)
+ mkdir -p $(BUILD)/bin
+ cp $(BIN) $(BUILD)/bin
+
+$(BIN): $(OBJS)
+ $(CC) $(LDFLAGS) -o $(BIN) $(OBJS) $(LDLIBS)
+
+%.o: %.c
+ $(CC) $(CFLAGS) -o $@ -c $<
+
+depend.mak:
+ $(CC) -MM -MG $(CFLAGS) $(SRCS) > depend.mak
+
+-include depend.mak
+
+clean:
+ rm -f *~ $(OBJS) $(BIN) depend.mak