/* Copyright (c)1994-2000 Begemot Computer Associates. All rights reserved.
 * See the file COPYRIGHT for details of redistribution and use. */

/*
 * write the manufacturers bad sector file onto the last
 * track of an rl02 disk
 */
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <fcntl.h>
# include <errno.h>
# include <unistd.h>
# include <netinet/in.h>
# ifdef HAVE_GETOPT_H
#  include <getopt.h>
# endif

# include <begemot.h>
# include "cdefs.h"
# include "util.h"

RCSID("$Id: fmt.c 476 2001-07-09 08:09:10Z hbb $")

# define RL_MDBSF_POS		20460		/* starting lbn of file */
# define RL_MDBSF_BLOCKS	20		/* size in blocks of file */

# define RP_POS (19*22*815 - 1)

void	rl(char *file, char *sno);
void	rp(char *file);

u_short	buf[256];


static char usgtxt[] =
"Usage: fmt rl file serial-no\n"
"   or: fmt rp file\n"
"   or: fmt [-h]\n"
"Options:\n"
"	-h	print this help\n";

u_short little_endian(u_short u);
static void	usage(void) DEAD_FUNC;

int
main(int argc, char *argv[])
{
	int opt;

	set_argv0(argv[0]);
	while((opt = getopt(argc, argv, "h")) != EOF)
		switch(opt) {

		  case 'h':
			usage();
			break;
		}
	argc -= optind;
	argv += optind;

	if(argc < 2)
		usage();

	if(!strcmp(argv[0], "rl")) {
		argc--; argv++;
		if(argc != 2)
			usage();
		rl(argv[0], argv[1]);
	} else if(!strcmp(argv[0], "rp")) {
		argc--; argv++;
		if(argc != 1)
			usage();
		rp(argv[0]);
	} else
		usage();

	return 0;
}

static void
usage()
{
	fprintf(stderr, usgtxt);
	exit(1);
}


void
rl(char *file, char *sno)
{
	int	b, fd;
	long	serial;

	serial = strtol(sno, 0, 0);

	memset(buf, 0377, sizeof(buf));
	buf[0] = little_endian((u_short)(serial >> 16));
	buf[1] = little_endian((u_short)serial);
	buf[2] = 0;
	buf[3] = 0;

	if((fd = open(file, O_WRONLY | O_CREAT, 0666)) < 0)
		panic("%s: %s", file, strerror(errno));

	if(lseek(fd, RL_MDBSF_POS * 512L, SEEK_SET) != RL_MDBSF_POS * 512L)
		panic("lseek: %s", strerror(errno));

	for(b = 0; b < RL_MDBSF_BLOCKS; b++)
		if(write(fd, buf, sizeof(buf)) != sizeof(buf))
			panic("write: %s", strerror(errno));
	close(fd);
}



void
rp(char *file)
{
	int fd;

	if((fd = open(file, O_WRONLY|O_CREAT, 0666)) < 0)
		panic("%s: %s", file, strerror(errno));
	if(lseek(fd, RP_POS*512, 0) != RP_POS*512)
		panic("lseek: %s", strerror(errno));

	buf[0] = little_endian(0001401);
	buf[1] = little_endian(0176000);
	buf[255] = little_endian(0177401);

	if(write(fd, buf, 512)  != 512)
		panic("write: %s", strerror(errno));
	close(fd);
}

u_short
little_endian(u_short u)
{
	u_short	n = htons(u);
	return ((n & 0377) << 8) | ((n & 0177400) >> 8);
}

