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.23/binutils/ar
- from Rev 115 to Rev 157
- ↔ Reverse comparison
Rev 115 → Rev 157
/ranlib.c
0,0 → 1,367
/* |
* ranlib.c -- archive index generator |
*/ |
|
|
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <time.h> |
#include <fcntl.h> |
|
#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) */ |
long position; /* position of member which defines the symbol */ |
/* (as file offset to the member's ArHeader) */ |
} Entry; |
|
|
FILE *fi; |
FILE *fo; |
|
long nxtOff; /* file offset to next member */ |
long 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) { |
long 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) { |
long 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; |
long curPos; |
long 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; |
} |
/Makefile
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 |
/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 157)
@@ -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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
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 157)
@@ -0,0 +1,5 @@
+ .code
+ .export L12345
+
+L12345:
+ add $1,$2,$3
Index: endian.c
===================================================================
--- endian.c (nonexistent)
+++ endian.c (revision 157)
@@ -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 157)
@@ -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 157)
@@ -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.h
===================================================================
--- ranlib.h (nonexistent)
+++ ranlib.h (revision 157)
@@ -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_ */