* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Hugh Smith at The University of Guelph.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)build.c 5.1 (Berkeley) %G%";
extern CHDR chdr
; /* converted header */
extern char *archive
; /* archive name */
extern char *tname
; /* temporary file "name" */
struct _rlib
*next
; /* next structure */
off_t pos
; /* offset of defining archive file */
int symlen
; /* strlen(sym) */
afd
= open_archive(O_RDWR
);
SETCF(afd
, archive
, tfd
, tname
, RPAD
|WPAD
);
/* Read through the archive, creating list of symbols. */
if (!strcmp(chdr
.name
, RANLIBMAG
)) {
SKIP(afd
, chdr
.size
, archive
);
put_header(&cf
, (struct stat
*)NULL
);
copyfile(&cf
, chdr
.size
);
/* Create the symbol table. */
/* Copy the saved objects into the archive. */
size
= lseek(tfd
, (off_t
)0, SEEK_CUR
);
(void)lseek(tfd
, (off_t
)0, SEEK_SET
);
SETCF(tfd
, tname
, afd
, archive
, RPAD
|WPAD
);
(void)ftruncate(afd
, lseek(afd
, (off_t
)0, SEEK_CUR
));
long symcnt
; /* symbol count */
long tsymlen
; /* total string length */
* Read the exec structure; ignore any files that don't look
register char *strtab
, *sym
;
/* Get current offsets for original and tmp files. */
r_off
= lseek(rfd
, (off_t
)0, SEEK_CUR
);
w_off
= lseek(wfd
, (off_t
)0, SEEK_CUR
);
/* Read in exec structure. */
nr
= read(rfd
, (char *)&ebuf
, sizeof(struct exec
));
if (nr
!= sizeof(struct exec
))
/* Check magic number and symbol count. */
if (N_BADMAG(ebuf
) || ebuf
.a_syms
== 0)
/* Seek to string table. */
if (lseek(rfd
, N_STROFF(ebuf
) + r_off
, SEEK_SET
) == (off_t
)-1)
/* Read in size of the string table. */
nr
= read(rfd
, (char *)&strsize
, sizeof(strsize
));
if (nr
!= sizeof(strsize
))
/* Read in the string table. */
strsize
-= sizeof(strsize
);
strtab
= (char *)emalloc(strsize
);
nr
= read(rfd
, strtab
, strsize
);
/* Seek to symbol table. */
if (fseek(fp
, N_SYMOFF(ebuf
) + r_off
, SEEK_SET
) == (off_t
)-1)
/* For each symbol read the nlist entry and save it as necessary. */
nsyms
= ebuf
.a_syms
/ sizeof(struct nlist
);
if (!fread((char *)&nl
, sizeof(struct nlist
), 1, fp
)) {
/* Ignore if no name or local. */
if (!nl
.n_un
.n_strx
|| !(nl
.n_type
& N_EXT
))
* If the symbol is an undefined external and the n_value
* field is non-zero, keep it.
if ((nl
.n_type
& N_TYPE
) == N_UNDF
&& !nl
.n_value
)
/* First four bytes are the table size. */
sym
= strtab
+ nl
.n_un
.n_strx
- sizeof(long);
symlen
= strlen(sym
) + 1;
rp
= (RLIB
*)emalloc(sizeof(RLIB
));
rp
->sym
= (char *)emalloc(symlen
);
bcopy(sym
, rp
->sym
, symlen
);
/* Build in forward order for "ar -m" command. */
bad1
: (void)lseek(rfd
, (off_t
)r_off
, SEEK_SET
);
* Write the symbol table into the archive, computing offsets as
char hb
[sizeof(struct ar_hdr
) + 1], pad
;
long ransize
, size
, stroff
;
/* Rewind the archive, leaving the magic number. */
if (fseek(fp
, (off_t
)SARMAG
, SEEK_SET
) == (off_t
)-1)
/* Size of the ranlib archive file, pad if necessary. */
symcnt
* sizeof(struct ranlib
) + sizeof(long) + tsymlen
;
/* Put out the ranlib archive file header. */
#define DEFMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
(void)sprintf(hb
, HDR2
, RANLIBMAG
, 0L, getuid(), getgid(),
DEFMODE
& ~umask(), ransize
, ARFMAG
);
if (!fwrite(hb
, sizeof(struct ar_hdr
), 1, fp
))
/* First long is the size of the ranlib structure section. */
size
= symcnt
* sizeof(struct ranlib
);
if (!fwrite((char *)&size
, sizeof(size
), 1, fp
))
/* Offset of the first archive file. */
size
= SARMAG
+ sizeof(struct ar_hdr
) + ransize
;
* Write out the ranlib structures. The offset into the string
* table is cumulative, the offset into the archive is the value
* set in rexec() plus the offset to the first archive file.
for (rp
= rhead
, stroff
= 0; rp
; rp
= rp
->next
) {
rn
.ran_un
.ran_strx
= stroff
;
rn
.ran_off
= size
+ rp
->pos
;
if (!fwrite((char *)&rn
, sizeof(struct ranlib
), 1, fp
))
/* Second long is the size of the string table. */
if (!fwrite((char *)&tsymlen
, sizeof(tsymlen
), 1, fp
))
/* Write out the string table. */
for (rp
= rhead
; rp
; rp
= rp
->next
)
if (!fwrite(rp
->sym
, rp
->symlen
, 1, fp
))
if (pad
&& !fwrite(&pad
, sizeof(pad
), 1, fp
))