view tool/archive.c @ 4:e33380b5bd46

tool/archive.c: preparation for making some vars global
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sat, 06 Jun 2015 03:14:02 +0000
parents 058d377fc299
children 5ba13fd0e737
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"

struct ar_hdr ar_hdr;
char member_name[17];
unsigned member_size;
u_char *member_body;

process_archive()
{
	FILE *inf, *outf;
	char ar_signature_buf[SARMAG], *cp;

	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';
		member_size = strtoul(ar_hdr.ar_size, 0, 10);
		member_body = malloc(member_size);
		if (!member_body) {
			fprintf(stderr,
		"error: unable to malloc buffer for archive member \"%s\"\n",
				member_name);
			exit(1);
		}
		if (fread(member_body, 1, member_size, inf) != member_size) {
			fprintf(stderr,
			"error reading the body of member \"%s\" from %s\n",
				member_name, lib_in_filename);
			exit(1);
		}
		if (member_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(member_body, 1, member_size, outf);
		free(member_body);
		if (member_size & 1)
			putc('\n', outf);
	}
	fclose(inf);
	fclose(outf);
	return(0);
}