--- /dev/null
+EMHOME = ../../..
+MODULES = $(EMHOME)/modules
+INSTALL = $(MODULES)/install
+COMPARE = $(MODULES)/compare
+CFLAGS = -O -I$(EMHOME)/h
+CFILES = rd_arhdr.c wr_arhdr.c \
+ rd_ranlib.c wr_ranlib.c \
+ rd_bytes.c wr_bytes.c \
+ rd.c wr.c \
+ wr_putc.c \
+ rd_int2.c wr_int2.c \
+ rd_unsig2.c \
+ rd_long.c wr_long.c
+# do not change the order in OFILES
+OFILES = rd.o rd_arhdr.o rd_int2.o rd_long.o rd_ranlib.o rd_unsig2.o \
+ rd_bytes.o wr_arhdr.o wr_int2.o wr_long.o wr_putc.o wr.o \
+ wr_ranlib.o wr_bytes.o
+
+all: libobject.a
+
+install: all
+ $(INSTALL) lib/libobject.a
+ $(INSTALL) man/object.3
+
+compare: all
+ $(COMPARE) lib/libobject.a
+ $(COMPARE) man/object.3
+
+clean:
+ rm -f *.[oa] nohup.out Out byte_order byte_order.h
+
+libobject.a: $(OFILES)
+ ar r libobject.a $(OFILES)
+ -sh -c 'ranlib libobject.a'
+
+depend: byte_order.h
+ sed '/^#AUTOAUTO/,$$d' Makefile > Makefile.new
+ echo '#AUTOAUTOAUTOAUTOAUTOAUTOAUTO' >> Makefile.new
+ mkdep $(CFILES) | sed 's/\.c:/\.o:/' >> Makefile.new
+ mv Makefile Makefile.old
+ mv Makefile.new Makefile
+
+byte_order: byte_order.o
+ $(CC) $(LDFLAGS) -o byte_order byte_order.o
+
+byte_order.h: byte_order
+ byte_order > byte_order.h
+
+#AUTOAUTOAUTOAUTOAUTOAUTOAUTO
+rd_arhdr.o: byte_order.h object.h
+wr_arhdr.o: byte_order.h object.h
+rd_ranlib.o: byte_order.h object.h
+wr_ranlib.o: byte_order.h object.h
+rd.o: byte_order.h object.h
+wr.o: byte_order.h object.h
+rd_int2.o: byte_order.h object.h
+wr_int2.o: byte_order.h object.h
+rd_unsig2.o: byte_order.h object.h
+rd_long.o: byte_order.h object.h
+wr_long.o: byte_order.h object.h
--- /dev/null
+#include <stdio.h>
+
+char bytes_reversed = 0;
+char words_reversed = 0;
+char char_unsigned = 0;
+
+/*
+ * Determine the byte/word order in shorts/longs, assuming the size of a short
+ * is 2 chars, and the size of a long is 4 chars. Not all theoretical
+ * possibilities are tested; only bytes reversed and/or words reversed.
+ */
+determine_ordering()
+{
+ short s;
+ long l;
+ register char *cp;
+ register short *sp;
+
+ cp = (char *)&s;
+ cp[0] = 0x01; cp[1] = 0x02;
+ if (s != 0x01 + (0x02 << 8))
+ bytes_reversed = 1;
+ sp = (short *)&l;
+ sp[0] = 0x0001; sp[1] = 0x0002;
+ if (l != 0x0001 + (0x0002L << 16))
+ words_reversed = 1;
+}
+
+/*
+ * determine whether characters are unsigned or signed
+ */
+
+uns_char()
+{
+ char c = 0200;
+ int i = c;
+
+ if (i > 0) char_unsigned = 1;
+}
+
+main()
+{
+ determine_ordering();
+ uns_char();
+ printf("#define BYTES_REVERSED %d\n", bytes_reversed);
+ printf("#define WORDS_REVERSED %d\n", words_reversed);
+ printf("#define CHAR_UNSIGNED %d\n", char_unsigned);
+ return 0;
+}
--- /dev/null
+.TH OBJECT 3 "October 16, 1986"
+.SH NAME
+wr_open, wr_close, wr_ohead, wr_sect, wr_outsect, wr_emit, wr_putc, wr_relo,
+wr_name, wr_string, wr_arhdr, wr_ranlib, wr_int2, wr_long,
+rd_open, rd_fdopen, rd_close, rd_ohead, rd_sect, rd_outsect,
+rd_emit, rd_relo, rd_rew_relo, rd_name, rd_string, rd_arhdr, rd_ranlib,
+rd_int2, rd_unsigned2, rd_long\ \-\ routines to read
+and write ACK-object files and libraries
+.SH SYNOPSIS
+.B #include <out.h>
+.br
+.B #include <arch.h>
+.br
+.B #include <ranlib.h>
+.PP
+.B int wr_open(filename)
+.br
+.B char *filename;
+.PP
+.B wr_close()
+.PP
+.B wr_ohead(head)
+.br
+.B struct outsect *head;
+.PP
+.B wr_sect(sect, cnt)
+.br
+.B struct outsect *sect;
+.br
+.B unsigned int cnt;
+.PP
+.B wr_outsect(sectionnr)
+.br
+.B int sectionnr;
+.PP
+.B wr_emit(emit, cnt)
+.br
+.B char *emit;
+.br
+.B long cnt;
+.PP
+.B wr_putc(ch)
+.PP
+.B wr_relo(relo, cnt)
+.br
+.B struct outrelo *relo;
+.br
+.B unsigned int cnt;
+.PP
+.B wr_name(name, cnt)
+.br
+.B struct name *name;
+.br
+.B unsigned int cnt;
+.PP
+.B wr_string(stringaddr, cnt)
+.br
+.B char *stringaddr;
+.br
+.B long cnt;
+.PP
+.B wr_arhdr(fd, arhdr)
+.br
+.B struct arhdr *arhdr;
+.PP
+.B wr_ranlib(fd, ran, cnt)
+.br
+.B struct ranlib *ran;
+.br
+.B long cnt;
+.PP
+.B wr_int2(fd, i)
+.PP
+.B wr_long(fd, l)
+.br
+.B long l;
+.PP
+.B int rd_open(filename)
+.br
+.B char *filename;
+.PP
+.B int rd_fdopen(fd)
+.PP
+.B rd_close()
+.PP
+.B rd_ohead(head)
+.br
+.B struct outsect *head;
+.PP
+.B rd_sect(sect, cnt)
+.br
+.B struct outsect *sect;
+.br
+.B unsigned int cnt;
+.PP
+.B rd_outsect(sectionnr)
+.br
+.B int sectionnr;
+.PP
+.B rd_emit(emit, cnt)
+.br
+.B char *emit;
+.br
+.B long cnt;
+.PP
+.B rd_relo(relo, cnt)
+.br
+.B struct outrelo *relo;
+.br
+.B unsigned int cnt;
+.PP
+.B rd_rew_relo(head)
+.br
+.B struct outhead *head;
+.PP
+.B rd_name(name, cnt)
+.br
+.B struct name *name;
+.br
+.B unsigned int cnt;
+.PP
+.B rd_string(stringaddr, cnt)
+.br
+.B char *stringaddr;
+.br
+.B long cnt;
+.PP
+.B rd_arhdr(fd, arhdr)
+.br
+.B struct arhdr *arhdr;
+.PP
+.B rd_ranlib(fd, ran, cnt)
+.br
+.B struct ranlib *ran;
+.br
+.B long cnt;
+.PP
+.B int rd_int2(fd)
+.PP
+.B unsigned int rd_unsigned2(fd)
+.PP
+.B long rd_long(fd)
+.SH DESCRIPTION
+These routines come in handy when reading or writing ACK-object files
+or libraries. No checking is performed.
+.PP
+.I Wr_open
+opens the file
+.I filename
+for writing and initializes some of this modules local variables.
+It must be called before writing parts of the object file.
+It returns 1 if it succeeds, 0 if it fails.
+.PP
+.I Wr_close
+closes the object file. Don't forget to call it, because it might
+flush internal buffers.
+.PP
+.I Wr_ohead
+writes the
+.I head
+header structure.
+This routine must be called before the routines to write the other
+parts.
+.PP
+.I Wr_sect
+writes
+.I cnt
+section headers, starting at
+.IB sect .
+Before writing a section, its section header must be written.
+.PP
+.I Wr_outsect
+indicates that the next section to be written is
+.IB sectionnr .
+This routine can be used to switch between sections.
+.PP
+.I Wr_emit
+writes
+.I cnt
+bytes, starting at
+.IB emit ,
+of the current section.
+.PP
+.I Wr_putc
+adds character
+.I ch
+to the current section.
+.PP
+.I Wr_relo
+writes
+.I cnt
+outrelo structures, indicated by
+.IB relo ,
+in the relocation information part of the object file.
+.PP
+.I Wr_name
+writes
+.I cnt
+outname structures, indicated by
+.IB name ,
+in the name-table part of the object file.
+.PP
+.I Wr_string
+writes
+.I cnt
+bytes, indicated by
+.IB stringaddr ,
+in the string table part of the object file.
+.PP
+The next few routines can be used independantly:
+.I Wr_arhdr
+writes the archive member header
+.I arhdr
+to file descriptor
+.IB fd .
+.PP
+.I Wr_ranlib
+writes
+.I cnt
+ranlib structures, indicated by
+.IB ran ,
+to file descriptor
+.IB fd.
+.PP
+.I Wr_int2
+writes a 2-byte integer
+.I i
+to file descriptor
+.IB fd ,
+low order byte first.
+.PP
+.I Wr_long
+writes a 4-byte integer
+.I l
+to file descriptor
+.IB fd ,
+low order word first, low order byte first.
+.PP
+Most of the
+.I rd_
+routines are the opposite of the
+.I wr_
+routines. However, a few of them deserve special mentioning:
+.PP
+.I Rd_fdopen
+initialises for reading an "object file" from file descriptor
+.IB fd ,
+at its current position.
+This is useful for reading an object that resides in an archive.
+It returns 1 if it succeeds, 0 otherwise.
+If you use this entry point for reading, you don't have to call
+.I rd_close
+to close the file. You can close the file yourself.
+.PP
+.I Rd_rew_relo
+rewinds the relocation part, so that it can be read again.
+\fILed\fR(1) sometimes needs this.
+.PP
+.I Rd_unsigned2
+reads two bytes from file descriptor
+.I fd
+and interpretes them as an unsigned integer.
+.PP
+When using any of the reading routines, you must define a routine
+named
+.IB rd_fatal .
+It is called when a read fails, and is not supposed to return.
+Likewise, a routine
+.I wr_fatal
+must be defined when using any of the writing routines.
+.SH FILES
+~em/h/out.h
+.br
+~em/h/arch.h
+.br
+~em/h/ranlib.h
+.br
+~em/modules/lib/libobject.a: the library in which these routines reside
+.SH "SEE ALSO"
+ack.out(5), arch(1), aal(1)
+.SH DIAGNOSTICS
+The routines
+.IB wr_open ,
+.IB rd_open ,
+and
+.I rd_fdopen
+return 0 if they fail, and 1 if they succeed.
--- /dev/null
+#include "byte_order.h"
+
+#if CHAR_UNSIGNED
+#define Xchar(ch) (ch)
+#else
+#define Xchar(ch) ((ch) & 0377)
+#endif
+
+#if BYTES_REVERSED
+#define uget2(c) (Xchar((c)[0]) | ((unsigned) Xchar((c)[1]) << 8))
+#define Xput2(i, c) (((c)[0] = (i)), ((c)[1] = (i) >> 8))
+#define put2(i, c) { register int j = (i); Xput2(j, c); }
+#else
+#define uget2(c) (* ((unsigned short *) (c)))
+#define Xput2(i, c) (* ((short *) (c)) = (i))
+#define put2(i, c) Xput2(i, c)
+#endif
+
+#define get2(c) ((short) uget2(c))
+
+#if WORDS_REVERSED || BYTES_REVERSED
+#define get4(c) (uget2(c) | ((long) uget2((c)+2) << 16))
+#define put4(l, c) { register long x=(l); \
+ Xput2((int)x,c); \
+ Xput2((int)(x>>16),(c)+2); \
+ }
+#else
+#define get4(c) (* ((long *) (c)))
+#define put4(l, c) (* ((long *) (c)) = (l))
+#endif
--- /dev/null
+#include <out.h>
+#include "object.h"
+
+extern long lseek();
+
+/*
+ * Parts of the output file.
+ */
+#define PARTEMIT 0
+#define PARTRELO 1
+#define PARTNAME 2
+#define PARTCHAR 3
+#ifdef SYMDBUG
+#define PARTDBUG 4
+#else
+#define PARTDBUG 3
+#define NPARTS (PARTDBUG + 1)
+
+static long offset[MAXSECT];
+
+static int outfile;
+static long outseek[NPARTS];
+static long currpos;
+static long rd_base;
+#define OUTSECT(i) \
+ (outseek[PARTEMIT] = offset[i])
+#define BEGINSEEK(p, o) \
+ (outseek[(p)] = (o))
+
+static int sectionnr;
+
+static
+OUTREAD(p, b, n)
+ char *b;
+ long n;
+{
+ register long l = outseek[p];
+
+ if (currpos != l) {
+ lseek(outfile, l, 0);
+ }
+ rd_bytes(outfile, b, n);
+ l += n;
+ currpos = l;
+ outseek[p] = l;
+}
+
+/*
+ * Open the output file according to the chosen strategy.
+ */
+int
+rd_open(f)
+ char *f;
+{
+
+ if ((outfile = open(f, 0)) < 0)
+ return 0;
+ return rd_fdopen(outfile);
+}
+
+static int offcnt;
+
+rd_fdopen(fd)
+{
+ register int i;
+
+ for (i = 0; i < NPARTS; i++) outseek[i] = 0;
+ offcnt = 0;
+ rd_base = lseek(fd, 0L, 1);
+ if (rd_base < 0) {
+ return 0;
+ }
+ currpos = rd_base;
+ outseek[PARTEMIT] = currpos;
+ outfile = fd;
+ sectionnr = 0;
+ return 1;
+}
+
+rd_close()
+{
+
+ close(outfile);
+}
+
+rd_ohead(head)
+ register struct outhead *head;
+{
+ register long off;
+
+ OUTREAD(PARTEMIT, (char *) head, (long) SZ_HEAD);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outhead) != SZ_HEAD)
+#endif
+ {
+ register char *c = (char *) head + (SZ_HEAD-4);
+
+ head->oh_nchar = get4(c);
+ c -= 4; head->oh_nemit = get4(c);
+ c -= 2; head->oh_nname = uget2(c);
+ c -= 2; head->oh_nrelo = uget2(c);
+ c -= 2; head->oh_nsect = uget2(c);
+ c -= 2; head->oh_flags = uget2(c);
+ c -= 2; head->oh_stamp = uget2(c);
+ c -= 2; head->oh_magic = uget2(c);
+ }
+ off = OFF_RELO(*head) + rd_base;
+ BEGINSEEK(PARTRELO, off);
+ off += (long) head->oh_nrelo * SZ_RELO;
+ BEGINSEEK(PARTNAME, off);
+ off += (long) head->oh_nname * SZ_NAME;
+ BEGINSEEK(PARTCHAR, off);
+#ifdef SYMDBUG
+ off += head->oh_nchar;
+ BEGINSEEK(PARTDBUG, off);
+#endif
+}
+
+rd_rew_relos(head)
+ register struct outhead *head;
+{
+ register long off = OFF_RELO(*head) + rd_base;
+
+ BEGINSEEK(PARTRELO, off);
+}
+
+rd_sect(sect, cnt)
+ register struct outsect *sect;
+ register unsigned int cnt;
+{
+ register char *c = (char *) sect + cnt * SZ_SECT;
+
+ OUTREAD(PARTEMIT, (char *) sect, (long)cnt * SZ_SECT);
+ sect += cnt;
+ offcnt += cnt;
+ while (cnt--) {
+ sect--;
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outsect) != SZ_SECT) {
+#endif
+ c -= 4; sect->os_lign = get4(c);
+ c -= 4; sect->os_flen = get4(c);
+ c -= 4; sect->os_foff = get4(c);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ }
+#endif
+ offset[--offcnt] = sect->os_foff + rd_base;
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outsect) != SZ_SECT) {
+#endif
+ c -= 4; sect->os_size = get4(c);
+ c -= 4; sect->os_base = get4(c);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ }
+#endif
+ }
+}
+
+rd_outsect(s)
+{
+ OUTSECT(s);
+ sectionnr = s;
+}
+
+/*
+ * We don't have to worry about byte order here.
+ */
+rd_emit(emit, cnt)
+ char *emit;
+ long cnt;
+{
+ OUTREAD(PARTEMIT, emit, cnt);
+ offset[sectionnr] += cnt;
+}
+
+rd_relo(relo, cnt)
+ register struct outrelo *relo;
+ register unsigned int cnt;
+{
+
+ OUTREAD(PARTRELO, (char *) relo, (long) cnt * SZ_RELO);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outrelo) != SZ_RELO)
+#endif
+ {
+ register char *c = (char *) relo + (long) cnt * SZ_RELO;
+
+ relo += cnt;
+ while (cnt--) {
+ relo--;
+ c -= 4; relo->or_addr = get4(c);
+ c -= 2; relo->or_nami = uget2(c);
+ relo->or_sect = *--c;
+ relo->or_type = *--c;
+ }
+ }
+}
+
+rd_name(name, cnt)
+ register struct outname *name;
+ register unsigned int cnt;
+{
+
+ OUTREAD(PARTNAME, (char *) name, (long) cnt * SZ_NAME);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outname) != SZ_NAME)
+#endif
+ {
+ register char *c = (char *) name + (long) cnt * SZ_NAME;
+
+ name += cnt;
+ while (cnt--) {
+ name--;
+ c -= 4; name->on_valu = get4(c);
+ c -= 2; name->on_desc = uget2(c);
+ c -= 2; name->on_type = uget2(c);
+ c -= 4; name->on_foff = get4(c);
+ }
+ }
+}
+
+rd_string(addr, len)
+ char *addr;
+ long len;
+{
+
+ OUTREAD(PARTCHAR, addr, len);
+}
+
+#ifdef SYMDBUG
+rd_dbug(buf, size)
+ char *buf;
+ long size;
+{
+ OUTREAD(PARTDBUG, buf, size);
+}
+#endif
--- /dev/null
+#include <arch.h>
+#include "object.h"
+
+rd_arhdr(fd, arhdr)
+ register struct ar_hdr *arhdr;
+{
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof (struct ar_hdr) != AR_TOTAL)
+#endif
+ {
+ char buf[AR_TOTAL];
+ register char *c = buf;
+ register char *p = arhdr->ar_name;
+ register int i = 14;
+
+ rd_bytes(fd, c, (long) AR_TOTAL);
+ while (i--) {
+ *p++ = *c++;
+ }
+ arhdr->ar_date = get4(c); c += 4;
+ arhdr->ar_uid = *c++;
+ arhdr->ar_gid = *c++;
+ arhdr->ar_mode = get2(c); c += 2;
+ arhdr->ar_size = get4(c);
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else rd_bytes(fd, (char *) arhdr, (long) AR_TOTAL);
+#endif
+}
--- /dev/null
+#define MININT (1 << (sizeof(int) * 8 - 1))
+#define MAXCHUNK (-(MININT + 1)) /* Highest count we write(2). */
+
+/*
+ * We don't have to worry about byte order here.
+ * Just read "cnt" bytes from file-descriptor "fd".
+ */
+int
+rd_bytes(fd, string, cnt)
+ register char *string;
+ register long cnt;
+{
+
+ while (cnt) {
+ register int n = cnt >= MAXCHUNK ? MAXCHUNK : cnt;
+
+ if (read(fd, string, n) != n)
+ rd_fatal();
+ string += n;
+ cnt -= n;
+ }
+}
--- /dev/null
+#include "object.h"
+
+int
+rd_int2(fd)
+{
+ char buf[2];
+
+ rd_bytes(fd, buf, 2L);
+ return get2(buf);
+}
--- /dev/null
+#include "object.h"
+
+long
+rd_long(fd)
+{
+ char buf[4];
+
+ rd_bytes(fd, buf, 4L);
+ return get4(buf);
+}
--- /dev/null
+#include <ranlib.h>
+#include "object.h"
+
+rd_ranlib(fd, ran, cnt)
+ register struct ranlib *ran;
+ register long cnt;
+{
+ rd_bytes(fd, (char *) ran, cnt * SZ_RAN);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof (struct ranlib) != SZ_RAN)
+#endif
+ {
+ register char *c = (char *) ran;
+
+ while (cnt--) {
+ ran->ran_off = get4(c); c += 4;
+ ran->ran_pos = get4(c); c += 4;
+ ran++;
+ }
+ }
+}
--- /dev/null
+#include "object.h"
+
+unsigned int
+rd_unsigned2(fd)
+{
+ char buf[2];
+
+ rd_bytes(fd, buf, 2L);
+ return uget2(buf);
+}
--- /dev/null
+/*
+ * You can choose between two strategies:
+ * - Open the output file several times, once for each logical part, and
+ * write to it in multiple places.
+ * - Open the output file once and seek back and forth to each logical
+ * part. In this case #define OUTSEEK.
+ */
+
+#include <out.h>
+#include "object.h"
+
+extern long lseek();
+
+/*
+ * Parts of the output file.
+ */
+#define PARTEMIT 0
+#define PARTRELO 1
+#define PARTNAME 2
+#define PARTCHAR 3
+#ifdef SYMDBUG
+#define PARTDBUG 4
+#else
+#define PARTDBUG 3
+#endif
+#define NPARTS (PARTDBUG + 1)
+
+static long offset[MAXSECT];
+
+#ifdef OUTSEEK
+static int outfile;
+static long outseek[NPARTS];
+static long currpos;
+#define OUTSECT(i) \
+ (outseek[PARTEMIT] = offset[i])
+static
+OUTWRITE(p, b, n) {
+ char *b;
+ long n;
+{
+ register long l = outseek[p];
+
+ if (currpos != l) {
+ lseek(outfile, l, 0);
+ }
+ wr_bytes(outfile, b, n);
+ currpos = l + n;
+ outseek[p] = currpos;
+}
+
+#define BEGINSEEK(p, o) \
+ (outseek[(p)] = (o))
+
+#else OUTSEEK
+
+static int outfile[NPARTS];
+static long currpos[NPARTS];
+#define OUTSECT(i) \
+ (currpos[PARTEMIT] == offset[(i)] ?\
+ 0 :\
+ (currpos[PARTEMIT] = offset[(i)],\
+ lseek(outfile[PARTEMIT], currpos[PARTEMIT], 0)))
+#define OUTWRITE(p, b, n) \
+ (wr_bytes(outfile[(p)], (b), (n)), currpos[(p)] += (n))
+#define BEGINSEEK(p, o) \
+ (currpos[(p)] = lseek(outfile[(p)], (o), 0))
+
+#endif OUTSEEK
+
+int _ocnt;
+char *_pbuf;
+static int sectionnr;
+static int offcnt;
+
+/*
+ * Open the output file according to the chosen strategy.
+ */
+int
+wr_open(f)
+ char *f;
+{
+#ifndef OUTSEEK
+ register int *fdp;
+#endif OUTSEEK
+
+ close(creat(f, 0666));
+#ifdef OUTSEEK
+ if ((outfile = open(f, 1)) < 0)
+ return 0;
+ currpos = 0;
+#else OUTSEEK
+ for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++)
+ if ((*fdp = open(f, 1)) < 0)
+ return 0;
+#endif OUTSEEK
+ offcnt = 0;
+ return 1;
+}
+
+wr_close()
+{
+#ifndef OUTSEEK
+ register int *fdp;
+#endif not OUTSEEK
+
+ if (_ocnt) {
+ wr_flush();
+ }
+#ifdef OUTSEEK
+ close(outfile);
+#else not OUTSEEK
+ for (fdp = &outfile[PARTEMIT]; fdp < &outfile[NPARTS]; fdp++) {
+ close(*fdp);
+ }
+#endif not OUTSEEK
+}
+
+wr_ohead(head)
+ register struct outhead *head;
+{
+ register long off = OFF_RELO(*head);
+
+ BEGINSEEK(PARTEMIT, 0L);
+ BEGINSEEK(PARTRELO, off);
+ off += (long) head->oh_nrelo * SZ_RELO;
+ BEGINSEEK(PARTNAME, off);
+ off += (long) head->oh_nname * SZ_NAME;
+ BEGINSEEK(PARTCHAR, off);
+#ifdef SYMDBUG
+ off += head->oh_nchar;
+ BEGINSEEK(PARTDBUG, off);
+#endif
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outhead) != SZ_HEAD)
+#endif
+ {
+ char buf[SZ_HEAD];
+ register char *c = buf;
+
+ put2(head->oh_magic, c); c += 2;
+ put2(head->oh_stamp, c); c += 2;
+ put2(head->oh_flags, c); c += 2;
+ put2(head->oh_nsect, c); c += 2;
+ put2(head->oh_nrelo, c); c += 2;
+ put2(head->oh_nname, c); c += 2;
+ put4(head->oh_nemit, c); c += 4;
+ put4(head->oh_nchar, c);
+ OUTWRITE(PARTEMIT, buf, (long) SZ_HEAD);
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else OUTWRITE(PARTEMIT, (char *) head, (long) SZ_HEAD);
+#endif
+}
+
+wr_sect(sect, cnt1)
+ register struct outsect *sect;
+ unsigned int cnt1;
+{
+ char buf[MAXSECT * SZ_SECT];
+ register char *c = buf;
+ register unsigned int cnt = cnt1;
+
+ while (cnt--) {
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outsect) != SZ_SECT)
+#endif
+ {
+ put4(sect->os_base, c); c += 4;
+ put4(sect->os_size, c); c += 4;
+ put4(sect->os_foff, c); c += 4;
+ }
+ offset[offcnt++] = sect->os_foff;
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outsect) != SZ_SECT)
+#endif
+ {
+ put4(sect->os_flen, c); c += 4;
+ put4(sect->os_lign, c); c += 4;
+ }
+ sect++;
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outsect) != SZ_SECT)
+#endif
+ OUTWRITE(PARTEMIT, buf, (long) cnt1 * SZ_SECT);
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else
+ OUTWRITE(PARTEMIT, (char *) (sect - cnt1), (long) cnt1 * SZ_SECT);
+#endif
+}
+
+wr_flush()
+{
+ OUTWRITE(PARTEMIT, _pbuf, (long) _ocnt);
+ offset[sectionnr] += _ocnt;
+ _ocnt = 0;
+}
+
+wr_outsect(s)
+{
+ if (s != sectionnr) {
+ if (_ocnt) {
+ wr_flush();
+ }
+ sectionnr = s;
+ OUTSECT(s);
+ }
+}
+
+/*
+ * We don't have to worry about byte order here.
+ */
+wr_emit(emit, cnt)
+ char *emit;
+ long cnt;
+{
+ if (_ocnt) wr_flush();
+ OUTWRITE(PARTEMIT, emit, cnt);
+ offset[sectionnr] += cnt;
+}
+
+wr_relo(relo, cnt)
+ register struct outrelo *relo;
+ register unsigned int cnt;
+{
+ long l;
+
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outrelo) != SZ_RELO)
+#endif
+ {
+ char buf[100 * SZ_RELO];
+ register char *c = buf;
+ register int i = 0;
+
+ while (cnt--) {
+ *c++ = relo->or_type;
+ *c++ = relo->or_sect;
+ put2(relo->or_nami, c); c += 2;
+ put4(relo->or_addr, c); c += 4;
+ relo++;
+ i++;
+ if (i == 100 || cnt == 0) {
+ c = buf;
+ l = (long) (i * SZ_RELO);
+ OUTWRITE(PARTRELO, c, l);
+ i = 0;
+ }
+ }
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else {
+ l = (long) cnt * SZ_RELO;
+ OUTWRITE(PARTRELO, (char *) relo, l);
+ }
+#endif
+}
+
+wr_name(name, cnt)
+ register struct outname *name;
+ register unsigned int cnt;
+{
+ long l;
+
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof(struct outname) != SZ_NAME)
+#endif
+ {
+ char buf[100 * SZ_NAME];
+ register char *c = buf;
+ register int i = 0;
+
+ while (cnt--) {
+ put4(name->on_foff,c); c += 4;
+ put2(name->on_type,c); c += 2;
+ put2(name->on_desc,c); c += 2;
+ put4(name->on_valu,c); c += 4;
+ name++;
+ i++;
+ if (i == 100 || !cnt) {
+ c = buf;
+ l = (long) (i * SZ_NAME);
+ OUTWRITE(PARTNAME, c, l);
+ i = 0;
+ }
+ }
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else {
+ l = (long)cnt * SZ_NAME;
+ OUTWRITE(PARTNAME, (char *) name, l);
+ }
+#endif
+
+}
+
+wr_string(addr, len)
+ char *addr;
+ long len;
+{
+
+ OUTWRITE(PARTCHAR, addr, len);
+}
+
+#ifdef SYMDBUG
+
+wr_dbug(buf, size)
+ char *buf;
+ long size;
+{
+ OUTWRITE(PARTDBUG, buf, size);
+}
+
+#endif SYMDBUG
--- /dev/null
+#include <arch.h>
+#include "object.h"
+
+wr_arhdr(fd, arhdr)
+ register struct ar_hdr *arhdr;
+{
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof (struct ar_hdr) != AR_TOTAL)
+#endif
+ {
+ char buf[AR_TOTAL];
+ register char *c = buf;
+ register char *p = arhdr->ar_name;
+ register int i = 14;
+
+ while (i--) {
+ *c++ = *p++;
+ }
+ put4(arhdr->ar_date,c); c += 4;
+ *c++ = arhdr->ar_uid;
+ *c++ = arhdr->ar_gid;
+ put2(arhdr->ar_mode,c); c += 2;
+ put4(arhdr->ar_size,c);
+ wr_bytes(fd, buf, (long) AR_TOTAL);
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else wr_bytes(fd, (char *) arhdr, (long) AR_TOTAL);
+#endif
+}
--- /dev/null
+#define MININT (1 << (sizeof(int) * 8 - 1))
+#define MAXCHUNK (-(MININT + 1)) /* Highest count we write(2). */
+
+/*
+ * Just write "cnt" bytes to file-descriptor "fd".
+ */
+wr_bytes(fd, string, cnt)
+ register char *string;
+ register long cnt;
+{
+
+ while (cnt) {
+ register int n = cnt >= MAXCHUNK ? MAXCHUNK : cnt;
+
+ if (write(fd, string, n) != n)
+ wr_fatal();
+ string += n;
+ cnt -= n;
+ }
+}
--- /dev/null
+#include "object.h"
+
+wr_int2(fd, i)
+{
+ char buf[2];
+
+ put2(i, buf);
+ wr_bytes(fd, buf, 2L);
+}
--- /dev/null
+#include "object.h"
+
+wr_long(fd, l)
+ long l;
+{
+ char buf[4];
+
+ put4(l, buf);
+ wr_bytes(fd, buf, 4L);
+}
--- /dev/null
+#include <stdio.h>
+
+static char buf[BUFSIZ];
+
+extern char *_pbuf;
+extern int _ocnt;
+
+wr_putc(ch)
+{
+ _pbuf = buf;
+ buf[_ocnt++] = ch;
+ if (_ocnt == BUFSIZ) {
+ wr_flush();
+ }
+}
--- /dev/null
+#include <ranlib.h>
+#include "object.h"
+
+wr_ranlib(fd, ran, cnt)
+ register struct ranlib *ran;
+ register long cnt;
+{
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ if (sizeof (struct ranlib) != SZ_RAN)
+#endif
+ {
+ char buf[100 * SZ_RAN];
+
+ while (cnt) {
+ register int i = (cnt > 100) ? 100 : cnt;
+ register char *c = buf;
+ long j = i * SZ_RAN;
+
+ cnt -= i;
+ while (i--) {
+ put4(ran->ran_off,c); c += 4;
+ put4(ran->ran_pos,c); c += 4;
+ ran++;
+ }
+ wr_bytes(fd, c, j);
+ }
+ }
+#if ! (BYTES_REVERSED || WORDS_REVERSED)
+ else wr_bytes(fd, (char *) ran, cnt * SZ_RAN);
+#endif
+}