wok annotate syslinux/stuff/iso2exe/iso2exe.c @ rev 19324

syslinux: adjust custom conf location
author Pascal Bellard <pascal.bellard@slitaz.org>
date Thu Jul 14 10:28:07 2016 +0200 (2016-07-14)
parents 3432c28d8372
children d33c3c211ef8
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@18783 13 int ftruncate(int fd, long newsize)
pascal@18783 14 {
pascal@18783 15 if (lseek(fd, newsize, SEEK_SET) != -1L)
pascal@18783 16 return write(fd, NULL, 0);
pascal@18783 17 return -1;
pascal@18783 18 }
pascal@18775 19 #endif
pascal@18775 20 #ifdef __MINGW32__
pascal@18775 21 #define ftruncate chsize
pascal@18775 22 #endif
pascal@18775 23 #if !defined(__MSDOS__) && !defined(WIN32)
pascal@18775 24 #define O_BINARY 0
pascal@18775 25 #endif
pascal@17591 26 typedef unsigned char uint8_t;
pascal@17591 27 typedef unsigned long uint32_t;
pascal@14150 28 #include "iso2exe.h"
pascal@14150 29
pascal@18780 30 static int fd, forced, uninstall;
pascal@18780 31 static unsigned status = 1;
pascal@18775 32 static char *append, *initrd;
pascal@17489 33 static char tazlitoinfo[0x8000U - BOOTISOSZ];
pascal@14264 34 #define buffer tazlitoinfo
pascal@14264 35 #define BUFFERSZ 2048
pascal@18897 36 #define BYTE(n) * (unsigned char *) (n)
pascal@17451 37 #define WORD(n) * (unsigned short *) (n)
pascal@17451 38 #define LONG(n) * (unsigned long *) (n)
pascal@14150 39
pascal@14150 40 static void readsector(unsigned long sector)
pascal@14150 41 {
pascal@14264 42 if (lseek(fd, sector * BUFFERSZ, SEEK_SET) == -1 ||
pascal@14268 43 read(fd, buffer, BUFFERSZ) != BUFFERSZ) {
pascal@17451 44 puts(bootiso+READSECTORERR);
pascal@14268 45 exit(1);
pascal@14268 46 }
pascal@14150 47 }
pascal@14150 48
pascal@18775 49 static unsigned long getcustomsector(void)
pascal@18775 50 {
pascal@18775 51 readsector(16UL);
pascal@19324 52 return LONG(buffer + 80);
pascal@18775 53 }
pascal@18775 54
pascal@17810 55 static int skipmd5 = 0;
pascal@17591 56 #define ALIGN1
pascal@17591 57
pascal@17591 58 typedef struct {
pascal@17591 59 uint32_t l;
pascal@17591 60 uint32_t h;
pascal@17591 61 } uint64_t;
pascal@17591 62 static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
pascal@17591 63 static uint64_t total64; /* must be directly before hash[] */
pascal@17591 64 static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */
pascal@17591 65
pascal@18909 66 /* #define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) */
pascal@17591 67 static uint32_t rotl32(uint32_t x, unsigned n)
pascal@17591 68 {
pascal@17591 69 return (x << n) | (x >> (32 - n));
pascal@17591 70 }
pascal@17591 71
pascal@17591 72 static void md5_process_block64(void);
pascal@17591 73
pascal@17591 74 /* Feed data through a temporary buffer.
pascal@17591 75 * The internal buffer remembers previous data until it has 64
pascal@17591 76 * bytes worth to pass on.
pascal@17591 77 */
pascal@17591 78 static void common64_hash(const void *buffer, size_t len)
pascal@17591 79 {
pascal@17591 80 unsigned bufpos = total64.l & 63;
pascal@17591 81
pascal@17591 82 total64.l += len; if (total64.l < len) total64.h++;
pascal@17591 83
pascal@17591 84 while (1) {
pascal@17591 85 unsigned remaining = 64 - bufpos;
pascal@17591 86 if (remaining > len)
pascal@17591 87 remaining = len;
pascal@17591 88 /* Copy data into aligned buffer */
pascal@17591 89 memcpy(wbuffer + bufpos, buffer, remaining);
pascal@17591 90 len -= remaining;
pascal@17591 91 buffer = (const char *)buffer + remaining;
pascal@17591 92 bufpos += remaining;
pascal@17591 93 /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
pascal@17591 94 bufpos -= 64;
pascal@17591 95 if (bufpos != 0)
pascal@17591 96 break;
pascal@17591 97 /* Buffer is filled up, process it */
pascal@17591 98 md5_process_block64();
pascal@17591 99 /*bufpos = 0; - already is */
pascal@17591 100 }
pascal@17591 101 }
pascal@17591 102
pascal@17591 103 /* Process the remaining bytes in the buffer */
pascal@17591 104 static void common64_end(void)
pascal@17591 105 {
pascal@17591 106 unsigned bufpos = total64.l & 63;
pascal@17591 107 /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
pascal@17591 108 wbuffer[bufpos++] = 0x80;
pascal@17591 109
pascal@17591 110 /* This loop iterates either once or twice, no more, no less */
pascal@17591 111 while (1) {
pascal@17591 112 unsigned remaining = 64 - bufpos;
pascal@17591 113 memset(wbuffer + bufpos, 0, remaining);
pascal@17591 114 /* Do we have enough space for the length count? */
pascal@17591 115 if (remaining >= 8) {
pascal@17591 116 /* Store the 64-bit counter of bits in the buffer */
pascal@18909 117 /* uint64_t t = total64 << 3; */
pascal@17591 118 uint32_t *t = (uint32_t *) (&wbuffer[64 - 8]);
pascal@17591 119 /* wbuffer is suitably aligned for this */
pascal@18909 120 /* *(uint64_t *) (&wbuffer[64 - 8]) = t; */
pascal@17591 121 t[0] = total64.l << 3;
pascal@17591 122 t[1] = (total64.h << 3) | (total64.l >> 29);
pascal@17591 123 }
pascal@17591 124 md5_process_block64();
pascal@17591 125 if (remaining >= 8)
pascal@17591 126 break;
pascal@17591 127 bufpos = 0;
pascal@17591 128 }
pascal@17591 129 }
pascal@17591 130
pascal@17591 131 /* These are the four functions used in the four steps of the MD5 algorithm
pascal@17591 132 * and defined in the RFC 1321. The first function is a little bit optimized
pascal@17591 133 * (as found in Colin Plumbs public domain implementation).
pascal@17591 134 * #define FF(b, c, d) ((b & c) | (~b & d))
pascal@17591 135 */
pascal@17591 136 #undef FF
pascal@17591 137 #undef FG
pascal@17591 138 #undef FH
pascal@17591 139 #undef FI
pascal@17591 140 #define FF(b, c, d) (d ^ (b & (c ^ d)))
pascal@17591 141 #define FG(b, c, d) FF(d, b, c)
pascal@17591 142 #define FH(b, c, d) (b ^ c ^ d)
pascal@17591 143 #define FI(b, c, d) (c ^ (b | ~d))
pascal@17591 144
pascal@17591 145 /* Hash a single block, 64 bytes long and 4-byte aligned */
pascal@17591 146 static void md5_process_block64(void)
pascal@17591 147 {
pascal@17591 148 uint32_t *words = (void*) wbuffer;
pascal@17591 149 uint32_t A = hash[0];
pascal@17591 150 uint32_t B = hash[1];
pascal@17591 151 uint32_t C = hash[2];
pascal@17591 152 uint32_t D = hash[3];
pascal@17591 153
pascal@17591 154 const uint32_t *pc;
pascal@17591 155 const char *pp;
pascal@17591 156 const char *ps;
pascal@17591 157 int i;
pascal@17591 158 uint32_t temp;
pascal@17591 159
pascal@17591 160
pascal@17591 161 pc = C_array;
pascal@17591 162 pp = P_array;
pascal@17591 163 ps = S_array - 4;
pascal@17591 164
pascal@17591 165 for (i = 0; i < 64; i++) {
pascal@17591 166 if ((i & 0x0f) == 0)
pascal@17591 167 ps += 4;
pascal@17591 168 temp = A;
pascal@17591 169 switch (i >> 4) {
pascal@17591 170 case 0:
pascal@17591 171 temp += FF(B, C, D);
pascal@17591 172 break;
pascal@17591 173 case 1:
pascal@17591 174 temp += FG(B, C, D);
pascal@17591 175 break;
pascal@17591 176 case 2:
pascal@17591 177 temp += FH(B, C, D);
pascal@17591 178 break;
pascal@17591 179 case 3:
pascal@17591 180 temp += FI(B, C, D);
pascal@17591 181 }
pascal@17591 182 temp += words[(int) (*pp++)] + *pc++;
pascal@17591 183 temp = rotl32(temp, ps[i & 3]);
pascal@17591 184 temp += B;
pascal@17591 185 A = D;
pascal@17591 186 D = C;
pascal@17591 187 C = B;
pascal@17591 188 B = temp;
pascal@17591 189 }
pascal@17591 190 /* Add checksum to the starting values */
pascal@17591 191 hash[0] += A;
pascal@17591 192 hash[1] += B;
pascal@17591 193 hash[2] += C;
pascal@17591 194 hash[3] += D;
pascal@17591 195
pascal@17591 196 }
pascal@17591 197 #undef FF
pascal@17591 198 #undef FG
pascal@17591 199 #undef FH
pascal@17591 200 #undef FI
pascal@17591 201
pascal@17591 202 /* Initialize structure containing state of computation.
pascal@17591 203 * (RFC 1321, 3.3: Step 3)
pascal@17591 204 */
pascal@17591 205 static void md5_begin(void)
pascal@17591 206 {
pascal@17591 207 hash[0] = 0x67452301;
pascal@17591 208 hash[1] = 0xefcdab89;
pascal@17591 209 hash[2] = 0x98badcfe;
pascal@17591 210 hash[3] = 0x10325476;
pascal@17591 211 total64.l = total64.h = 0;
pascal@17591 212 }
pascal@17591 213
pascal@17591 214 /* Used also for sha1 and sha256 */
pascal@17591 215 #define md5_hash common64_hash
pascal@17591 216
pascal@17591 217 /* Process the remaining bytes in the buffer and put result from CTX
pascal@17591 218 * in first 16 bytes following RESBUF. The result is always in little
pascal@17591 219 * endian byte order, so that a byte-wise output yields to the wanted
pascal@17591 220 * ASCII representation of the message digest.
pascal@17591 221 */
pascal@17591 222 #define md5_end common64_end
pascal@17591 223
pascal@18775 224 static int writenhash(void *buffer, size_t len)
pascal@18775 225 {
pascal@18775 226 md5_hash(buffer, len);
pascal@18775 227 return write(fd, buffer, len);
pascal@18775 228 }
pascal@18775 229
pascal@17591 230 static void md5sum(void)
pascal@17591 231 {
pascal@17591 232 unsigned long sectors = 0;
pascal@17591 233 int count;
pascal@17591 234
pascal@17591 235 lseek(fd, 32768UL, SEEK_SET);
pascal@17591 236
pascal@17591 237 md5_begin();
pascal@17591 238 while ((count = read(fd, buffer, BUFFERSZ)) > 0) {
pascal@17591 239 if (sectors == 0)
pascal@19323 240 sectors = LONG(buffer + 80) - 16UL;
pascal@17591 241 md5_hash(buffer, count);
pascal@17591 242 if (--sectors == 0)
pascal@17591 243 break;
pascal@17591 244 }
pascal@17591 245
pascal@17591 246 if (count < 0)
pascal@17591 247 return;
pascal@17591 248
pascal@17591 249 md5_end();
pascal@17591 250
pascal@17591 251 lseek(fd, 32752UL, SEEK_SET);
pascal@17591 252 write(fd, hash, 16);
pascal@17591 253 memcpy(bootiso + BOOTISOSZ - 16, hash, 16);
pascal@17591 254 }
pascal@17591 255
pascal@17591 256 static unsigned chksum(unsigned start, unsigned stop)
pascal@17591 257 {
pascal@17591 258 unsigned i, n = 0;
pascal@17591 259
pascal@17591 260 lseek(fd, 0UL /* (unsigned long) (start / BUFFERSZ) */, SEEK_SET);
pascal@17591 261 while (1) {
pascal@17591 262 if (read(fd, buffer, BUFFERSZ) != BUFFERSZ)
pascal@17591 263 return 0;
pascal@17591 264 for (i = start % BUFFERSZ; i < BUFFERSZ; i += 2, start += 2) {
pascal@17591 265 if (start >= stop)
pascal@17591 266 return - n;
pascal@17591 267 n += WORD(buffer + i);
pascal@17591 268 }
pascal@17591 269 }
pascal@17591 270 }
pascal@17591 271
pascal@18783 272 static unsigned clear_config(unsigned i)
pascal@18779 273 {
pascal@18779 274 for (;i % 512; i++) {
pascal@18779 275 /* clear custom config */
pascal@18779 276 write(fd, buffer + 2048, 2048);
pascal@18779 277 }
pascal@18783 278 return i;
pascal@18779 279 }
pascal@18779 280
pascal@17451 281 static unsigned install(char *filename)
pascal@14150 282 {
pascal@14150 283 #define heads 64
pascal@14150 284 #define sectors 32
pascal@17489 285 #define partition (446+16)
pascal@17451 286 #define trksz (512UL * heads * sectors)
pascal@14150 287 unsigned long size, catalog, lba;
pascal@14261 288 int cylinders, i, j, isohybrid;
pascal@14150 289 unsigned n;
pascal@14268 290 if (!filename)
pascal@17451 291 return USAGE;
pascal@14268 292 fd = open(filename,O_RDWR|O_BINARY);
pascal@14150 293 if (fd == -1)
pascal@17451 294 return OPENERR;
pascal@14150 295
pascal@17591 296 if (uninstall) {
pascal@17591 297 struct { char check[sizeof(tazlitoinfo) - BUFFERSZ - 1024]; };
pascal@17591 298 readsector(0UL);
pascal@18775 299 n = BUFFERSZ; /* fill with zeros */
pascal@17591 300 if (WORD(buffer) == 23117) {
pascal@18775 301 /* restore isolinux hybrid boot */
pascal@17810 302 readsector((unsigned long) buffer[417]);
pascal@18775 303 n = 0; /* fill with hybrid boot */
pascal@17591 304 }
pascal@17591 305 lseek(fd, 0UL, SEEK_SET);
pascal@17591 306 for (i = 0; i < 32; i++, n = BUFFERSZ) {
pascal@18789 307 write(fd, buffer + n, BUFFERSZ);
pascal@17591 308 }
pascal@18909 309 lseek(fd, getcustomsector() << 11, SEEK_SET);
pascal@18783 310 i = clear_config(i);
pascal@18775 311 ftruncate(fd, i * 2048UL);
pascal@17591 312 close(fd);
pascal@17591 313 status = 0;
pascal@17591 314 return UNINSTALLMSG;
pascal@17591 315 }
pascal@17591 316
pascal@18781 317 readsector(0UL);
pascal@18781 318 if (buffer[0] == 'M' && buffer[1] == 'Z') {
pascal@18781 319 if (forced == 0)
pascal@18781 320 return ALREADYEXEERR;
pascal@18781 321 n = (buffer[417] + 1) * 512;
pascal@18781 322 i = 0x8000 - 1024;
pascal@18781 323 if (i > sizeof(tazlitoinfo))
pascal@18781 324 i = sizeof(tazlitoinfo);
pascal@18781 325 if (lseek(fd, n, SEEK_SET) == -1 ||
pascal@18781 326 read(fd, tazlitoinfo, sizeof(tazlitoinfo)) != sizeof(tazlitoinfo) ||
pascal@18781 327 lseek(fd, 1024UL, SEEK_SET) == -1 ||
pascal@18781 328 write(fd, tazlitoinfo, i) != i) {
pascal@18781 329 puts(bootiso+READSECTORERR);
pascal@18781 330 exit(1);
pascal@18781 331 }
pascal@18781 332 }
pascal@18781 333
pascal@18780 334 do {
pascal@18780 335 /* Install hybridiso boot sector */
pascal@18780 336 readsector(17UL);
pascal@18780 337 status = ELTORITOERR;
pascal@18780 338 if (strncmp(buffer+7, bootiso+ELTORITOERR+ELTORITOOFS, 23))
pascal@18780 339 break;
pascal@18780 340 catalog = LONG(buffer + 71);
pascal@18780 341 readsector(catalog);
pascal@18780 342 status = CATALOGERR;
pascal@18780 343 if (LONG(buffer) != 1 || LONG(buffer + 30) != 0x88AA55UL)
pascal@18780 344 break;
pascal@18780 345 lba = LONG(buffer + 40);
pascal@18780 346 readsector(lba);
pascal@18780 347 status = HYBRIDERR;
pascal@18780 348 if (LONG(buffer + 64) != 1886961915UL)
pascal@18780 349 break;
pascal@18780 350 isohybrid = bootiso[417] * 512;
pascal@18780 351 LONG(bootiso + isohybrid + 432) = lba * 4;
pascal@18780 352 LONG(bootiso + isohybrid + 440) = rand();
pascal@18780 353 LONG(bootiso + isohybrid + partition) = 0x10080UL;
pascal@18780 354 WORD(bootiso + isohybrid + 510) = 0xAA55U;
pascal@18780 355 #if 0
pascal@18780 356 size = lseek(fd, 0UL, SEEK_END);
pascal@18780 357 size += 0x000FFFFFUL;
pascal@18780 358 size &= 0xFFF00000UL;
pascal@18780 359 #else
pascal@18780 360 for (size = 0x000FFFFFUL; /* 1M - 1 */
pascal@18780 361 read(fd, tazlitoinfo, 1024) == 1024;
pascal@18780 362 size += 1024);
pascal@18780 363 size &= 0xFFF00000UL; /* round */
pascal@18780 364 #endif
pascal@18780 365 cylinders = (size >> 20) - 1;
pascal@18780 366 bootiso[isohybrid + partition + 4] = 23; /* "Windows hidden IFS" */
pascal@18780 367 bootiso[isohybrid + partition + 5] = heads - 1;
pascal@18780 368 bootiso[isohybrid + partition + 6] = ((cylinders & 0x300) >> 2) + sectors;
pascal@18780 369 bootiso[isohybrid + partition + 7] = cylinders & 0xFF;
pascal@18780 370 LONG(bootiso + isohybrid + partition + 8) = 0;
pascal@18780 371 LONG(bootiso + isohybrid + partition + 12) = (size >> 9);
pascal@18780 372
pascal@18780 373 /* Copy the partition table */
pascal@18780 374 memcpy(bootiso + 0x1BE, bootiso + isohybrid + 0x1BE, 66);
pascal@18780 375 status = 0;
pascal@18780 376 } while (0);
pascal@18780 377
pascal@18780 378 if (forced == 0 && status)
pascal@18780 379 return status;
pascal@18780 380
pascal@18780 381 status = 1;
pascal@18775 382 if (append || initrd) {
pascal@18775 383 unsigned long pos = getcustomsector() * 2048UL;
pascal@18775 384 lseek(fd, pos, SEEK_SET);
pascal@18779 385 clear_config(pos);
pascal@18779 386 lseek(fd, pos, SEEK_SET);
pascal@18909 387 write(fd, bootiso+CUSTOM_HEADER, 40);
pascal@18789 388 n = pos + 40;
pascal@18775 389 md5_begin();
pascal@18775 390 if (append) {
pascal@18789 391 i = strlen(append);
pascal@18909 392 writenhash(bootiso+CMDLINE_TAG, 7);
pascal@18789 393 writenhash(append, i);
pascal@18775 394 writenhash("\n", 1);
pascal@18789 395 n += i + 8;
pascal@18775 396 }
pascal@18775 397 if (initrd) {
pascal@18775 398 char number[16], *p;
pascal@18775 399 unsigned long end, x;
pascal@18775 400 int data = open(initrd,O_RDONLY|O_BINARY);
pascal@18775 401 if (data == -1)
pascal@18775 402 return OPENINITRDERR;
pascal@18775 403 for (end = 0;; end += i) {
pascal@18775 404 i = read(data, buffer, BUFFERSZ);
pascal@18775 405 if (i <= 0)
pascal@18775 406 break;
pascal@18775 407 }
pascal@18775 408 p = number + sizeof(number) -1;
pascal@18775 409 x = end; *p-- = '\n';
pascal@18775 410 do {
pascal@18775 411 *p-- = '0' + (x % 10);
pascal@18775 412 x /= 10;
pascal@18775 413 } while (x);
pascal@18775 414 if (*++p != '0') {
pascal@18909 415 writenhash(bootiso+INITRD_TAG, 7);
pascal@18775 416 i = number - p + sizeof(number);
pascal@18775 417 writenhash(p, i);
pascal@18789 418 n += i + 7;
pascal@18775 419 lseek(data, 0UL, SEEK_SET);
pascal@18775 420 do {
pascal@18775 421 i = read(data, buffer, BUFFERSZ);
pascal@18775 422 if (i <= 0)
pascal@18775 423 break;
pascal@18775 424 if (i > end)
pascal@18775 425 i = end;
pascal@18775 426 writenhash(buffer, i);
pascal@18789 427 n += i;
pascal@18775 428 end -= i;
pascal@18775 429 } while (end != 0);
pascal@18775 430 }
pascal@18775 431 close(data);
pascal@18775 432 }
pascal@18789 433 while (n & 0x000FFFFFUL) {
pascal@18789 434 unsigned long i = 0x100000UL - (n & 0x000FFFFFUL);
pascal@18789 435 if (i > BUFFERSZ)
pascal@18789 436 i = BUFFERSZ;
pascal@18789 437 i = write(fd, buffer + BUFFERSZ, i);
pascal@18789 438 if (i <= 0)
pascal@18789 439 break;
pascal@18789 440 n += i;
pascal@18789 441 }
pascal@18789 442 ftruncate(fd, n);
pascal@18775 443 md5_end();
pascal@18775 444 {
pascal@18779 445 static char h[] = "0123456789abcdef";
pascal@18775 446 char string[32], *s = string + 30;
pascal@18775 447 unsigned char *p = (void *) hash;
pascal@18775 448
pascal@18775 449 lseek(fd, 7 + pos, SEEK_SET);
pascal@18775 450 for (p += 15; s >= string; p--, s -= 2) {
pascal@18775 451 s[1] = h[ *p & 15 ];
pascal@18775 452 s[0] = h[ *p >> 4 ];
pascal@18775 453 }
pascal@18775 454 write(fd, string, 32);
pascal@18775 455 }
pascal@19027 456
pascal@19027 457 /* Update partition size */
pascal@19027 458 n = 1+((n - 1) >> 20);
pascal@19027 459 BYTE(bootiso + partition + 7) =
pascal@19027 460 BYTE(bootiso + isohybrid + partition + 7) = n -1;
pascal@19027 461 LONG(bootiso + partition + 12) =
pascal@19027 462 LONG(bootiso + isohybrid + partition + 12) = n * 2048;
pascal@18775 463 }
pascal@18775 464
pascal@17451 465 /* Install iso2exe boot sector */
pascal@17810 466 LONG(bootiso + 440) = time(NULL);
pascal@14150 467
pascal@17451 468 /* read tazlito flavor data */
pascal@14261 469 lseek(fd, 1024UL, SEEK_SET);
pascal@14261 470 read(fd, tazlitoinfo, sizeof(tazlitoinfo));
pascal@14261 471
pascal@17451 472 /* Update iso image */
pascal@17810 473 n = (bootiso[417] + 1) * 512;
pascal@14151 474 lseek(fd, 0UL, SEEK_SET);
pascal@17451 475 write(fd, bootiso, n); /* EXE/PE + isohybrid mbr */
pascal@17489 476 write(fd, tazlitoinfo, sizeof(tazlitoinfo));
pascal@17451 477 write(fd, bootiso + n, BOOTISOSZ - n); /* COM + rootfs + EXE/DOS */
pascal@14150 478
pascal@17810 479 /* Compute the boot checksums */
pascal@17810 480 if (!skipmd5) {
pascal@17591 481 puts(bootiso + MD5MSG);
pascal@17591 482 md5sum();
pascal@17591 483 lseek(fd, 0UL, SEEK_SET);
pascal@17591 484 write(fd, bootiso, 512);
pascal@17810 485 n = WORD(bootiso + 2) - 512*(WORD(bootiso + 4) - 1);
pascal@17810 486 WORD(bootiso + 18) = chksum(0, (unsigned short) n) - 1;
pascal@17591 487 }
pascal@17810 488 lseek(fd, 0UL, SEEK_SET);
pascal@17810 489 write(fd, bootiso, 512);
pascal@14150 490 close(fd);
pascal@14268 491 status = 0;
pascal@17451 492 return SUCCESSMSG;
pascal@14150 493 }
pascal@14268 494
pascal@18909 495 static unsigned short files[] = {
pascal@18897 496 WIN32_EXE, /* 0 */
pascal@18897 497 SYSLINUX_MBR, /* 1 */
pascal@18897 498 FLAVOR_INFO, /* 2 */
pascal@18897 499 FLOPPY_BOOT, /* 3 */
pascal@18897 500 TAZBOOT_COM, /* 4 */
pascal@18897 501 ROOTFS_GZ, /* 5 */
pascal@18897 502 DOSSTUB, /* 6 */
pascal@18897 503 BOOT_MD5, /* 7 */
pascal@18897 504 FS_ISO, /* 8 */
pascal@18897 505 CUSTOM_MAGIC, /* 9 */
pascal@18897 506 CUSTOM_APPEND, /* 10 */
pascal@18897 507 CUSTOM_INITRD /* 11 */
pascal@18897 508 };
pascal@18897 509
pascal@18897 510 static long file_offset, file_size;
pascal@18897 511 static void fileofs(int number)
pascal@18897 512 {
pascal@18897 513 unsigned long i, c, stub;
pascal@18897 514 char *s;
pascal@18897 515
pascal@18897 516 c = getcustomsector();
pascal@18909 517 readsector(0UL);
pascal@18897 518 i = 1024;
pascal@18897 519 if (WORD(buffer+1024) != 35615) i = 512 * (1 + BYTE(buffer+417));
pascal@18897 520 stub = WORD(buffer+20) - 0xC0;
pascal@18897 521 file_size = file_offset = 0;
pascal@18897 522 switch (files[number]) {
pascal@18897 523 case WIN32_EXE: /* win32.exe */
pascal@18897 524 if (i != 1024) file_size = i - 512; break;
pascal@18897 525 case SYSLINUX_MBR: /* syslinux.mbr */
pascal@18897 526 if (i != 1024) file_offset = i - 512;
pascal@18897 527 file_size = 512; break;
pascal@18897 528 case FLAVOR_INFO: /* flavor.info */
pascal@18897 529 file_offset = i; file_size = 0; break;
pascal@18897 530 case FLOPPY_BOOT: /* floppy.boot */
pascal@18897 531 file_size = BYTE(buffer+26)*512;
pascal@18897 532 file_offset = WORD(buffer+64) - 0xC0 - file_size; break;
pascal@18897 533 case TAZBOOT_COM: /* tazboot.com */
pascal@18897 534 file_offset = WORD(buffer+64) - 0xC0;
pascal@18897 535 file_size = stub - WORD(buffer+24) - file_offset; break;
pascal@18897 536 case ROOTFS_GZ: /* rootfs.gz */
pascal@18897 537 file_size = WORD(buffer+24);
pascal@18897 538 file_offset = stub - file_size; break;
pascal@18897 539 case DOSSTUB: /* dosstub */
pascal@18897 540 file_offset = stub;
pascal@18897 541 file_size = 0x8000U - file_offset; break;
pascal@18897 542 case BOOT_MD5: /* boot.md5 */
pascal@18897 543 file_offset = 0x7FF0U; file_size = 16; break;
pascal@18897 544 case FS_ISO: /* fs.iso */
pascal@18897 545 file_offset = 0x8000U; file_size = 2048*c - file_offset; break;
pascal@18897 546 case CUSTOM_MAGIC: /* custom.magic */
pascal@18897 547 readsector(c);
pascal@18909 548 if (!strncmp(buffer, bootiso+CUSTOM_HEADER, 6)) {
pascal@18897 549 file_size = 39; file_offset = 2048*c;
pascal@18897 550 }; break;
pascal@18897 551 case CUSTOM_APPEND: /* custom.append */
pascal@18897 552 readsector(c);
pascal@18897 553 file_offset = 2048*c + 47; s = strstr(buffer, "append=");
pascal@18897 554 if (s) file_size = strchr(s,'\n') - s - 7;
pascal@18897 555 break;
pascal@18897 556 case CUSTOM_INITRD: /* custom.initrd */
pascal@18897 557 readsector(c);
pascal@18897 558 s = strstr(buffer,"initrd:");
pascal@18897 559 if (!s) break;
pascal@18897 560 file_size = atoi(s + 7);
pascal@18897 561 s = strchr(s,'\n') + 1;
pascal@18897 562 file_offset = 2048*c + (s - buffer);
pascal@18897 563 }
pascal@18897 564 }
pascal@18897 565
pascal@18909 566 static long heap = 0;
pascal@18909 567 static void show_free(void)
pascal@18909 568 {
pascal@18909 569 if (file_offset > heap && (file_offset - heap) > 16)
pascal@18909 570 printf(bootiso + FREE_FORMAT, file_offset - heap,
pascal@18909 571 heap, file_offset);
pascal@18909 572 }
pascal@18909 573
pascal@18897 574 static void list(void)
pascal@18897 575 {
pascal@18909 576 int num;
pascal@18897 577
pascal@18897 578 for (num = 0; num < sizeof(files)/sizeof(files[0]); num++) {
pascal@18897 579 fileofs(num);
pascal@18897 580 if (file_size <= 0 || file_offset > 0x3FFFFFFFUL) continue;
pascal@18897 581 readsector(file_offset / 2048);
pascal@18897 582 if (WORD(buffer + file_offset % 2048) == 0) continue;
pascal@18909 583 show_free();
pascal@18897 584 if (file_offset >= heap) heap = file_offset + file_size;
pascal@18909 585 printf(bootiso + USED_FORMAT, bootiso + files[num],
pascal@18909 586 file_offset, file_size);
pascal@18897 587 }
pascal@18909 588 #ifdef __MSDOS__
pascal@18909 589 file_offset = (heap + 0xFFFFFUL) & 0xFFF00000UL;
pascal@18909 590 #else
pascal@18909 591 file_offset=lseek(fd, 0UL, SEEK_END);
pascal@18909 592 #endif
pascal@18909 593 show_free();
pascal@18897 594 }
pascal@18897 595
pascal@18897 596 static void extract(char *name)
pascal@18897 597 {
pascal@18897 598 int num;
pascal@18897 599
pascal@18897 600 for (num = sizeof(files)/sizeof(files[0]) - 1;
pascal@18897 601 strcmp(name,bootiso + files[num]); num--) if (num <= 0) return;
pascal@18897 602 fileofs(num);
pascal@18897 603 if (file_size == 0) return;
pascal@18897 604 lseek(fd, file_offset, SEEK_SET);
pascal@18897 605 num = open(name, O_WRONLY|O_BINARY|O_CREAT, 0x644);
pascal@18897 606 while (file_size > 0) {
pascal@18897 607 int n = read(fd, buffer, BUFFERSZ);
pascal@18897 608 if (n <= 0) break;
pascal@18897 609 if (n > file_size) n = file_size;
pascal@18897 610 write(num,buffer,n);
pascal@18897 611 file_size -= n;
pascal@18897 612 }
pascal@18897 613 close(num);
pascal@18897 614 }
pascal@18897 615
pascal@14268 616 int main(int argc, char *argv[])
pascal@14268 617 {
pascal@17591 618 int i;
pascal@18775 619 char *s;
pascal@18775 620
pascal@18909 621 data_fixup();
pascal@18897 622 for (i = 0; argc > 2;) {
pascal@18775 623 s = argv[1];
pascal@18775 624 if (*s != '-') break;
pascal@18775 625 while (*s == '-') s++;
pascal@18775 626 switch (*s | 0x20) {
pascal@18775 627 case 'a' : append=argv[2]; break;
pascal@18775 628 case 'i' : initrd=argv[2]; break;
pascal@18897 629 case 'r' : case 'l' :
pascal@18897 630 i++; argv++; argc--; continue;
pascal@18775 631 }
pascal@18775 632 argv += 2;
pascal@18775 633 argc -= 2;
pascal@18775 634 }
pascal@18897 635 if (i != 0) {
pascal@18897 636 fd = open(argv[i],O_RDONLY|O_BINARY);
pascal@18897 637 if (fd == -1) puts(bootiso + OPENERR);
pascal@18897 638 else if (argc <= 2) list();
pascal@18897 639 else for (i = 2; i < argc; i++) extract(argv[i]);
pascal@18897 640 return 0;
pascal@18897 641 }
pascal@17591 642 for (i = 2; i < argc; i++) {
pascal@17591 643 char *s = argv[i];
pascal@17591 644 while ((unsigned)(*s - '-') <= ('/' - '-')) s++;
pascal@17591 645 switch (*s | 0x20) {
pascal@17591 646 case 'f' : forced++; break;
pascal@17810 647 case 'q' : skipmd5++; break;
pascal@17591 648 case 'u' : uninstall++; break;
pascal@17591 649 }
pascal@17591 650 }
pascal@17451 651 puts(bootiso + install(argv[1]));
pascal@16055 652 if (status > 1)
pascal@17451 653 puts(bootiso + FORCEMSG);
pascal@14268 654 #ifdef WIN32
pascal@14268 655 Sleep(2000);
pascal@14268 656 #endif
pascal@14268 657 return status;
pascal@14268 658 }