/*
 * decode.c - program to decode SAL error records
 *
 * Copyright (c) 2003 Hewlett-Packard Co
 *	Bjorn Helgaas <bjorn.helgaas@hp.com>
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

char *
salinfo_buffer(char *path)
{
	int fd, nbytes, size, alloc;
	char *buffer;

	fd = open(path, O_RDONLY);
	if (fd == -1) {
		perror(path);
		exit(1);
	}

	buffer = NULL;
	alloc = 16 * 1024;	// total buffer size
	size = 0;		// amount of buffer used so far
	do {
		buffer = realloc(buffer, alloc);
		if (!buffer) {
			fprintf(stderr, "Can't alloc %d bytes\n", alloc);
			exit(1);
		}

		nbytes = read(fd, buffer + size, alloc - size);
		if (nbytes == -1) {
			perror("read");
			exit(1);
		}

		if (nbytes == alloc - size)
			alloc *= 2;

		size += nbytes;
	} while (nbytes);

	close(fd);

	if (size)
		return buffer;

	free(buffer);
	return NULL;
}

main(int argc, char **argv)
{
	char *path = argv[1];
	char *buffer;

	if (argc != 2) {
		fprintf(stderr, "Usage: %s file\n", argv[0]);
		exit(1);
	}

	buffer = salinfo_buffer(path);
	if (!buffer)
		exit(0);

	printf("+BEGIN HARDWARE ERROR STATE from %s\n", path);
	ia64_log_platform_info_print(buffer, printf);
	printf("+END HARDWARE ERROR STATE from %s\n", path);

	free(buffer);
}
