rev |
line source |
pascal@17451
|
1 #ifdef __TURBOC__
|
pascal@17451
|
2 #include <io.h>
|
pascal@17451
|
3 #endif
|
pascal@14150
|
4 #include <sys/types.h>
|
pascal@14150
|
5 #include <fcntl.h>
|
pascal@14150
|
6 #include <stdio.h>
|
pascal@17451
|
7 #include <stdlib.h>
|
pascal@17451
|
8 #include <string.h>
|
pascal@14268
|
9 #ifdef WIN32
|
pascal@14268
|
10 #include <windows.h>
|
pascal@14268
|
11 #endif
|
pascal@18775
|
12 #ifdef __MSDOS__
|
pascal@18775
|
13 #define ftruncate(a,b)
|
pascal@18775
|
14 #endif
|
pascal@18775
|
15 #ifdef __MINGW32__
|
pascal@18775
|
16 #define ftruncate chsize
|
pascal@18775
|
17 #endif
|
pascal@18775
|
18 #if !defined(__MSDOS__) && !defined(WIN32)
|
pascal@18775
|
19 #define O_BINARY 0
|
pascal@18775
|
20 #endif
|
pascal@17591
|
21 typedef unsigned char uint8_t;
|
pascal@17591
|
22 typedef unsigned long uint32_t;
|
pascal@14150
|
23 #include "iso2exe.h"
|
pascal@14150
|
24
|
pascal@18780
|
25 static int fd, forced, uninstall;
|
pascal@18780
|
26 static unsigned status = 1;
|
pascal@18775
|
27 static char *append, *initrd;
|
pascal@17489
|
28 static char tazlitoinfo[0x8000U - BOOTISOSZ];
|
pascal@14264
|
29 #define buffer tazlitoinfo
|
pascal@14264
|
30 #define BUFFERSZ 2048
|
pascal@17451
|
31 #define WORD(n) * (unsigned short *) (n)
|
pascal@17451
|
32 #define LONG(n) * (unsigned long *) (n)
|
pascal@14150
|
33
|
pascal@14150
|
34 static void readsector(unsigned long sector)
|
pascal@14150
|
35 {
|
pascal@14264
|
36 if (lseek(fd, sector * BUFFERSZ, SEEK_SET) == -1 ||
|
pascal@14268
|
37 read(fd, buffer, BUFFERSZ) != BUFFERSZ) {
|
pascal@17451
|
38 puts(bootiso+READSECTORERR);
|
pascal@14268
|
39 exit(1);
|
pascal@14268
|
40 }
|
pascal@14150
|
41 }
|
pascal@14150
|
42
|
pascal@18775
|
43 static unsigned long getcustomsector(void)
|
pascal@18775
|
44 {
|
pascal@18775
|
45 readsector(16UL);
|
pascal@18775
|
46 return 16UL + LONG(buffer + 80);
|
pascal@18775
|
47 }
|
pascal@18775
|
48
|
pascal@17810
|
49 static int skipmd5 = 0;
|
pascal@17591
|
50 #define ALIGN1
|
pascal@17591
|
51
|
pascal@17591
|
52 typedef struct {
|
pascal@17591
|
53 uint32_t l;
|
pascal@17591
|
54 uint32_t h;
|
pascal@17591
|
55 } uint64_t;
|
pascal@17591
|
56 static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
|
pascal@17591
|
57 static uint64_t total64; /* must be directly before hash[] */
|
pascal@17591
|
58 static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */
|
pascal@17591
|
59
|
pascal@17591
|
60 //#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
|
pascal@17591
|
61 static uint32_t rotl32(uint32_t x, unsigned n)
|
pascal@17591
|
62 {
|
pascal@17591
|
63 return (x << n) | (x >> (32 - n));
|
pascal@17591
|
64 }
|
pascal@17591
|
65
|
pascal@17591
|
66 static void md5_process_block64(void);
|
pascal@17591
|
67
|
pascal@17591
|
68 /* Feed data through a temporary buffer.
|
pascal@17591
|
69 * The internal buffer remembers previous data until it has 64
|
pascal@17591
|
70 * bytes worth to pass on.
|
pascal@17591
|
71 */
|
pascal@17591
|
72 static void common64_hash(const void *buffer, size_t len)
|
pascal@17591
|
73 {
|
pascal@17591
|
74 unsigned bufpos = total64.l & 63;
|
pascal@17591
|
75
|
pascal@17591
|
76 total64.l += len; if (total64.l < len) total64.h++;
|
pascal@17591
|
77
|
pascal@17591
|
78 while (1) {
|
pascal@17591
|
79 unsigned remaining = 64 - bufpos;
|
pascal@17591
|
80 if (remaining > len)
|
pascal@17591
|
81 remaining = len;
|
pascal@17591
|
82 /* Copy data into aligned buffer */
|
pascal@17591
|
83 memcpy(wbuffer + bufpos, buffer, remaining);
|
pascal@17591
|
84 len -= remaining;
|
pascal@17591
|
85 buffer = (const char *)buffer + remaining;
|
pascal@17591
|
86 bufpos += remaining;
|
pascal@17591
|
87 /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
|
pascal@17591
|
88 bufpos -= 64;
|
pascal@17591
|
89 if (bufpos != 0)
|
pascal@17591
|
90 break;
|
pascal@17591
|
91 /* Buffer is filled up, process it */
|
pascal@17591
|
92 md5_process_block64();
|
pascal@17591
|
93 /*bufpos = 0; - already is */
|
pascal@17591
|
94 }
|
pascal@17591
|
95 }
|
pascal@17591
|
96
|
pascal@17591
|
97 /* Process the remaining bytes in the buffer */
|
pascal@17591
|
98 static void common64_end(void)
|
pascal@17591
|
99 {
|
pascal@17591
|
100 unsigned bufpos = total64.l & 63;
|
pascal@17591
|
101 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
|
pascal@17591
|
102 wbuffer[bufpos++] = 0x80;
|
pascal@17591
|
103
|
pascal@17591
|
104 /* This loop iterates either once or twice, no more, no less */
|
pascal@17591
|
105 while (1) {
|
pascal@17591
|
106 unsigned remaining = 64 - bufpos;
|
pascal@17591
|
107 memset(wbuffer + bufpos, 0, remaining);
|
pascal@17591
|
108 /* Do we have enough space for the length count? */
|
pascal@17591
|
109 if (remaining >= 8) {
|
pascal@17591
|
110 /* Store the 64-bit counter of bits in the buffer */
|
pascal@17591
|
111 //uint64_t t = total64 << 3;
|
pascal@17591
|
112 uint32_t *t = (uint32_t *) (&wbuffer[64 - 8]);
|
pascal@17591
|
113 /* wbuffer is suitably aligned for this */
|
pascal@17591
|
114 //*(uint64_t *) (&wbuffer[64 - 8]) = t;
|
pascal@17591
|
115 t[0] = total64.l << 3;
|
pascal@17591
|
116 t[1] = (total64.h << 3) | (total64.l >> 29);
|
pascal@17591
|
117 }
|
pascal@17591
|
118 md5_process_block64();
|
pascal@17591
|
119 if (remaining >= 8)
|
pascal@17591
|
120 break;
|
pascal@17591
|
121 bufpos = 0;
|
pascal@17591
|
122 }
|
pascal@17591
|
123 }
|
pascal@17591
|
124
|
pascal@17591
|
125 /* These are the four functions used in the four steps of the MD5 algorithm
|
pascal@17591
|
126 * and defined in the RFC 1321. The first function is a little bit optimized
|
pascal@17591
|
127 * (as found in Colin Plumbs public domain implementation).
|
pascal@17591
|
128 * #define FF(b, c, d) ((b & c) | (~b & d))
|
pascal@17591
|
129 */
|
pascal@17591
|
130 #undef FF
|
pascal@17591
|
131 #undef FG
|
pascal@17591
|
132 #undef FH
|
pascal@17591
|
133 #undef FI
|
pascal@17591
|
134 #define FF(b, c, d) (d ^ (b & (c ^ d)))
|
pascal@17591
|
135 #define FG(b, c, d) FF(d, b, c)
|
pascal@17591
|
136 #define FH(b, c, d) (b ^ c ^ d)
|
pascal@17591
|
137 #define FI(b, c, d) (c ^ (b | ~d))
|
pascal@17591
|
138
|
pascal@17591
|
139 /* Hash a single block, 64 bytes long and 4-byte aligned */
|
pascal@17591
|
140 static void md5_process_block64(void)
|
pascal@17591
|
141 {
|
pascal@17591
|
142 uint32_t *words = (void*) wbuffer;
|
pascal@17591
|
143 uint32_t A = hash[0];
|
pascal@17591
|
144 uint32_t B = hash[1];
|
pascal@17591
|
145 uint32_t C = hash[2];
|
pascal@17591
|
146 uint32_t D = hash[3];
|
pascal@17591
|
147
|
pascal@17591
|
148 const uint32_t *pc;
|
pascal@17591
|
149 const char *pp;
|
pascal@17591
|
150 const char *ps;
|
pascal@17591
|
151 int i;
|
pascal@17591
|
152 uint32_t temp;
|
pascal@17591
|
153
|
pascal@17591
|
154
|
pascal@17591
|
155 pc = C_array;
|
pascal@17591
|
156 pp = P_array;
|
pascal@17591
|
157 ps = S_array - 4;
|
pascal@17591
|
158
|
pascal@17591
|
159 for (i = 0; i < 64; i++) {
|
pascal@17591
|
160 if ((i & 0x0f) == 0)
|
pascal@17591
|
161 ps += 4;
|
pascal@17591
|
162 temp = A;
|
pascal@17591
|
163 switch (i >> 4) {
|
pascal@17591
|
164 case 0:
|
pascal@17591
|
165 temp += FF(B, C, D);
|
pascal@17591
|
166 break;
|
pascal@17591
|
167 case 1:
|
pascal@17591
|
168 temp += FG(B, C, D);
|
pascal@17591
|
169 break;
|
pascal@17591
|
170 case 2:
|
pascal@17591
|
171 temp += FH(B, C, D);
|
pascal@17591
|
172 break;
|
pascal@17591
|
173 case 3:
|
pascal@17591
|
174 temp += FI(B, C, D);
|
pascal@17591
|
175 }
|
pascal@17591
|
176 temp += words[(int) (*pp++)] + *pc++;
|
pascal@17591
|
177 temp = rotl32(temp, ps[i & 3]);
|
pascal@17591
|
178 temp += B;
|
pascal@17591
|
179 A = D;
|
pascal@17591
|
180 D = C;
|
pascal@17591
|
181 C = B;
|
pascal@17591
|
182 B = temp;
|
pascal@17591
|
183 }
|
pascal@17591
|
184 /* Add checksum to the starting values */
|
pascal@17591
|
185 hash[0] += A;
|
pascal@17591
|
186 hash[1] += B;
|
pascal@17591
|
187 hash[2] += C;
|
pascal@17591
|
188 hash[3] += D;
|
pascal@17591
|
189
|
pascal@17591
|
190 }
|
pascal@17591
|
191 #undef FF
|
pascal@17591
|
192 #undef FG
|
pascal@17591
|
193 #undef FH
|
pascal@17591
|
194 #undef FI
|
pascal@17591
|
195
|
pascal@17591
|
196 /* Initialize structure containing state of computation.
|
pascal@17591
|
197 * (RFC 1321, 3.3: Step 3)
|
pascal@17591
|
198 */
|
pascal@17591
|
199 static void md5_begin(void)
|
pascal@17591
|
200 {
|
pascal@17591
|
201 hash[0] = 0x67452301;
|
pascal@17591
|
202 hash[1] = 0xefcdab89;
|
pascal@17591
|
203 hash[2] = 0x98badcfe;
|
pascal@17591
|
204 hash[3] = 0x10325476;
|
pascal@17591
|
205 total64.l = total64.h = 0;
|
pascal@17591
|
206 }
|
pascal@17591
|
207
|
pascal@17591
|
208 /* Used also for sha1 and sha256 */
|
pascal@17591
|
209 #define md5_hash common64_hash
|
pascal@17591
|
210
|
pascal@17591
|
211 /* Process the remaining bytes in the buffer and put result from CTX
|
pascal@17591
|
212 * in first 16 bytes following RESBUF. The result is always in little
|
pascal@17591
|
213 * endian byte order, so that a byte-wise output yields to the wanted
|
pascal@17591
|
214 * ASCII representation of the message digest.
|
pascal@17591
|
215 */
|
pascal@17591
|
216 #define md5_end common64_end
|
pascal@17591
|
217
|
pascal@18775
|
218 static int writenhash(void *buffer, size_t len)
|
pascal@18775
|
219 {
|
pascal@18775
|
220 md5_hash(buffer, len);
|
pascal@18775
|
221 return write(fd, buffer, len);
|
pascal@18775
|
222 }
|
pascal@18775
|
223
|
pascal@17591
|
224 static void md5sum(void)
|
pascal@17591
|
225 {
|
pascal@17591
|
226 unsigned long sectors = 0;
|
pascal@17591
|
227 int count;
|
pascal@17591
|
228
|
pascal@17591
|
229 lseek(fd, 32768UL, SEEK_SET);
|
pascal@17591
|
230
|
pascal@17591
|
231 md5_begin();
|
pascal@17591
|
232 while ((count = read(fd, buffer, BUFFERSZ)) > 0) {
|
pascal@17591
|
233 if (sectors == 0)
|
pascal@17591
|
234 sectors = LONG(buffer + 80);
|
pascal@17591
|
235 md5_hash(buffer, count);
|
pascal@17591
|
236 if (--sectors == 0)
|
pascal@17591
|
237 break;
|
pascal@17591
|
238 }
|
pascal@17591
|
239
|
pascal@17591
|
240 if (count < 0)
|
pascal@17591
|
241 return;
|
pascal@17591
|
242
|
pascal@17591
|
243 md5_end();
|
pascal@17591
|
244
|
pascal@17591
|
245 lseek(fd, 32752UL, SEEK_SET);
|
pascal@17591
|
246 write(fd, hash, 16);
|
pascal@17591
|
247 memcpy(bootiso + BOOTISOSZ - 16, hash, 16);
|
pascal@17591
|
248 }
|
pascal@17591
|
249
|
pascal@17591
|
250 static unsigned chksum(unsigned start, unsigned stop)
|
pascal@17591
|
251 {
|
pascal@17591
|
252 unsigned i, n = 0;
|
pascal@17591
|
253
|
pascal@17591
|
254 lseek(fd, 0UL /* (unsigned long) (start / BUFFERSZ) */, SEEK_SET);
|
pascal@17591
|
255 while (1) {
|
pascal@17591
|
256 if (read(fd, buffer, BUFFERSZ) != BUFFERSZ)
|
pascal@17591
|
257 return 0;
|
pascal@17591
|
258 for (i = start % BUFFERSZ; i < BUFFERSZ; i += 2, start += 2) {
|
pascal@17591
|
259 if (start >= stop)
|
pascal@17591
|
260 return - n;
|
pascal@17591
|
261 n += WORD(buffer + i);
|
pascal@17591
|
262 }
|
pascal@17591
|
263 }
|
pascal@17591
|
264 }
|
pascal@17591
|
265
|
pascal@18779
|
266 static void clear_config(unsigned i)
|
pascal@18779
|
267 {
|
pascal@18779
|
268 for (;i % 512; i++) {
|
pascal@18779
|
269 /* clear custom config */
|
pascal@18779
|
270 write(fd, buffer + 2048, 2048);
|
pascal@18779
|
271 }
|
pascal@18779
|
272 }
|
pascal@18779
|
273
|
pascal@17451
|
274 static unsigned install(char *filename)
|
pascal@14150
|
275 {
|
pascal@14150
|
276 #define heads 64
|
pascal@14150
|
277 #define sectors 32
|
pascal@17489
|
278 #define partition (446+16)
|
pascal@17451
|
279 #define trksz (512UL * heads * sectors)
|
pascal@14150
|
280 unsigned long size, catalog, lba;
|
pascal@14261
|
281 int cylinders, i, j, isohybrid;
|
pascal@14150
|
282 unsigned n;
|
pascal@18775
|
283 #ifdef __MSDOS__
|
pascal@14268
|
284 for (bootiso = (char *) install;
|
pascal@17451
|
285 bootiso[0] != 'M' || bootiso[1] != 'Z' || bootiso[2] != '\xEB';
|
pascal@17451
|
286 bootiso++) if (bootiso < (char *) install) {
|
pascal@17451
|
287 bootiso = "No bootiso data";
|
pascal@17451
|
288 return 0;
|
pascal@17451
|
289 }
|
pascal@14150
|
290 #endif
|
pascal@14268
|
291 if (!filename)
|
pascal@17451
|
292 return USAGE;
|
pascal@14268
|
293 fd = open(filename,O_RDWR|O_BINARY);
|
pascal@14150
|
294 if (fd == -1)
|
pascal@17451
|
295 return OPENERR;
|
pascal@14150
|
296
|
pascal@17591
|
297 if (uninstall) {
|
pascal@17591
|
298 struct { char check[sizeof(tazlitoinfo) - BUFFERSZ - 1024]; };
|
pascal@17591
|
299 readsector(0UL);
|
pascal@18775
|
300 n = BUFFERSZ; /* fill with zeros */
|
pascal@17591
|
301 if (WORD(buffer) == 23117) {
|
pascal@18775
|
302 /* restore isolinux hybrid boot */
|
pascal@17810
|
303 readsector((unsigned long) buffer[417]);
|
pascal@18775
|
304 n = 0; /* fill with hybrid boot */
|
pascal@17591
|
305 }
|
pascal@17591
|
306 lseek(fd, 0UL, SEEK_SET);
|
pascal@17591
|
307 for (i = 0; i < 32; i++, n = BUFFERSZ) {
|
pascal@17591
|
308 write(fd, buffer + n, 1024);
|
pascal@17591
|
309 }
|
pascal@18775
|
310 i = getcustomsector();
|
pascal@18775
|
311 lseek(fd, i * 2048UL, SEEK_SET);
|
pascal@18779
|
312 clear_config(i);
|
pascal@18775
|
313 ftruncate(fd, i * 2048UL);
|
pascal@17591
|
314 close(fd);
|
pascal@17591
|
315 status = 0;
|
pascal@17591
|
316 return UNINSTALLMSG;
|
pascal@17591
|
317 }
|
pascal@17591
|
318
|
pascal@18780
|
319 do {
|
pascal@18780
|
320 readsector(0UL);
|
pascal@18780
|
321 status = ALREADYEXEERR;
|
pascal@18780
|
322 if (buffer[0] == 'M' && buffer[1] == 'Z')
|
pascal@18780
|
323 break;
|
pascal@18780
|
324
|
pascal@18780
|
325 /* Install hybridiso boot sector */
|
pascal@18780
|
326 readsector(17UL);
|
pascal@18780
|
327 status = ELTORITOERR;
|
pascal@18780
|
328 if (strncmp(buffer+7, bootiso+ELTORITOERR+ELTORITOOFS, 23))
|
pascal@18780
|
329 break;
|
pascal@18780
|
330 catalog = LONG(buffer + 71);
|
pascal@18780
|
331 readsector(catalog);
|
pascal@18780
|
332 status = CATALOGERR;
|
pascal@18780
|
333 if (LONG(buffer) != 1 || LONG(buffer + 30) != 0x88AA55UL)
|
pascal@18780
|
334 break;
|
pascal@18780
|
335 lba = LONG(buffer + 40);
|
pascal@18780
|
336 readsector(lba);
|
pascal@18780
|
337 status = HYBRIDERR;
|
pascal@18780
|
338 if (LONG(buffer + 64) != 1886961915UL)
|
pascal@18780
|
339 break;
|
pascal@18780
|
340 isohybrid = bootiso[417] * 512;
|
pascal@18780
|
341 LONG(bootiso + isohybrid + 432) = lba * 4;
|
pascal@18780
|
342 LONG(bootiso + isohybrid + 440) = rand();
|
pascal@18780
|
343 LONG(bootiso + isohybrid + partition) = 0x10080UL;
|
pascal@18780
|
344 WORD(bootiso + isohybrid + 510) = 0xAA55U;
|
pascal@18780
|
345 #if 0
|
pascal@18780
|
346 size = lseek(fd, 0UL, SEEK_END);
|
pascal@18780
|
347 size += 0x000FFFFFUL;
|
pascal@18780
|
348 size &= 0xFFF00000UL;
|
pascal@18780
|
349 #else
|
pascal@18780
|
350 for (size = 0x000FFFFFUL; /* 1M - 1 */
|
pascal@18780
|
351 read(fd, tazlitoinfo, 1024) == 1024;
|
pascal@18780
|
352 size += 1024);
|
pascal@18780
|
353 size &= 0xFFF00000UL; /* round */
|
pascal@18780
|
354 #endif
|
pascal@18780
|
355 cylinders = (size >> 20) - 1;
|
pascal@18780
|
356 bootiso[isohybrid + partition + 4] = 23; /* "Windows hidden IFS" */
|
pascal@18780
|
357 bootiso[isohybrid + partition + 5] = heads - 1;
|
pascal@18780
|
358 bootiso[isohybrid + partition + 6] = ((cylinders & 0x300) >> 2) + sectors;
|
pascal@18780
|
359 bootiso[isohybrid + partition + 7] = cylinders & 0xFF;
|
pascal@18780
|
360 LONG(bootiso + isohybrid + partition + 8) = 0;
|
pascal@18780
|
361 LONG(bootiso + isohybrid + partition + 12) = (size >> 9);
|
pascal@18780
|
362
|
pascal@18780
|
363 /* Copy the partition table */
|
pascal@18780
|
364 memcpy(bootiso + 0x1BE, bootiso + isohybrid + 0x1BE, 66);
|
pascal@18780
|
365 status = 0;
|
pascal@18780
|
366 } while (0);
|
pascal@18780
|
367
|
pascal@18780
|
368 if (forced == 0 && status)
|
pascal@18780
|
369 return status;
|
pascal@18780
|
370
|
pascal@18780
|
371 status = 1;
|
pascal@18775
|
372 if (append || initrd) {
|
pascal@18775
|
373 unsigned long pos = getcustomsector() * 2048UL;
|
pascal@18775
|
374 lseek(fd, pos, SEEK_SET);
|
pascal@18779
|
375 clear_config(pos);
|
pascal@18779
|
376 lseek(fd, pos, SEEK_SET);
|
pascal@18775
|
377 write(fd, "#!boot 00000000000000000000000000000000\n", 40);
|
pascal@18775
|
378 md5_begin();
|
pascal@18775
|
379 if (append) {
|
pascal@18775
|
380 writenhash("append=", 7);
|
pascal@18775
|
381 writenhash(append, strlen(append));
|
pascal@18775
|
382 writenhash("\n", 1);
|
pascal@18775
|
383 }
|
pascal@18775
|
384 if (initrd) {
|
pascal@18775
|
385 char number[16], *p;
|
pascal@18775
|
386 unsigned long end, x;
|
pascal@18775
|
387 int data = open(initrd,O_RDONLY|O_BINARY);
|
pascal@18775
|
388 if (data == -1)
|
pascal@18775
|
389 return OPENINITRDERR;
|
pascal@18775
|
390 for (end = 0;; end += i) {
|
pascal@18775
|
391 i = read(data, buffer, BUFFERSZ);
|
pascal@18775
|
392 if (i <= 0)
|
pascal@18775
|
393 break;
|
pascal@18775
|
394 }
|
pascal@18775
|
395 p = number + sizeof(number) -1;
|
pascal@18775
|
396 x = end; *p-- = '\n';
|
pascal@18775
|
397 do {
|
pascal@18775
|
398 *p-- = '0' + (x % 10);
|
pascal@18775
|
399 x /= 10;
|
pascal@18775
|
400 } while (x);
|
pascal@18775
|
401 if (*++p != '0') {
|
pascal@18775
|
402 writenhash("initrd:", 7);
|
pascal@18775
|
403 i = number - p + sizeof(number);
|
pascal@18775
|
404 writenhash(p, i);
|
pascal@18775
|
405 lseek(data, 0UL, SEEK_SET);
|
pascal@18775
|
406 do {
|
pascal@18775
|
407 i = read(data, buffer, BUFFERSZ);
|
pascal@18775
|
408 if (i <= 0)
|
pascal@18775
|
409 break;
|
pascal@18775
|
410 if (i > end)
|
pascal@18775
|
411 i = end;
|
pascal@18775
|
412 writenhash(buffer, i);
|
pascal@18775
|
413 end -= i;
|
pascal@18775
|
414 } while (end != 0);
|
pascal@18775
|
415 }
|
pascal@18775
|
416 close(data);
|
pascal@18775
|
417 }
|
pascal@18775
|
418 md5_end();
|
pascal@18775
|
419 {
|
pascal@18779
|
420 static char h[] = "0123456789abcdef";
|
pascal@18775
|
421 char string[32], *s = string + 30;
|
pascal@18775
|
422 unsigned char *p = (void *) hash;
|
pascal@18775
|
423
|
pascal@18775
|
424 lseek(fd, 7 + pos, SEEK_SET);
|
pascal@18775
|
425 for (p += 15; s >= string; p--, s -= 2) {
|
pascal@18775
|
426 s[1] = h[ *p & 15 ];
|
pascal@18775
|
427 s[0] = h[ *p >> 4 ];
|
pascal@18775
|
428 }
|
pascal@18775
|
429 write(fd, string, 32);
|
pascal@18775
|
430 }
|
pascal@18775
|
431 }
|
pascal@18775
|
432
|
pascal@17451
|
433 /* Install iso2exe boot sector */
|
pascal@17810
|
434 LONG(bootiso + 440) = time(NULL);
|
pascal@14150
|
435
|
pascal@17451
|
436 /* read tazlito flavor data */
|
pascal@14261
|
437 lseek(fd, 1024UL, SEEK_SET);
|
pascal@14261
|
438 read(fd, tazlitoinfo, sizeof(tazlitoinfo));
|
pascal@14261
|
439
|
pascal@17451
|
440 /* Update iso image */
|
pascal@17810
|
441 n = (bootiso[417] + 1) * 512;
|
pascal@14151
|
442 lseek(fd, 0UL, SEEK_SET);
|
pascal@17451
|
443 write(fd, bootiso, n); /* EXE/PE + isohybrid mbr */
|
pascal@17489
|
444 write(fd, tazlitoinfo, sizeof(tazlitoinfo));
|
pascal@17451
|
445 write(fd, bootiso + n, BOOTISOSZ - n); /* COM + rootfs + EXE/DOS */
|
pascal@14150
|
446
|
pascal@17810
|
447 /* Compute the boot checksums */
|
pascal@17810
|
448 if (!skipmd5) {
|
pascal@17591
|
449 puts(bootiso + MD5MSG);
|
pascal@17591
|
450 md5sum();
|
pascal@17591
|
451 lseek(fd, 0UL, SEEK_SET);
|
pascal@17591
|
452 write(fd, bootiso, 512);
|
pascal@17810
|
453 n = WORD(bootiso + 2) - 512*(WORD(bootiso + 4) - 1);
|
pascal@17810
|
454 WORD(bootiso + 18) = chksum(0, (unsigned short) n) - 1;
|
pascal@17591
|
455 }
|
pascal@17810
|
456 lseek(fd, 0UL, SEEK_SET);
|
pascal@17810
|
457 write(fd, bootiso, 512);
|
pascal@14150
|
458 close(fd);
|
pascal@14268
|
459 status = 0;
|
pascal@17451
|
460 return SUCCESSMSG;
|
pascal@14150
|
461 }
|
pascal@14268
|
462
|
pascal@14268
|
463 int main(int argc, char *argv[])
|
pascal@14268
|
464 {
|
pascal@17591
|
465 int i;
|
pascal@18775
|
466 char *s;
|
pascal@18775
|
467
|
pascal@18775
|
468 while (argc > 2) {
|
pascal@18775
|
469 s = argv[1];
|
pascal@18775
|
470 if (*s != '-') break;
|
pascal@18775
|
471 while (*s == '-') s++;
|
pascal@18775
|
472 switch (*s | 0x20) {
|
pascal@18775
|
473 case 'a' : append=argv[2]; break;
|
pascal@18775
|
474 case 'i' : initrd=argv[2]; break;
|
pascal@18775
|
475 }
|
pascal@18775
|
476 argv += 2;
|
pascal@18775
|
477 argc -= 2;
|
pascal@18775
|
478 }
|
pascal@17591
|
479 for (i = 2; i < argc; i++) {
|
pascal@17591
|
480 char *s = argv[i];
|
pascal@17591
|
481 while ((unsigned)(*s - '-') <= ('/' - '-')) s++;
|
pascal@17591
|
482 switch (*s | 0x20) {
|
pascal@17591
|
483 case 'f' : forced++; break;
|
pascal@17810
|
484 case 'q' : skipmd5++; break;
|
pascal@17591
|
485 case 'u' : uninstall++; break;
|
pascal@17591
|
486 }
|
pascal@17591
|
487 }
|
pascal@17451
|
488 puts(bootiso + install(argv[1]));
|
pascal@16055
|
489 if (status > 1)
|
pascal@17451
|
490 puts(bootiso + FORCEMSG);
|
pascal@14268
|
491 #ifdef WIN32
|
pascal@14268
|
492 Sleep(2000);
|
pascal@14268
|
493 #endif
|
pascal@14268
|
494 return status;
|
pascal@14268
|
495 }
|