xref: /csrg-svn/sys/hp300/stand/mkboot.c (revision 56510)
141488Smckusick /*
241488Smckusick  * Copyright (c) 1990 The Regents of the University of California.
341488Smckusick  * All rights reserved.
441488Smckusick  *
541488Smckusick  * %sccs.include.redist.c%
641488Smckusick  *
7*56510Sbostic  *	@(#)mkboot.c	7.4 (Berkeley) 10/11/92
841488Smckusick  */
941488Smckusick 
1041488Smckusick #ifndef lint
1141488Smckusick char copyright[] =
1241488Smckusick "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
1341488Smckusick  All rights reserved.\n";
1441488Smckusick #endif /* not lint */
1541488Smckusick 
1641488Smckusick #ifndef lint
1745790Sbostic static char sccsid[] = "@(#)mkboot.c	7.2 (Berkeley) 12/16/90";
1841488Smckusick #endif /* not lint */
1941488Smckusick 
20*56510Sbostic #include <sys/param.h>
21*56510Sbostic #include <sys/exec.h>
22*56510Sbostic #include <sys/file.h>
2354073Shibler 
24*56510Sbostic #include <hp300/stand/volhdr.h>
25*56510Sbostic 
2641488Smckusick #include <stdio.h>
2741488Smckusick #include <ctype.h>
2841488Smckusick 
2941488Smckusick int lpflag;
3041488Smckusick int loadpoint;
3141488Smckusick struct load ld;
3241488Smckusick struct lifvol lifv;
3341488Smckusick struct lifdir lifd[8];
3441488Smckusick struct exec ex;
3541488Smckusick char buf[10240];
3641488Smckusick 
3741488Smckusick main(argc, argv)
3841488Smckusick 	char **argv;
3941488Smckusick {
4041488Smckusick 	int ac;
4141488Smckusick 	char **av;
4241488Smckusick 	int from1, from2, to;
4341488Smckusick 	register int n;
4441488Smckusick 	char *n1, *n2, *lifname();
4541488Smckusick 
4641488Smckusick 	ac = --argc;
4741488Smckusick 	av = ++argv;
4841488Smckusick 	if (ac == 0)
4941488Smckusick 		usage();
5041488Smckusick 	if (!strcmp(av[0], "-l")) {
5141488Smckusick 		av++;
5241488Smckusick 		ac--;
5341488Smckusick 		if (ac == 0)
5441488Smckusick 			usage();
5541488Smckusick 		sscanf(av[0], "0x%x", &loadpoint);
5641488Smckusick 		lpflag++;
5741488Smckusick 		av++;
5841488Smckusick 		ac--;
5941488Smckusick 	}
6041488Smckusick 	if (ac == 0)
6141488Smckusick 		usage();
6241488Smckusick 	from1 = open(av[0], O_RDONLY, 0);
6341488Smckusick 	if (from1 < 0) {
6441488Smckusick 		perror("open");
6541488Smckusick 		exit(1);
6641488Smckusick 	}
6741488Smckusick 	n1 = av[0];
6841488Smckusick 	av++;
6941488Smckusick 	ac--;
7041488Smckusick 	if (ac == 0)
7141488Smckusick 		usage();
7241488Smckusick 	if (ac == 2) {
7341488Smckusick 		from2 = open(av[0], O_RDONLY, 0);
7441488Smckusick 		if (from2 < 0) {
7541488Smckusick 			perror("open");
7641488Smckusick 			exit(1);
7741488Smckusick 		}
7841488Smckusick 		n2 = av[0];
7941488Smckusick 		av++;
8041488Smckusick 		ac--;
8141488Smckusick 	} else
8241488Smckusick 		from2 = -1;
8341488Smckusick 	to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644);
8441488Smckusick 	if (to < 0) {
8541488Smckusick 		perror("open");
8641488Smckusick 		exit(1);
8741488Smckusick 	}
8841488Smckusick 	/* clear possibly unused directory entries */
8941488Smckusick 	strncpy(lifd[1].dir_name, "          ", 10);
9041488Smckusick 	lifd[1].dir_type = -1;
9141488Smckusick 	lifd[1].dir_addr = 0;
9241488Smckusick 	lifd[1].dir_length = 0;
9341488Smckusick 	lifd[1].dir_flag = 0xFF;
9441488Smckusick 	lifd[1].dir_exec = 0;
9541488Smckusick 	lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
9641488Smckusick 	/* record volume info */
9741488Smckusick 	lifv.vol_id = VOL_ID;
9841488Smckusick 	strncpy(lifv.vol_label, "BOOT43", 6);
9941488Smckusick 	lifv.vol_addr = 2;
10041488Smckusick 	lifv.vol_oct = VOL_OCT;
10141488Smckusick 	lifv.vol_dirsize = 1;
10241488Smckusick 	lifv.vol_version = 1;
10341488Smckusick 	/* output bootfile one */
10441488Smckusick 	lseek(to, 3 * SECTSIZE, 0);
10541488Smckusick 	putfile(from1, to);
10641488Smckusick 	n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE;
10741488Smckusick 	strcpy(lifd[0].dir_name, lifname(n1));
10841488Smckusick 	lifd[0].dir_type = DIR_TYPE;
10941488Smckusick 	lifd[0].dir_addr = 3;
11041488Smckusick 	lifd[0].dir_length = n;
11154073Shibler 	bcddate(from1, lifd[0].dir_toc);
11241488Smckusick 	lifd[0].dir_flag = DIR_FLAG;
11341488Smckusick 	lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
11441488Smckusick 	lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length;
11541488Smckusick 	/* if there is an optional second boot program, output it */
11641488Smckusick 	if (from2 >= 0) {
11741488Smckusick 		lseek(to, (3 + n) * SECTSIZE, 0);
11841488Smckusick 		putfile(from2, to);
11941488Smckusick 		n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE;
12041488Smckusick 		strcpy(lifd[1].dir_name, lifname(n2));
12141488Smckusick 		lifd[1].dir_type = DIR_TYPE;
12241488Smckusick 		lifd[1].dir_addr = 3 + lifd[0].dir_length;
12341488Smckusick 		lifd[1].dir_length = n;
12454073Shibler 		bcddate(from2, lifd[1].dir_toc);
12541488Smckusick 		lifd[1].dir_flag = DIR_FLAG;
12641488Smckusick 		lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
12741488Smckusick 		lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length;
12841488Smckusick 	}
12941488Smckusick 	/* output volume/directory header info */
13041488Smckusick 	lseek(to, 0 * SECTSIZE, 0);
13141488Smckusick 	write(to, &lifv, sizeof(lifv));
13241488Smckusick 	lseek(to, 2 * SECTSIZE, 0);
13341488Smckusick 	write(to, lifd, sizeof(lifd));
13441488Smckusick 	exit(0);
13541488Smckusick }
13641488Smckusick 
13741488Smckusick putfile(from, to)
13841488Smckusick {
13941488Smckusick 	register int n, tcnt, dcnt;
14041488Smckusick 
14141488Smckusick 	n = read(from, &ex, sizeof(ex));
14241488Smckusick 	if (n != sizeof(ex)) {
14341488Smckusick 		fprintf(stderr, "error reading file header\n");
14441488Smckusick 		exit(1);
14541488Smckusick 	}
14641488Smckusick 	if (ex.a_magic == OMAGIC) {
14741488Smckusick 		tcnt = ex.a_text;
14841488Smckusick 		dcnt = ex.a_data;
14941488Smckusick 	}
15041488Smckusick 	else if (ex.a_magic == NMAGIC) {
15141488Smckusick 		tcnt = (ex.a_text + PGOFSET) & ~PGOFSET;
15241488Smckusick 		dcnt = ex.a_data;
15341488Smckusick 	}
15441488Smckusick 	else {
15541488Smckusick 		fprintf(stderr, "bad magic number\n");
15641488Smckusick 		exit(1);
15741488Smckusick 	}
15841488Smckusick 	ld.address = lpflag ? loadpoint : ex.a_entry;
15941488Smckusick 	ld.count = tcnt + dcnt;
16041488Smckusick 	write(to, &ld, sizeof(ld));
16141488Smckusick 	while (tcnt) {
16241488Smckusick 		n = sizeof(buf);
16341488Smckusick 		if (n > tcnt)
16441488Smckusick 			n = tcnt;
16541488Smckusick 		n = read(from, buf, n);
16641488Smckusick 		if (n < 0) {
16741488Smckusick 			perror("read");
16841488Smckusick 			exit(1);
16941488Smckusick 		}
17041488Smckusick 		if (n == 0) {
17141488Smckusick 			fprintf(stderr, "short read\n");
17241488Smckusick 			exit(1);
17341488Smckusick 		}
17441488Smckusick 		if (write(to, buf, n) < 0) {
17541488Smckusick 			perror("write");
17641488Smckusick 			exit(1);
17741488Smckusick 		}
17841488Smckusick 		tcnt -= n;
17941488Smckusick 	}
18041488Smckusick 	while (dcnt) {
18141488Smckusick 		n = sizeof(buf);
18241488Smckusick 		if (n > dcnt)
18341488Smckusick 			n = dcnt;
18441488Smckusick 		n = read(from, buf, n);
18541488Smckusick 		if (n < 0) {
18641488Smckusick 			perror("read");
18741488Smckusick 			exit(1);
18841488Smckusick 		}
18941488Smckusick 		if (n == 0) {
19041488Smckusick 			fprintf(stderr, "short read\n");
19141488Smckusick 			exit(1);
19241488Smckusick 		}
19341488Smckusick 		if (write(to, buf, n) < 0) {
19441488Smckusick 			perror("write");
19541488Smckusick 			exit(1);
19641488Smckusick 		}
19741488Smckusick 		dcnt -= n;
19841488Smckusick 	}
19941488Smckusick }
20041488Smckusick 
20141488Smckusick usage()
20241488Smckusick {
20341488Smckusick 	fprintf(stderr,
20441488Smckusick 		"usage:  mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n");
20541488Smckusick 	exit(1);
20641488Smckusick }
20741488Smckusick 
20841488Smckusick char *
20941488Smckusick lifname(str)
21041488Smckusick  char *str;
21141488Smckusick {
21241488Smckusick 	static char lname[10] = "SYS_XXXXX";
21341488Smckusick 	register int i;
21441488Smckusick 
21541488Smckusick 	for (i = 4; i < 9; i++) {
21641488Smckusick 		if (islower(*str))
21741488Smckusick 			lname[i] = toupper(*str);
21841488Smckusick 		else if (isalnum(*str) || *str == '_')
21941488Smckusick 			lname[i] = *str;
22041488Smckusick 		else
22141488Smckusick 			break;
22241488Smckusick 		str++;
22341488Smckusick 	}
22441488Smckusick 	for ( ; i < 10; i++)
22541488Smckusick 		lname[i] = '\0';
22641488Smckusick 	return(lname);
22741488Smckusick }
22854073Shibler 
229*56510Sbostic #include <sys/stat.h>
230*56510Sbostic #include <time.h>	/* XXX */
23154073Shibler 
23254073Shibler bcddate(fd, toc)
23354073Shibler 	int fd;
23454073Shibler 	char *toc;
23554073Shibler {
23654073Shibler 	struct stat statb;
23754073Shibler 	struct tm *tm;
23854073Shibler 
23954073Shibler 	fstat(fd, &statb);
24054073Shibler 	tm = localtime(&statb.st_ctime);
24154073Shibler 	*toc = ((tm->tm_mon+1) / 10) << 4;
24254073Shibler 	*toc++ |= (tm->tm_mon+1) % 10;
24354073Shibler 	*toc = (tm->tm_mday / 10) << 4;
24454073Shibler 	*toc++ |= tm->tm_mday % 10;
24554073Shibler 	*toc = (tm->tm_year / 10) << 4;
24654073Shibler 	*toc++ |= tm->tm_year % 10;
24754073Shibler 	*toc = (tm->tm_hour / 10) << 4;
24854073Shibler 	*toc++ |= tm->tm_hour % 10;
24954073Shibler 	*toc = (tm->tm_min / 10) << 4;
25054073Shibler 	*toc++ |= tm->tm_min % 10;
25154073Shibler 	*toc = (tm->tm_sec / 10) << 4;
25254073Shibler 	*toc |= tm->tm_sec % 10;
25354073Shibler }
254