Commit | Line | Data |
---|---|---|
a8fd2d0d KM |
1 | /* |
2 | * Copyright (c) 1990 The Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * %sccs.include.redist.c% | |
6 | * | |
b28b3a13 | 7 | * @(#)mkboot.c 7.2 (Berkeley) %G% |
a8fd2d0d KM |
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 | |
b28b3a13 | 17 | static char sccsid[] = "@(#)mkboot.c 7.2 (Berkeley) %G%"; |
a8fd2d0d KM |
18 | #endif /* not lint */ |
19 | ||
b28b3a13 | 20 | #include "../include/param.h" |
a8fd2d0d KM |
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 | } |