view tool/archive.c @ 3:003df9892e57

import original TCS211 libs from Sotovik
author Space Falcon <falcon@ivan.Harhan.ORG>
date Fri, 05 Jun 2015 21:19:08 +0000
parents 058d377fc299
children e33380b5bd46
line wrap: on
line source

/*
 * This module implements archive processing for ti-libpatch.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "ar.h"
#include "globals.h"

process_archive()
{
	FILE *inf, *outf;
	char ar_signature_buf[SARMAG];
	struct ar_hdr ar_hdr;
	char member_name[17], *cp;
	unsigned size;
	char *buf;

	inf = fopen(lib_in_filename, "r");
	if (!inf) {
		perror(lib_in_filename);
		exit(1);
	}
	if (fread(ar_signature_buf, 1, SARMAG, inf) != SARMAG ||
	    strncmp(ar_signature_buf, ARMAG, SARMAG)) {
		fprintf(stderr, "error: %s is not an archive\n",
			lib_in_filename);
		exit(1);
	}
	outf = fopen(lib_out_filename, "w");
	if (!outf) {
		perror(lib_out_filename);
		exit(1);
	}
	fwrite(ar_signature_buf, 1, SARMAG, outf);
	while (fread(&ar_hdr, sizeof(struct ar_hdr), 1, inf)) {
		if (strncmp(ar_hdr.ar_fmag, ARFMAG, sizeof(ar_hdr.ar_fmag))) {
			fprintf(stderr, "error parsing %s: bad ar_fmag\n",
				lib_in_filename);
			exit(1);
		}
		bcopy(ar_hdr.ar_name, member_name, 16);
		member_name[16] = '\0';
		cp = index(member_name, '/');
		if (!cp) {
			fprintf(stderr,
				"error parsing %s: no \'/\' in ar_name[]\n",
				lib_in_filename);
			exit(1);
		}
		*cp = '\0';
		size = strtoul(ar_hdr.ar_size, 0, 10);
		buf = malloc(size);
		if (!buf) {
			fprintf(stderr,
		"error: unable to malloc buffer for archive member \"%s\"\n",
				member_name);
			exit(1);
		}
		if (fread(buf, 1, size, inf) != size) {
			fprintf(stderr,
			"error reading the body of member \"%s\" from %s\n",
				member_name, lib_in_filename);
			exit(1);
		}
		if (size & 1 && getc(inf) != '\n') {
			fprintf(stderr,
		"error parsing %s: no \\n after odd-sized member \"%s\"\n",
				lib_in_filename, member_name);
			exit(1);
		}
		/* the patch hook will go here */
		/* write it out */
		fwrite(&ar_hdr, sizeof(struct ar_hdr), 1, outf);
		fwrite(buf, 1, size, outf);
		free(buf);
		if (size & 1)
			putc('\n', outf);
	}
	fclose(inf);
	fclose(outf);
	return(0);
}