00001
00002
00003
00004
00005
00006 #define nil 0
00007 #define _POSIX_SOURCE 1
00008 #define _MINIX 1
00009 #include <stdio.h>
00010 #include <stddef.h>
00011 #include <sys/types.h>
00012 #include <sys/stat.h>
00013 #include <sys/ioctl.h>
00014 #include <stdlib.h>
00015 #include <unistd.h>
00016 #include <fcntl.h>
00017 #include <string.h>
00018 #include <errno.h>
00019 #include <dirent.h>
00020 #include <a.out.h>
00021 #include <minix/config.h>
00022 #include <minix/const.h>
00023 #include <minix/partition.h>
00024 #include <minix/u64.h>
00025 #include "rawfs.h"
00026 #include "image.h"
00027
00028 #define BOOTBLOCK 0
00029 #define SECTOR_SIZE 512
00030 #define RATIO(b) ((b)/SECTOR_SIZE)
00031 #define SIGNATURE 0xAA55
00032 #define BOOT_MAX 64
00033 #define SIGPOS 510
00034 #define PARTPOS 446
00035
00036
00037
00038 #define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a)))
00039 #define control(c) between('\0', (c), '\37')
00040
00041 #define BOOT_BLOCK_SIZE 1024
00042
00043 void report(char *label)
00044
00045 {
00046 fprintf(stderr, "installboot: %s: %s\n", label, strerror(errno));
00047 }
00048
00049 void fatal(char *label)
00050 {
00051 report(label);
00052 exit(1);
00053 }
00054
00055 char *basename(char *name)
00056
00057
00058
00059
00060 {
00061 static char base[IM_NAME_MAX];
00062 char *p, *bp= base;
00063
00064 if ((p= strchr(name, ':')) != nil) {
00065 while (name <= p && bp < base + IM_NAME_MAX - 1)
00066 *bp++ = *name++;
00067 }
00068 for (;;) {
00069 if ((p= strrchr(name, '/')) == nil) { p= name; break; }
00070 if (*++p != 0) break;
00071 *--p= 0;
00072 }
00073 while (*p != 0 && bp < base + IM_NAME_MAX - 1) *bp++ = *p++;
00074 *bp= 0;
00075 return base;
00076 }
00077
00078 void bread(FILE *f, char *name, void *buf, size_t len)
00079
00080 {
00081 if (len > 0 && fread(buf, len, 1, f) != 1) {
00082 if (ferror(f)) fatal(name);
00083 fprintf(stderr, "installboot: Unexpected EOF on %s\n", name);
00084 exit(1);
00085 }
00086 }
00087
00088 void bwrite(FILE *f, char *name, void *buf, size_t len)
00089 {
00090 if (len > 0 && fwrite(buf, len, 1, f) != 1) fatal(name);
00091 }
00092
00093 long total_text= 0, total_data= 0, total_bss= 0;
00094 int making_image= 0;
00095
00096 void read_header(int talk, char *proc, FILE *procf, struct image_header *ihdr)
00097
00098
00099
00100 {
00101 int n, big= 0;
00102 static int banner= 0;
00103 struct exec *phdr= &ihdr->process;
00104
00105 if (procf == nil) {
00106
00107 n= phdr->a_hdrlen;
00108 } else {
00109 memset(ihdr, 0, sizeof(*ihdr));
00110
00111
00112 strncpy(ihdr->name, basename(proc), IM_NAME_MAX);
00113
00114
00115 n= fread(phdr, sizeof(char), A_MINHDR, procf);
00116 if (ferror(procf)) fatal(proc);
00117 }
00118
00119 if (n < A_MINHDR || BADMAG(*phdr)) {
00120 fprintf(stderr, "installboot: %s is not an executable\n", proc);
00121 exit(1);
00122 }
00123
00124
00125 if (procf != nil) {
00126 bread(procf, proc, ((char *) phdr) + A_MINHDR,
00127 phdr->a_hdrlen - A_MINHDR);
00128 }
00129
00130 if (talk && !banner) {
00131 printf(" text data bss size\n");
00132 banner= 1;
00133 }
00134
00135 if (talk) {
00136 printf(" %8ld %8ld %8ld %9ld %s\n",
00137 phdr->a_text, phdr->a_data, phdr->a_bss,
00138 phdr->a_text + phdr->a_data + phdr->a_bss, proc);
00139 }
00140 total_text+= phdr->a_text;
00141 total_data+= phdr->a_data;
00142 total_bss+= phdr->a_bss;
00143
00144 if (phdr->a_cpu == A_I8086) {
00145 long data= phdr->a_data + phdr->a_bss;
00146
00147 if (!(phdr->a_flags & A_SEP)) data+= phdr->a_text;
00148
00149 if (phdr->a_text >= 65536) big|= 1;
00150 if (data >= 65536) big|= 2;
00151 }
00152 if (big) {
00153 fprintf(stderr,
00154 "%s will crash, %s%s%s segment%s larger then 64K\n",
00155 proc,
00156 big & 1 ? "text" : "",
00157 big == 3 ? " and " : "",
00158 big & 2 ? "data" : "",
00159 big == 3 ? "s are" : " is");
00160 }
00161 }
00162
00163 void padimage(char *image, FILE *imagef, int n)
00164
00165 {
00166 while (n > 0) {
00167 if (putc(0, imagef) == EOF) fatal(image);
00168 n--;
00169 }
00170 }
00171
00172 #define align(n) (((n) + ((SECTOR_SIZE) - 1)) & ~((SECTOR_SIZE) - 1))
00173
00174 void copyexec(char *proc, FILE *procf, char *image, FILE *imagef, long n)
00175
00176 {
00177 int pad, c;
00178
00179
00180 pad= align(n) - n;
00181
00182 while (n > 0) {
00183 if ((c= getc(procf)) == EOF) {
00184 if (ferror(procf)) fatal(proc);
00185 fprintf(stderr, "installboot: premature EOF on %s\n",
00186 proc);
00187 exit(1);
00188 }
00189 if (putc(c, imagef) == EOF) fatal(image);
00190 n--;
00191 }
00192 padimage(image, imagef, pad);
00193 }
00194
00195 void make_image(char *image, char **procv)
00196
00197
00198
00199 {
00200 FILE *imagef, *procf;
00201 char *proc, *file;
00202 int procn;
00203 struct image_header ihdr;
00204 struct exec phdr;
00205 struct stat st;
00206
00207 making_image= 1;
00208
00209 if ((imagef= fopen(image, "w")) == nil) fatal(image);
00210
00211 for (procn= 0; (proc= *procv++) != nil; procn++) {
00212
00213 if ((file= strchr(proc, ':')) != nil) file++; else file= proc;
00214
00215
00216 if (stat(file, &st) < 0
00217 || (errno= EISDIR, !S_ISREG(st.st_mode))
00218 || (procf= fopen(file, "r")) == nil
00219 ) fatal(proc);
00220
00221
00222 read_header(1, proc, procf, &ihdr);
00223
00224
00225 phdr= ihdr.process;
00226
00227
00228 ihdr.process.a_syms= 0;
00229 ihdr.process.a_flags &= ~A_NSYM;
00230
00231
00232 bwrite(imagef, image, &ihdr, sizeof(ihdr));
00233
00234 padimage(image, imagef, SECTOR_SIZE - sizeof(ihdr));
00235
00236
00237 if (phdr.a_flags & A_PAL) {
00238 rewind(procf);
00239 phdr.a_text+= phdr.a_hdrlen;
00240 }
00241
00242
00243 if (phdr.a_flags & A_SEP) {
00244
00245
00246 copyexec(proc, procf, image, imagef, phdr.a_text);
00247 copyexec(proc, procf, image, imagef, phdr.a_data);
00248 } else {
00249
00250
00251 copyexec(proc, procf, image, imagef,
00252 phdr.a_text + phdr.a_data);
00253 }
00254
00255
00256 (void) fclose(procf);
00257 }
00258
00259
00260 if (fclose(imagef) == EOF) fatal(image);
00261
00262 printf(" ------ ------ ------ -------\n");
00263 printf(" %8ld %8ld %8ld %9ld total\n",
00264 total_text, total_data, total_bss,
00265 total_text + total_data + total_bss);
00266 }
00267
00268 void extractexec(FILE *imagef, char *image, FILE *procf, char *proc,
00269 long count, off_t *alen)
00270
00271 {
00272 char buf[SECTOR_SIZE];
00273
00274 while (count > 0) {
00275 bread(imagef, image, buf, sizeof(buf));
00276 *alen-= sizeof(buf);
00277
00278 bwrite(procf, proc, buf,
00279 count < sizeof(buf) ? (size_t) count : sizeof(buf));
00280 count-= sizeof(buf);
00281 }
00282 }
00283
00284 void extract_image(char *image)
00285
00286 {
00287 FILE *imagef, *procf;
00288 off_t len;
00289 struct stat st;
00290 struct image_header ihdr;
00291 struct exec phdr;
00292 char buf[SECTOR_SIZE];
00293
00294 if (stat(image, &st) < 0) fatal(image);
00295
00296
00297 len= S_ISREG(st.st_mode) ? st.st_size : -1;
00298
00299 if ((imagef= fopen(image, "r")) == nil) fatal(image);
00300
00301 while (len != 0) {
00302
00303 bread(imagef, image, buf, sizeof(buf));
00304 len-= sizeof(buf);
00305
00306 memcpy(&ihdr, buf, sizeof(ihdr));
00307 phdr= ihdr.process;
00308
00309
00310 read_header(1, ihdr.name, nil, &ihdr);
00311
00312 if ((procf= fopen(ihdr.name, "w")) == nil) fatal(ihdr.name);
00313
00314 if (phdr.a_flags & A_PAL) {
00315
00316 phdr.a_text+= phdr.a_hdrlen;
00317 } else {
00318 bwrite(procf, ihdr.name, &ihdr.process, phdr.a_hdrlen);
00319 }
00320
00321
00322 if (phdr.a_flags & A_SEP) {
00323 extractexec(imagef, image, procf, ihdr.name,
00324 phdr.a_text, &len);
00325 extractexec(imagef, image, procf, ihdr.name,
00326 phdr.a_data, &len);
00327 } else {
00328 extractexec(imagef, image, procf, ihdr.name,
00329 phdr.a_text + phdr.a_data, &len);
00330 }
00331
00332 if (fclose(procf) == EOF) fatal(ihdr.name);
00333 }
00334 }
00335
00336 int rawfd;
00337 char *rawdev;
00338
00339 void readblock(off_t blk, char *buf, int block_size)
00340
00341 {
00342 int n;
00343
00344 if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
00345 || (n= read(rawfd, buf, block_size)) < 0
00346 ) fatal(rawdev);
00347
00348 if (n < block_size) {
00349 fprintf(stderr, "installboot: Unexpected EOF on %s\n", rawdev);
00350 exit(1);
00351 }
00352 }
00353
00354 void writeblock(off_t blk, char *buf, int block_size)
00355
00356 {
00357 if (lseek(rawfd, blk * block_size, SEEK_SET) < 0
00358 || write(rawfd, buf, block_size) < 0
00359 ) fatal(rawdev);
00360 }
00361
00362 int raw_install(char *file, off_t *start, off_t *len, int block_size)
00363
00364
00365
00366
00367
00368
00369 {
00370 static char buf[_MAX_BLOCK_SIZE];
00371 FILE *f;
00372 off_t sec;
00373 unsigned long devsize;
00374 static int banner= 0;
00375 struct partition entry;
00376
00377
00378 devsize= -1;
00379 if (ioctl(rawfd, DIOCGETP, &entry) == 0) devsize= cv64ul(entry.size);
00380
00381 if ((f= fopen(file, "r")) == nil) fatal(file);
00382
00383
00384 sec= *start;
00385 do {
00386 int off= sec % RATIO(BOOT_BLOCK_SIZE);
00387
00388 if (fread(buf + off * SECTOR_SIZE, 1, SECTOR_SIZE, f) == 0)
00389 break;
00390
00391 if (sec >= devsize) {
00392 fprintf(stderr,
00393 "installboot: %s can't be attached to %s\n",
00394 file, rawdev);
00395 return 0;
00396 }
00397
00398 if (off == RATIO(BOOT_BLOCK_SIZE) - 1) writeblock(sec / RATIO(BOOT_BLOCK_SIZE), buf, BOOT_BLOCK_SIZE);
00399 } while (++sec != *start + *len);
00400
00401 if (ferror(f)) fatal(file);
00402 (void) fclose(f);
00403
00404
00405 if (sec % RATIO(BOOT_BLOCK_SIZE) != 0) writeblock(sec / RATIO(BOOT_BLOCK_SIZE), buf, BOOT_BLOCK_SIZE);
00406
00407 if (!banner) {
00408 printf(" sector length\n");
00409 banner= 1;
00410 }
00411 *len= sec - *start;
00412 printf("%8ld%8ld %s\n", *start, *len, file);
00413 *start= sec;
00414 return 1;
00415 }
00416
00417 enum howto { FS, BOOT };
00418
00419 void make_bootable(enum howto how, char *device, char *bootblock,
00420 char *bootcode, char **imagev)
00421
00422
00423
00424
00425
00426 {
00427 char buf[_MAX_BLOCK_SIZE + 256], *adrp, *parmp;
00428 struct fileaddr {
00429 off_t address;
00430 int count;
00431 } bootaddr[BOOT_MAX + 1], *bap= bootaddr;
00432 struct exec boothdr;
00433 struct image_header dummy;
00434 struct stat st;
00435 ino_t ino;
00436 off_t sector, max_sector;
00437 FILE *bootf;
00438 off_t addr, fssize, pos, len;
00439 char *labels, *label, *image;
00440 int nolabel;
00441 int block_size = 0;
00442
00443
00444 if ((rawfd= open(rawdev= device, O_RDWR)) < 0) fatal(device);
00445
00446
00447 fssize= r_super(&block_size);
00448
00449 switch (how) {
00450 case FS:
00451 if (fssize == 0) {
00452 fprintf(stderr,
00453 "installboot: %s is not a Minix file system\n",
00454 device);
00455 exit(1);
00456 }
00457 break;
00458 case BOOT:
00459 if (fssize != 0) {
00460 int s;
00461 printf("%s contains a file system!\n", device);
00462 printf("Scribbling in 10 seconds");
00463 for (s= 0; s < 10; s++) {
00464 fputc('.', stdout);
00465 fflush(stdout);
00466 sleep(1);
00467 }
00468 fputc('\n', stdout);
00469 }
00470 fssize= 1;
00471 }
00472
00473 if (how == FS) {
00474
00475 if ((ino= r_lookup(ROOT_INO, bootcode)) == 0) {
00476 if (errno != ENOENT) fatal(bootcode);
00477 }
00478 } else {
00479
00480 ino= 0;
00481 }
00482
00483 if (ino == 0) {
00484
00485
00486
00487 if (stat(bootcode, &st) < 0) fatal(bootcode);
00488
00489 if ((bootf= fopen(bootcode, "r")) == nil) fatal(bootcode);
00490 } else {
00491
00492 r_stat(ino, &st);
00493
00494
00495 if ((addr= r_vir2abs((off_t) 0)) == 0) {
00496 boothdr.a_magic[0]= !A_MAGIC0;
00497 } else {
00498 readblock(addr, buf, block_size);
00499
00500 memcpy(&boothdr, buf + 16, sizeof(struct exec));
00501 }
00502 bootf= nil;
00503 dummy.process= boothdr;
00504 }
00505
00506 read_header(0, bootcode, bootf, &dummy);
00507 boothdr= dummy.process;
00508
00509 if (bootf != nil) fclose(bootf);
00510
00511
00512 max_sector= (boothdr.a_hdrlen + boothdr.a_text
00513 + boothdr.a_data + SECTOR_SIZE - 1) / SECTOR_SIZE;
00514
00515 if (max_sector > BOOT_MAX * RATIO(block_size)) {
00516 fprintf(stderr, "installboot: %s is way too big\n", bootcode);
00517 exit(0);
00518 }
00519
00520
00521
00522
00523 bap->count= 0;
00524
00525 for (sector= 0; sector < max_sector; sector++) {
00526 if (ino == 0) {
00527 addr= fssize + (sector / RATIO(block_size));
00528 } else
00529 if ((addr= r_vir2abs(sector / RATIO(block_size))) == 0) {
00530 fprintf(stderr, "installboot: %s has holes!\n",
00531 bootcode);
00532 exit(1);
00533 }
00534 addr= (addr * RATIO(block_size)) + (sector % RATIO(block_size));
00535
00536
00537 if (bap->count == 0) bap->address= addr;
00538
00539
00540 if (bap->address + bap->count == addr)
00541 bap->count++;
00542 else {
00543
00544 bap++;
00545 bap->address= addr;
00546 bap->count= 1;
00547 }
00548 }
00549 (++bap)->count= 0;
00550
00551
00552 readblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
00553
00554 if ((bootf= fopen(bootblock, "r")) == nil) fatal(bootblock);
00555
00556 read_header(0, bootblock, bootf, &dummy);
00557 boothdr= dummy.process;
00558
00559 if (boothdr.a_text + boothdr.a_data +
00560 4 * (bap - bootaddr) + 1 > PARTPOS) {
00561 fprintf(stderr,
00562 "installboot: %s + addresses to %s don't fit in the boot sector\n",
00563 bootblock, bootcode);
00564 fprintf(stderr,
00565 "You can try copying/reinstalling %s to defragment it\n",
00566 bootcode);
00567 exit(1);
00568 }
00569
00570
00571 bread(bootf, bootblock, buf, boothdr.a_text + boothdr.a_data);
00572 (void) fclose(bootf);
00573
00574
00575 adrp= buf + (int) (boothdr.a_text + boothdr.a_data);
00576 for (bap= bootaddr; bap->count != 0; bap++) {
00577 *adrp++= bap->count;
00578 *adrp++= (bap->address >> 0) & 0xFF;
00579 *adrp++= (bap->address >> 8) & 0xFF;
00580 *adrp++= (bap->address >> 16) & 0xFF;
00581 }
00582
00583 *adrp++= 0;
00584
00585 if (bap > bootaddr+1) {
00586 printf("%s and %d addresses to %s patched into %s\n",
00587 bootblock, (int)(bap - bootaddr), bootcode, device);
00588 }
00589
00590
00591 buf[SIGPOS+0]= (SIGNATURE >> 0) & 0xFF;
00592 buf[SIGPOS+1]= (SIGNATURE >> 8) & 0xFF;
00593
00594
00595
00596
00597
00598 for (parmp= buf + SECTOR_SIZE; parmp < buf + 2*SECTOR_SIZE; parmp++) {
00599 if (*imagev != nil || (control(*parmp) && *parmp != '\n')) {
00600
00601 memset(buf + SECTOR_SIZE, '\n', SECTOR_SIZE);
00602 break;
00603 }
00604 }
00605
00606
00607 pos= fssize * RATIO(block_size);
00608
00609 if (ino == 0) {
00610
00611 len= max_sector;
00612 if (!raw_install(bootcode, &pos, &len, block_size)) {
00613 if (how == FS) {
00614 fprintf(stderr,
00615 "\t(Isn't there a copy of %s on %s that can be used?)\n",
00616 bootcode, device);
00617 }
00618 exit(1);
00619 }
00620 }
00621
00622 parmp= buf + SECTOR_SIZE;
00623 nolabel= 0;
00624
00625 if (how == BOOT) {
00626
00627 strcpy(parmp,
00628 "trailer()echo \\nInsert the root diskette then hit RETURN\\n\\w\\c\n");
00629 parmp+= strlen(parmp);
00630 }
00631
00632 while ((labels= *imagev++) != nil) {
00633
00634
00635 if ((image= strchr(labels, ':')) != nil)
00636 *image++= 0;
00637 else {
00638 if (nolabel) {
00639 fprintf(stderr,
00640 "installboot: Only one image can be the default\n");
00641 exit(1);
00642 }
00643 nolabel= 1;
00644 image= labels;
00645 labels= nil;
00646 }
00647 len= 0;
00648 if (!raw_install(image, &pos, &len, block_size)) exit(1);
00649
00650 if (labels == nil) {
00651
00652 sprintf(parmp, "image=%ld:%ld\n", pos-len, len);
00653 parmp+= strlen(parmp);
00654 }
00655
00656 while (labels != nil) {
00657
00658
00659
00660 label= labels;
00661 if ((labels= strchr(labels, ',')) != nil) *labels++ = 0;
00662
00663 sprintf(parmp,
00664 "%s(%c){label=%s;image=%ld:%ld;echo %s kernel selected;menu}\n",
00665 label,
00666 between('A', label[0], 'Z')
00667 ? label[0]-'A'+'a' : label[0],
00668 label, pos-len, len, label);
00669 parmp+= strlen(parmp);
00670 }
00671
00672 if (parmp > buf + block_size) {
00673 fprintf(stderr,
00674 "installboot: Out of parameter space, too many images\n");
00675 exit(1);
00676 }
00677 }
00678
00679 writeblock((off_t) BOOTBLOCK, buf, 1024);
00680
00681 if (pos > fssize * RATIO(block_size)) {
00682
00683 printf("%16ld (%ld kb) total\n", pos,
00684 (pos + RATIO(block_size) - 1) / RATIO(block_size));
00685 }
00686 }
00687
00688 void install_master(char *device, char *masterboot, char **guide)
00689
00690
00691
00692
00693
00694
00695 {
00696 FILE *masf;
00697 unsigned long size;
00698 struct stat st;
00699 static char buf[_MAX_BLOCK_SIZE];
00700
00701
00702 if ((rawfd= open(rawdev= device, O_RDWR)) < 0) fatal(device);
00703
00704
00705 if ((masf= fopen(masterboot, "r")) == nil) fatal(masterboot);
00706
00707
00708 if (fstat(fileno(masf), &st) >=0 && S_ISBLK(st.st_mode))
00709 size= PARTPOS;
00710 else {
00711
00712 struct image_header ihdr;
00713
00714 read_header(1, masterboot, masf, &ihdr);
00715 size= ihdr.process.a_text + ihdr.process.a_data;
00716 }
00717 if (size > PARTPOS) {
00718 fprintf(stderr, "installboot: %s is too big\n", masterboot);
00719 exit(1);
00720 }
00721
00722
00723 readblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
00724
00725 memset(buf, 0, PARTPOS);
00726 (void) bread(masf, masterboot, buf, size);
00727
00728 if (guide[0] != nil) {
00729
00730 char *keys= guide[0];
00731 char *logical= guide[1];
00732 size_t i;
00733 int logfd;
00734 u32_t offset;
00735 struct partition geometry;
00736
00737
00738 i= 0;
00739 do {
00740 if (!between('0', keys[i], '9')) {
00741 fprintf(stderr,
00742 "installboot: bad guide keys '%s'\n",
00743 keys);
00744 exit(1);
00745 }
00746 } while (keys[++i] != 0);
00747
00748 if (size + i + 1 > PARTPOS) {
00749 fprintf(stderr,
00750 "installboot: not enough space after '%s' for '%s'\n",
00751 masterboot, keys);
00752 exit(1);
00753 }
00754 memcpy(buf + size, keys, i);
00755 size += i;
00756 buf[size]= '\r';
00757
00758 if (logical != nil) {
00759 if ((logfd= open(logical, O_RDONLY)) < 0
00760 || ioctl(logfd, DIOCGETP, &geometry) < 0
00761 ) {
00762 fatal(logical);
00763 }
00764 offset= div64u(geometry.base, SECTOR_SIZE);
00765 if (size + 5 > PARTPOS) {
00766 fprintf(stderr,
00767 "installboot: not enough space "
00768 "after '%s' for '%s' and an offset "
00769 "to '%s'\n",
00770 masterboot, keys, logical);
00771 exit(1);
00772 }
00773 buf[size]= '#';
00774 memcpy(buf+size+1, &offset, 4);
00775 }
00776 }
00777
00778
00779 buf[SIGPOS+0]= (SIGNATURE >> 0) & 0xFF;
00780 buf[SIGPOS+1]= (SIGNATURE >> 8) & 0xFF;
00781
00782 writeblock(BOOTBLOCK, buf, BOOT_BLOCK_SIZE);
00783 }
00784
00785 void usage(void)
00786 {
00787 fprintf(stderr,
00788 "Usage: installboot -i(mage) image kernel mm fs ... init\n"
00789 " installboot -(e)x(tract) image\n"
00790 " installboot -d(evice) device bootblock boot [image ...]\n"
00791 " installboot -b(oot) device bootblock boot image ...\n"
00792 " installboot -m(aster) device masterboot [keys [logical]]\n");
00793 exit(1);
00794 }
00795
00796 int isoption(char *option, char *test)
00797
00798
00799
00800 {
00801 if (strcmp(option, test) == 0) return 1;
00802 if (option[0] != '-' && strlen(option) != 2) return 0;
00803 if (option[1] == test[1]) return 1;
00804 if (option[1] == 'x' && test[1] == 'e') return 1;
00805 return 0;
00806 }
00807
00808 int main(int argc, char **argv)
00809 {
00810 if (argc < 2) usage();
00811
00812 if (argc >= 4 && isoption(argv[1], "-image")) {
00813 make_image(argv[2], argv + 3);
00814 } else
00815 if (argc == 3 && isoption(argv[1], "-extract")) {
00816 extract_image(argv[2]);
00817 } else
00818 if (argc >= 5 && isoption(argv[1], "-device")) {
00819 make_bootable(FS, argv[2], argv[3], argv[4], argv + 5);
00820 } else
00821 if (argc >= 6 && isoption(argv[1], "-boot")) {
00822 make_bootable(BOOT, argv[2], argv[3], argv[4], argv + 5);
00823 } else
00824 if ((4 <= argc && argc <= 6) && isoption(argv[1], "-master")) {
00825 install_master(argv[2], argv[3], argv + 4);
00826 } else {
00827 usage();
00828 }
00829 exit(0);
00830 }
00831
00832
00833
00834