/*
 * 5799-WZQ (C) COPYRIGHT = NONE
 * LICENSED MATERIALS - PROPERTY OF IBM
 */
/* $Header:1kfix.c 12.0$ */
/* $ACIS:1kfix.c 12.0$ */
/* $Source: /ibm/acis/usr/src/old/RCS/1kfix.c,v $ */

#ifndef lint
static char *rcsid = "$Header:1kfix.c 12.0$";
#endif

static	char *sccsid = "@(#)1kfix.c	4.1 (Berkeley) 10/16/80";
#include <stdio.h>
#include <a.out.h>
#include <sys/param.h>
#include <sys/vm.h>
char	*malloc();

#define	round(a,b) (((a)+((b)-1))&~(b-1))

main(argc, argv)
	int argc;
	char *argv[];
{
	char *tp, *dp, *sp;
	struct exec x, y;
	int io;
	char zeroes[NBPG];

	--argc;
	++argv;
	if (argc == 0) {
		fprintf(stderr, "usage: 1kfix file ...\n");
		exit(1);
	}
	do {
		io = open(argv[0], 2);
		if (io < 0) {
			perror(argv[0]);
			argc--, argv++;
			continue;
		}
		if (read(io, &x, sizeof x) != sizeof x)
			goto format;

		switch (x.a_magic) {

		case OMAGIC:
		case NMAGIC:
			if ((round(x.a_text,NBPG) & CLOFSET) == 0) {
				fprintf(stderr, "%s: wins as is\n", argv[0]);
				goto skip;
			}
			break;

		case ZMAGIC:
			lseek(io, NBPG, 0);
			break;

		default:
format:
			printf("%s: not object file\n", argv[0]);
			goto skip;
		}

		tp = malloc(x.a_text);
		dp = malloc(x.a_data);
		sp = malloc(x.a_syms);
		if (read(io, tp, x.a_text) != x.a_text ||
		    read(io, dp, x.a_data) != x.a_data ||
		    read(io, sp, x.a_syms) != x.a_syms) {
			fprintf(stderr, "%s: short read\n", argv[0]);
			goto skip;
		}
		close(io);
		io = creat(argv[0], 0755);
		if (io < 0) {
			perror(argv[0]);
			goto skip;
		}

		y = x;
		switch (x.a_magic) {

		case ZMAGIC: {
			int i;
			for (i = 0; i < 512; i++)
				if (tp[i] != 0)
					break;
			if (i == 512)
				printf("%s: already fixed\n", argv[0]);
			if (x.a_text & CLOFSET) {
				y.a_text -= NBPG;
				y.a_data += NBPG;
			}
			}
			break;

		case OMAGIC:
		case NMAGIC:
			y.a_text = round(x.a_text, NBPG) - NBPG;
			y.a_data += NBPG;
			if (y.a_text == 0) {
				fprintf(stderr, "%s: text size would be 0\n", argv[0]);
				goto skip;
			}
		}
		y.a_trsize = y.a_drsize = 0;
		write(io, (char *)&y, sizeof y);
		if (x.a_magic == ZMAGIC)
			lseek(io, BSIZE, 0);
		write(io, tp, x.a_text);
		if (x.a_magic != ZMAGIC)
			write(io, zeroes, round(x.a_text, NBPG) - x.a_text);
		write(io, dp, x.a_data);
		write(io, sp, x.a_syms);
		free(tp);
		free(dp);
		free(sp);
skip:
		argc--, argv++;
		close(io);
	} while (argc > 0);
	exit(0);
}
