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