xref: /original-bsd/sys/hp300/stand/mkboot.c (revision b7cc7b86)
1 /*
2  * Copyright (c) 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)mkboot.c	7.2 (Berkeley) 12/16/90
8  */
9 
10 #ifndef lint
11 char copyright[] =
12 "@(#) Copyright (c) 1990 The Regents of the University of California.\n\
13  All rights reserved.\n";
14 #endif /* not lint */
15 
16 #ifndef lint
17 static char sccsid[] = "@(#)mkboot.c	7.2 (Berkeley) 12/16/90";
18 #endif /* not lint */
19 
20 #include "../include/param.h"
21 #include "volhdr.h"
22 #include <sys/exec.h>
23 #include <sys/file.h>
24 #include <stdio.h>
25 #include <ctype.h>
26 
27 int lpflag;
28 int loadpoint;
29 struct load ld;
30 struct lifvol lifv;
31 struct lifdir lifd[8];
32 struct exec ex;
33 char buf[10240];
34 
35 main(argc, argv)
36 	char **argv;
37 {
38 	int ac;
39 	char **av;
40 	int from1, from2, to;
41 	register int n;
42 	char *n1, *n2, *lifname();
43 
44 	ac = --argc;
45 	av = ++argv;
46 	if (ac == 0)
47 		usage();
48 	if (!strcmp(av[0], "-l")) {
49 		av++;
50 		ac--;
51 		if (ac == 0)
52 			usage();
53 		sscanf(av[0], "0x%x", &loadpoint);
54 		lpflag++;
55 		av++;
56 		ac--;
57 	}
58 	if (ac == 0)
59 		usage();
60 	from1 = open(av[0], O_RDONLY, 0);
61 	if (from1 < 0) {
62 		perror("open");
63 		exit(1);
64 	}
65 	n1 = av[0];
66 	av++;
67 	ac--;
68 	if (ac == 0)
69 		usage();
70 	if (ac == 2) {
71 		from2 = open(av[0], O_RDONLY, 0);
72 		if (from2 < 0) {
73 			perror("open");
74 			exit(1);
75 		}
76 		n2 = av[0];
77 		av++;
78 		ac--;
79 	} else
80 		from2 = -1;
81 	to = open(av[0], O_WRONLY | O_TRUNC | O_CREAT, 0644);
82 	if (to < 0) {
83 		perror("open");
84 		exit(1);
85 	}
86 	/* clear possibly unused directory entries */
87 	strncpy(lifd[1].dir_name, "          ", 10);
88 	lifd[1].dir_type = -1;
89 	lifd[1].dir_addr = 0;
90 	lifd[1].dir_length = 0;
91 	lifd[1].dir_flag = 0xFF;
92 	lifd[1].dir_exec = 0;
93 	lifd[7] = lifd[6] = lifd[5] = lifd[4] = lifd[3] = lifd[2] = lifd[1];
94 	/* record volume info */
95 	lifv.vol_id = VOL_ID;
96 	strncpy(lifv.vol_label, "BOOT43", 6);
97 	lifv.vol_addr = 2;
98 	lifv.vol_oct = VOL_OCT;
99 	lifv.vol_dirsize = 1;
100 	lifv.vol_version = 1;
101 	/* output bootfile one */
102 	lseek(to, 3 * SECTSIZE, 0);
103 	putfile(from1, to);
104 	n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE;
105 	strcpy(lifd[0].dir_name, lifname(n1));
106 	lifd[0].dir_type = DIR_TYPE;
107 	lifd[0].dir_addr = 3;
108 	lifd[0].dir_length = n;
109 	lifd[0].dir_flag = DIR_FLAG;
110 	lifd[0].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
111 	lifv.vol_length = lifd[0].dir_addr + lifd[0].dir_length;
112 	/* if there is an optional second boot program, output it */
113 	if (from2 >= 0) {
114 		lseek(to, (3 + n) * SECTSIZE, 0);
115 		putfile(from2, to);
116 		n = (ld.count + sizeof(ld) + (SECTSIZE - 1)) / SECTSIZE;
117 		strcpy(lifd[1].dir_name, lifname(n2));
118 		lifd[1].dir_type = DIR_TYPE;
119 		lifd[1].dir_addr = 3 + lifd[0].dir_length;
120 		lifd[1].dir_length = n;
121 		lifd[1].dir_flag = DIR_FLAG;
122 		lifd[1].dir_exec = lpflag? loadpoint + ex.a_entry : ex.a_entry;
123 		lifv.vol_length = lifd[1].dir_addr + lifd[1].dir_length;
124 	}
125 	/* output volume/directory header info */
126 	lseek(to, 0 * SECTSIZE, 0);
127 	write(to, &lifv, sizeof(lifv));
128 	lseek(to, 2 * SECTSIZE, 0);
129 	write(to, lifd, sizeof(lifd));
130 	exit(0);
131 }
132 
133 putfile(from, to)
134 {
135 	register int n, tcnt, dcnt;
136 
137 	n = read(from, &ex, sizeof(ex));
138 	if (n != sizeof(ex)) {
139 		fprintf(stderr, "error reading file header\n");
140 		exit(1);
141 	}
142 	if (ex.a_magic == OMAGIC) {
143 		tcnt = ex.a_text;
144 		dcnt = ex.a_data;
145 	}
146 	else if (ex.a_magic == NMAGIC) {
147 		tcnt = (ex.a_text + PGOFSET) & ~PGOFSET;
148 		dcnt = ex.a_data;
149 	}
150 	else {
151 		fprintf(stderr, "bad magic number\n");
152 		exit(1);
153 	}
154 	ld.address = lpflag ? loadpoint : ex.a_entry;
155 	ld.count = tcnt + dcnt;
156 	write(to, &ld, sizeof(ld));
157 	while (tcnt) {
158 		n = sizeof(buf);
159 		if (n > tcnt)
160 			n = tcnt;
161 		n = read(from, buf, n);
162 		if (n < 0) {
163 			perror("read");
164 			exit(1);
165 		}
166 		if (n == 0) {
167 			fprintf(stderr, "short read\n");
168 			exit(1);
169 		}
170 		if (write(to, buf, n) < 0) {
171 			perror("write");
172 			exit(1);
173 		}
174 		tcnt -= n;
175 	}
176 	while (dcnt) {
177 		n = sizeof(buf);
178 		if (n > dcnt)
179 			n = dcnt;
180 		n = read(from, buf, n);
181 		if (n < 0) {
182 			perror("read");
183 			exit(1);
184 		}
185 		if (n == 0) {
186 			fprintf(stderr, "short read\n");
187 			exit(1);
188 		}
189 		if (write(to, buf, n) < 0) {
190 			perror("write");
191 			exit(1);
192 		}
193 		dcnt -= n;
194 	}
195 }
196 
197 usage()
198 {
199 	fprintf(stderr,
200 		"usage:  mkboot [-l loadpoint] prog1 [ prog2 ] outfile\n");
201 	exit(1);
202 }
203 
204 char *
205 lifname(str)
206  char *str;
207 {
208 	static char lname[10] = "SYS_XXXXX";
209 	register int i;
210 
211 	for (i = 4; i < 9; i++) {
212 		if (islower(*str))
213 			lname[i] = toupper(*str);
214 		else if (isalnum(*str) || *str == '_')
215 			lname[i] = *str;
216 		else
217 			break;
218 		str++;
219 	}
220 	for ( ; i < 10; i++)
221 		lname[i] = '\0';
222 	return(lname);
223 }
224