DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦25970585e⟧ TextFile

    Length: 4214 (0x1076)
    Types: TextFile
    Notes: UNIX file
    Names: »ranlib.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »cmd/ranlib.c« 

TextFile

/*
 * Make libraries more accessible to the loader
 * by copying all the globally defined symbols
 * into a special module at the front of the archive.
 */
#include <stdio.h>
#include "n.out.h"
#include <ar.h>
#include <canon.h>

static	struct	ldheader	ldh;

main(argc, argv)
int	argc;
char	*argv[];
{
	register int	i, errors = 0;

	if (argc==1) {
		fprintf(stderr, "Usage: %s [ archive]+\n", argv[0]);
		exit(1);
	}
	for (i=1; i<argc; i++) {
		errors += ranlib(argv[i]);
	}
	unlink(HDRNAME);
	exit(errors);
}

static
void
complain(plaint)
char	*plaint;
{
	fprintf(stderr, "Ranlib: %r", &plaint);
	putc('\n', stderr);
}

static
void
xwrite(sym, fp)
ar_sym	*sym;
FILE	*fp;
{
	if (fwrite(sym, sizeof(ar_sym), 1, fp)!=1) {
		complain("write error on header file");
		exit(1);
	}
}

static
void
addhdr(base, arhp, hdrfp, arfp, archive)
size_t	base;
struct	ar_hdr	*arhp;
FILE	*hdrfp, *arfp;
char	*archive;
{
	size_t	off;

	cansize(arhp->ar_size);
	arhp->ar_size += off = ftell(arfp);
	off -= base;
	ldh.l_magic = 0;	/* in case fread fails */
	if (fread(&ldh, sizeof ldh, 1, arfp)!=1) {
		complain("%.*s in %s is not a load module\n",
			DIRSIZ, arhp->ar_name, archive);
	} else {
		canshort(ldh.l_magic);
		canshort(ldh.l_flag);
		if (ldh.l_magic!=L_MAGIC) {
			complain("%.*s in %s is not a load module\n",
				DIRSIZ, arhp->ar_name, archive);
		} else {
			int	seg, nsym;
			size_t	offset;

			if ((ldh.l_flag & LF_32) == 0)
				ldh.l_tbase = sizeof(ldh) - 2*sizeof(short);
			else
				canshort(ldh.l_tbase);
			offset = ldh.l_tbase - sizeof(ldh);
			for (seg=0; seg<L_SYM; seg++) {
				if (seg==L_BSSI || seg==L_BSSD)
					continue;
				cansize(ldh.l_ssize[seg]);
				offset += ldh.l_ssize[seg];
			}
			fseek(arfp, offset, 1);
			cansize(ldh.l_ssize[L_SYM]);
			if ((ldh.l_flag & LF_32) == 0)
				nsym = ldh.l_ssize[L_SYM]
				    / (sizeof(struct ldsym) - sizeof(short));
			else
				nsym = ldh.l_ssize[L_SYM]/sizeof(struct ldsym);
			while (nsym--) {
				union	{struct ldsym; ar_sym;} sym;

				if (readsym((struct ldsym *)&sym, arfp) == 0) {
					complain("truncated module %.*s in %s",
					    DIRSIZ, arhp->ar_name, archive);
					exit(1);
				}
				if ((sym.ls_type&L_GLOBAL) == 0)
					continue;
				if ((sym.ls_type&LR_SEG) != L_REF
#if 0
				 || sym.ls_addr != 0) {
#else
				) {
#endif
					sym.ar_off = off;
					cansize(sym.ar_off);
					xwrite(&sym, hdrfp);
				}
			}
		}
	}
	fseek(arfp, arhp->ar_size, 0);	/* to end of module */
	return;
}

static
readsym(sp, fp)
register struct ldsym *sp;
FILE *fp;
{
	register int r;
	union { long l; unsigned u[2]; } u;

	if ((ldh.l_flag & LF_32) == 0) {
		r = fread(sp, sizeof(struct ldsym)-sizeof(short), 1, fp);
		u.l = sp->ls_addr;
		canshort(u.u[0]);
		sp->ls_addr = u.u[0];
	} else {
		r = fread(sp, sizeof(struct ldsym), 1, fp);
		canlong(sp->ls_addr);
	}
	canshort(sp->ls_type);
	return (r);
}

static
int
ranlib(archive)
char	*archive;
{
	FILE	*arfile, *hdrfile;
	char	arcmd[256];
	struct	ar_hdr	arhdr;
	int	armagic = 0;
	size_t	arbase = sizeof armagic+sizeof arhdr;

	if ((arfile=fopen(archive, "r"))==NULL) {
		complain("can't open archive %s", archive);
		return (1);
	}
	fread(&armagic, sizeof armagic, 1, arfile);
	canint(armagic);
	if (armagic!=ARMAG) {
		complain("%s is not an archive", archive);
		fclose(arfile);
		return (1);
	}
	if (fread(&arhdr, sizeof arhdr, 1, arfile)!=1) {
		fclose(arfile);	/* void archive */
		return (0);
	}
	if ((hdrfile=fopen(HDRNAME, "w"))==NULL) {
		complain("can't create header file");
		fclose(arfile);
		exit(1);
	}
	if (strncmp(arhdr.ar_name, HDRNAME, DIRSIZ)==0) {
		sprintf(arcmd, "ar ru %s %s", archive, HDRNAME);
		cansize(arhdr.ar_size);
		fseek(arfile, arhdr.ar_size, 1);
		arbase += arhdr.ar_size+sizeof arhdr;
	} else {
		sprintf(arcmd, "ar rub %.*s %s %s", DIRSIZ, arhdr.ar_name,
			archive, HDRNAME);
		addhdr(arbase, &arhdr, hdrfile, arfile, archive);
	}
	while(fread(&arhdr, sizeof arhdr, 1, arfile)==1)
		addhdr(arbase, &arhdr, hdrfile, arfile, archive);
	if (fclose(hdrfile)==EOF) {
		complain("close error on header file");
		exit(1);
	}
	if (ferror(arfile)) {
		complain("read error on archive %s", archive);
		fclose(arfile);
		return (1);
	}
	fclose(arfile);
	system(arcmd);
	return (0);
}