2 * GRUB Utilities -- Utilities for GRUB Legacy, GRUB2 and GRUB for DOS
3 * Copyright (C) 2007 Bean (bean123@126.com)
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
38 // Application flags, used by this program
42 #define AFG_READ_ONLY 4
43 #define AFG_NO_BACKUP_MBR 8
44 #define AFG_FORCE_BACKUP_MBR 16
45 #define AFG_RESTORE_PREVMBR 32
46 #define AFG_LIST_PART 64
47 #define AFG_IS_FLOPPY 128
48 #define AFG_LBA_MODE 256
49 #define AFG_CHS_MODE 512
50 #define AFG_OUTPUT 1024
53 // Grldr flags, this flag is used by grldr.mbr
55 #define GFG_DISABLE_FLOPPY 1
56 #define GFG_DISABLE_OSBR 2
58 #define GFG_PREVMBR_LAST 128
60 #define APP_NAME "grubinst: "
62 #define print_pause if (afg & AFG_PAUSE) {fputs("Press <ENTER> to continue ...\n",stderr); fflush(stderr); fgetc(stdin);}
64 #define print_apperr(a) { fprintf(stderr,APP_NAME "%s\n",a); print_pause; }
65 #define print_syserr(a) { perror(APP_NAME a); print_pause; }
67 static void help(void)
70 "\tgrubinst [OPTIONS] DEVICE_OR_FILE\n\n"
72 "\t--help,-h\t\tShow usage information\n\n"
73 "\t--pause\t\t\tPause before exiting\n\n"
74 "\t--version\t\tShow version information\n\n"
75 "\t--verbose,-v\t\tVerbose output\n\n"
76 "\t--list-part,-l\t\tList all logical partitions in DEVICE_OR_FILE\n\n"
77 "\t--save=FN,-s=FN\t\tSave the orginal MBR/BS to FN\n\n"
78 "\t--restore=FN,-r=FN\tRestore MBR/BS from previously saved FN\n\n"
79 "\t--restore-prevmbr,-r\tRestore previous MBR saved in the second sector\n"
80 "\t\t\t\tof DEVICE_OR_FILE\n\n"
81 "\t--read-only,-t\t\tdo everything except the actual write to the\n"
82 "\t\t\t\tspecified DEVICE_OR_FILE. (test mode)\n\n"
83 "\t--no-backup-mbr\t\tdo not copy the old MBR to the second sector of\n"
84 "\t\t\t\tDEVICE_OR_FILE.\n\n"
85 "\t--force-backup-mbr\tforce the copy of old MBR to the second sector\n"
86 "\t\t\t\tof DEVICE_OR_FILE.(default)\n\n"
87 "\t--mbr-enable-floppy\tenable the search for GRLDR on floppy.(default)\n\n"
88 "\t--mbr-disable-floppy\tdisable the search for GRLDR on floppy.\n\n"
89 "\t--mbr-enable-osbr\tenable the boot of PREVIOUS MBR with invalid\n"
90 "\t\t\t\tpartition table (usually an OS boot sector).\n"
91 "\t\t\t\t(default)\n\n"
92 "\t--mbr-disable-osbr\tdisable the boot of PREVIOUS MBR with invalid\n"
93 "\t\t\t\tpartition table (usually an OS boot sector).\n\n"
94 "\t--duce\t\t\tdisable the feature of unconditional entrance\n"
95 "\t\t\t\tto the command-line.\n\n"
96 "\t--boot-prevmbr-first\ttry to boot PREVIOUS MBR before the search for\n"
98 "\t--boot-prevmbr-last\ttry to boot PREVIOUS MBR after the search for\n"
99 "\t\t\t\tGRLDR.(default)\n\n"
100 "\t--preferred-drive=D\tpreferred boot drive number, 0 <= D < 255.\n\n"
101 "\t--preferred-partition=P\tpreferred partition number, 0 <= P < 255.\n\n"
102 "\t--time-out=T,-t=T\twait T seconds before booting PREVIOUS MBR. if\n"
103 "\t\t\t\tT is 0xff, wait forever. The default is 5.\n\n"
104 "\t\t\t\tbefore booting PREVIOUS MBR. K is a word\n"
105 "\t\t\t\tvalue, just as the value in AX register\n"
106 "\t\t\t\treturned from int16/AH=1. The high byte is the\n"
107 "\t\t\t\tscan code and the low byte is ASCII code. The\n"
108 "\t\t\t\tdefault is 0x3920 for space bar.\n\n"
109 "\t--key-name=S\t\tSpecify the name of the hot key.\n\n"
110 "\t--floppy,-f\t\tif DEVICE_OR_FILE is floppy, use this option.\n\n"
111 "\t--floppy=N\t\tif DEVICE_OR_FILE is a partition on a hard\n"
112 "\t\t\t\tdrive, use this option. N is used to specify\n"
113 "\t\t\t\tthe partition number: 0,1,2 and 3 for the\n"
114 "\t\t\t\tprimary partitions, and 4,5,6,... for the\n"
115 "\t\t\t\tlogical partitions.\n\n"
116 "\t--sectors-per-track=S\tspecifies sectors per track for --floppy.\n"
117 "\t\t\t\t1 <= S <= 63, default is 63.\n\n"
118 "\t--heads=H\t\tspecifies number of heads for --floppy.\n"
119 "\t\t\t\t1 <= H <= 256, default is 255.\n\n"
120 "\t--start-sector=B\tspecifies hidden sectors for --floppy=N.\n\n"
121 "\t--total-sectors=C\tspecifies total sectors for --floppy.\n"
122 "\t\t\t\tdefault is 0.\n\n"
123 "\t--lba\t\t\tuse lba mode for --floppy. If the floppy BIOS\n"
124 "\t\t\t\thas LBA support, you can specify --lba here.\n"
125 "\t\t\t\tIt is assumed that all floppy BIOSes have CHS\n"
126 "\t\t\t\tsupport. So you would rather specify --chs.\n"
127 "\t\t\t\tIf neither --chs nor --lba is specified, then\n"
128 "\t\t\t\tthe LBA indicator(i.e., the third byte of the\n"
129 "\t\t\t\tboot sector) will not be touched.\n\n"
130 "\t--chs\t\t\tuse chs mode for --floppy. You should specify\n"
131 "\t\t\t\t--chs if the floppy BIOS does not support LBA.\n"
132 "\t\t\t\tWe assume all floppy BIOSes have CHS support.\n"
133 "\t\t\t\tSo it is likely you want to specify --chs.\n"
134 "\t\t\t\tIf neither --chs nor --lba is specified, then\n"
135 "\t\t\t\tthe LBA indicator(i.e., the third byte of the\n"
136 "\t\t\t\tboot sector) will not be touched.\n\n"
137 "\t--install-partition=I\tInstall the boot record onto the boot area of\n"
138 "\t-p=I\t\t\tpartition number I of the specified hard drive\n"
139 "\t\t\t\tor harddrive image DEVICE_OR_FILE.\n\n"
140 "\t--boot-file=F,-b=F\tChange the name of boot file.\n\n"
141 "\t--load-seg=S\t\tChange load segment for boot file.\n\n"
142 "\t--grub2,-2\t\tLoad grub2 kernel g2ldr instead of grldr.\n\n"
143 "\t--output,-o\t\tSave embeded grldr.mbr to DEVICE_OR_FILE.\n\n"
144 "\t--edit,-e\t\tEdit external grldr/grldr.mbr.\n",
148 int afg
,gfg
,def_drive
,def_part
,time_out
,hot_key
,part_num
;
149 int def_spt
,def_hds
,def_ssc
,def_tsc
;
150 char *save_fn
,*restore_fn
,boot_file_83
[12];
151 const char *key_name
;
152 const char *boot_file
;
153 unsigned short load_seg
;
155 static char fn_buf
[24];
157 static char* get_disk_name(int n
)
160 sprintf(fn_buf
,"\\\\.\\PhysicalDrive%d",n
);
162 sprintf(fn_buf
,"/dev/hd%c",'a'+n
);
163 #elif defined(FREEBSD)
164 sprintf(fn_buf
,"/dev/ad%d",n
);
166 print_apperr("Disk device is not supported in your system");
172 static char* get_flop_name(int n
)
177 print_apperr("Only two floppy drives are supported");
180 sprintf(fn_buf
,"\\\\.\\%c:",'A'+n
);
181 #elif defined(LINUX) || defined(FREEBSD)
182 sprintf(fn_buf
,"/dev/fd%d",n
);
184 print_apperr("Floppy device is not supported in your system");
190 static char* parse_fname(char* fn
)
192 if ((afg
& AFG_OUTPUT
) && (fn
[0]=='('))
194 print_apperr("Can\'t use device name while using --output option");
197 if ((! strncmp(fn
,"(hd",3)) || (! strncmp(fn
,"(fd",3)))
202 n
=strtol(&fn
[3],&p
,0);
203 if ((n
<0) || (n
>=MAX_DISKS
))
205 print_apperr("Invalid device number");
210 part_num
=strtol(p
+1,&p
,0);
211 if ((part_num
<0) || (part_num
>=MAX_PARTS
))
213 print_apperr("Invalid partition number");
217 if ((*p
!=')') || (*(p
+1)!=0))
219 print_apperr("Invalid device name");
233 static char* str_upcase(char* str
)
238 if ((str
[i
]>='a') && (str
[i
]<='z'))
244 static char* str_lowcase(char* str
)
249 if ((str
[i
]>='A') && (str
[i
]<='Z'))
255 static int SetBootFile(char* fn
)
265 if ((pc
==fn
) || (pc
-fn
>8) || (strlen(pc
+1)>3))
268 memset(boot_file_83
,' ',sizeof(boot_file_83
)-1);
271 memcpy(boot_file_83
,fn
,pc
-fn
);
272 memcpy(&boot_file_83
[8],pc
+1,strlen(pc
+1));
275 memcpy(boot_file_83
,fn
,strlen(fn
));
281 static void list(int hd
)
286 fprintf(stderr
," # id base leng\n");
287 while (! xd_enum(hd
,&xe
))
288 fprintf(stderr
,"%2d %02llX %8llX %8llX\n",xe
.cur
,
289 (unsigned long long) xe
.dfs
,
290 (unsigned long long) xe
.bse
,
291 (unsigned long long) xe
.len
);
294 static int is_grldr_mbr(unsigned char* buf
)
299 n
=sizeof("Missing MBR-helper.")-1;
301 while ((i
>n
) && (buf
[i
]==0))
303 return (! memcmp(&buf
[i
-n
+1],"Missing MBR-helper.", sizeof("Missing MBR-helper.")));
306 static int install(char* fn
)
308 int hd
= -1,nn
,fs
,slen
;
309 unsigned char prev_mbr
[sizeof(grub_mbr
)];
317 unsigned short r1
,r2
;
319 if (afg
& AFG_VERBOSE
)
320 fprintf(stderr
,"Edit mode\n");
321 hd
=open(fn
,O_RDWR
| O_BINARY
,0644);
324 print_syserr("open");
327 r1
=get16(&grub_mbr
[0x1FFA],0);
328 nn
=read(hd
,grub_mbr
,sizeof(grub_mbr
));
331 print_syserr("read");
335 if (nn
<(int)sizeof(grub_mbr
))
337 print_apperr("The input file is too short");
341 if (get32(&grub_mbr
[0x1FFC],0)!=0xAA555247)
343 print_apperr("Invalid input file");
347 r2
=get16(&grub_mbr
[0x1FFA],0);
352 sprintf(buf
,"Version number mismatched (old=%d new=%d)",r2
,r1
);
365 // Patching the FAT32 boot sector
366 ofs
=get16(&grub_mbr
,0x400+0x1EC) & 0x7FF;
367 strcpy((char *) &grub_mbr
[0x400+ofs
],boot_file_83
);
369 set16(&grub_mbr
,0x400+0x1EA,load_seg
);
371 // Patching the FAT12/FAT16 boot sector
372 ofs
=get16(&grub_mbr
,0x600+0x1EC) & 0x7FF;
373 strcpy((char *) &grub_mbr
[0x600+ofs
],boot_file_83
);
375 set16(&grub_mbr
,0x600+0x1EA,load_seg
);
377 // Patching the EXT2 boot sector
378 ofs
=get16(grub_mbr
,0x800+0x1EE) & 0x7FF;
379 strcpy((char *) &grub_mbr
[0x800+ofs
],boot_file
);
381 // Patching the NTFS sector
382 ofs
=get16(grub_mbr
,0xA00+0x1EC) & 0x7FF;
383 strcpy((char *) &grub_mbr
[0xA00+ofs
],boot_file
);
385 set16(grub_mbr
,0xA00+0x1EA,load_seg
);
387 if (afg
& AFG_VERBOSE
)
389 fprintf(stderr
,"Boot file changed to %s\n",boot_file
);
391 fprintf(stderr
,"Load segment changed to %04X\n",load_seg
);
395 if (afg
& AFG_OUTPUT
)
399 mode
=(! (afg
& AFG_READ_ONLY
))?(O_TRUNC
| O_CREAT
):0;
400 if (! (afg
& AFG_EDIT
))
402 if (afg
& AFG_VERBOSE
)
403 fprintf(stderr
,"Extract mode\n");
404 hd
=open(fn
,O_RDWR
| O_BINARY
| mode
,0644);
407 print_syserr("open");
411 if (! (afg
& AFG_READ_ONLY
))
412 if (write(hd
,grub_mbr
,sizeof(grub_mbr
))!=sizeof(grub_mbr
))
414 print_apperr("Write to output file fails");
421 memset(&grub_mbr
[512],0,512);
423 grub_mbr
[3]=time_out
;
424 set16(&grub_mbr
,4,hot_key
);
425 grub_mbr
[6] = def_drive
;
426 grub_mbr
[7] = def_part
;
427 if ((key_name
==NULL
) && (hot_key
==0x3920))
430 strcpy((char *) &grub_mbr
[0x1fec],key_name
);
432 hd
=open(fn
,O_RDWR
| O_BINARY
,S_IREAD
| S_IWRITE
);
435 print_syserr("open");
438 if (afg
& AFG_LIST_PART
)
456 print_apperr("Partition not found");
461 if (afg
& AFG_VERBOSE
)
462 fprintf(stderr
,"Part Fs: %02X (%s)\nPart Leng: %llu\n",xe
.dfs
,dfs2str(xe
.dfs
),
463 (unsigned long long) xe
.len
);
468 if (afg
& AFG_VERBOSE
)
469 fprintf(stderr
,"Start sector: %llu\n", (unsigned long long) ssec
);
470 if ((ssec
) && (go_sect(hd
,ssec
)))
472 print_apperr("Can\'t seek to the start sector");
476 nn
=read(hd
,prev_mbr
,sizeof(prev_mbr
));
479 print_syserr("read");
483 if (nn
<(int)sizeof(prev_mbr
))
485 print_apperr("The input file is too short");
489 fs
=get_fstype(prev_mbr
);
490 if (afg
& AFG_VERBOSE
)
492 fprintf(stderr
,"Image type: %s\n",fst2str(fs
));
494 fprintf(stderr
,"Num of heads: %d\nSectors per track: %d\n",mbr_nhd
,mbr_spt
);
498 print_apperr("Unknown image type");
502 if (((part_num
!=-1) || (afg
& AFG_IS_FLOPPY
)) && (fs
==FST_MBR
))
504 print_apperr("Should be a file system image");
508 if ((part_num
==-1) && ((afg
& AFG_IS_FLOPPY
)==0) && (fs
!=FST_MBR
))
510 print_apperr("Should be a disk image");
518 unsigned char bs
[1024];
521 for (n
=0x1BE;n
<0x1FE;n
+=16)
524 if (ofs
>get32(&prev_mbr
[n
],8))
525 ofs
=get32(&prev_mbr
[n
],8);
527 if (ofs
<(sizeof(prev_mbr
)>>9))
529 print_apperr("Not enough room to install mbr");
533 slen
=sizeof(prev_mbr
);
536 print_apperr("Can\'t seek to the first partition");
540 if (read(hd
,bs
,sizeof(bs
))!=sizeof(bs
))
542 print_apperr("Fail to read boot sector");
549 else if (nfs
==FST_FAT16
)
555 memcpy(&grub_mbr
[0xB],&bs
[0xB],sln
);
556 set32(&grub_mbr
[0],0x1C,0);
557 set16(&grub_mbr
[0],0xE,get16(&grub_mbr
[0],0xE) + ofs
);
560 else if (fs
==FST_NTFS
)
565 if (go_sect(hd
,ssec
))
567 print_apperr("Can\'t seek to the start sector");
576 h2
=open(save_fn
,O_CREAT
| O_TRUNC
| O_RDWR
| O_BINARY
,S_IREAD
| S_IWRITE
);
579 print_syserr("open save file");
583 nn
=write(h2
,prev_mbr
,slen
);
586 print_syserr("write save file");
593 print_apperr("Can\'t write the whole MBR to the save file");
600 if (afg
& AFG_RESTORE_PREVMBR
)
604 print_apperr("Not a disk image");
608 if (memcmp(&prev_mbr
[1024+3],"GRLDR",5))
610 print_apperr("GRLDR is not installed");
614 if (get16(prev_mbr
,512+510)!=0xAA55)
616 print_apperr("No previous saved MBR");
620 memset(&grub_mbr
,0,sizeof(grub_mbr
));
621 memcpy(&grub_mbr
,&prev_mbr
[512],512);
622 memcpy(&grub_mbr
[0x1b8],&prev_mbr
[0x1b8],72);
624 if (afg
& AFG_VERBOSE
)
625 fprintf(stderr
,"Restore previous MBR mode\n");
629 // Load MBR/BS from restore file or configure grub_mbr
634 h2
=open(restore_fn
,O_RDONLY
| O_BINARY
,S_IREAD
);
637 print_syserr("open restore file");
641 nn
=read(h2
,grub_mbr
,slen
);
644 print_syserr("read restore file");
649 if ((nn
<512) || ((nn
& 0x1FF)!=0) ||
650 ((fs
!=FST_EXT2
) && (get16(grub_mbr
,510)!=0xAA55)))
652 print_apperr("Invalid restore file");
659 memset(&grub_mbr
[nn
],0,slen
-nn
);
661 //if ((fs==FST_FAT16) || (fs==FST_FAT32) || (fs==FST_NTFS))
666 new_fs
=get_fstype(grub_mbr
);
669 print_apperr("Invalid restore file");
675 if (afg
& AFG_VERBOSE
)
676 fprintf(stderr
,"Restore mode\n");
682 if (! (afg
& AFG_NO_BACKUP_MBR
))
686 if (afg
& AFG_FORCE_BACKUP_MBR
)
690 if (prev_mbr
[512+i
]!=prev_mbr
[512])
693 if ((i
==512) && (! is_grldr_mbr(prev_mbr
)))
694 memcpy(&grub_mbr
[512],prev_mbr
,512);
696 memcpy(&grub_mbr
[512],&prev_mbr
[512],512);
698 memcpy(&grub_mbr
[0x1b8],&prev_mbr
[0x1b8],72);
700 else if (fs
==FST_FAT16
)
702 memcpy(grub_mbr
,&grub_mbr
[0x600],slen
);
703 grub_mbr
[0x41]=part_num
;
705 else if (fs
==FST_FAT32
)
707 memcpy(grub_mbr
,&grub_mbr
[0x400],slen
);
708 grub_mbr
[0x5D]=part_num
;
710 else if (fs
==FST_NTFS
)
712 memcpy(grub_mbr
,&grub_mbr
[0xA00],slen
);
713 grub_mbr
[0x57]=part_num
;
715 else if (fs
==FST_EXT2
)
717 memcpy(&grub_mbr
,&grub_mbr
[0x800],slen
);
718 grub_mbr
[0x25]=part_num
;
719 if (afg
& AFG_LBA_MODE
)
721 else if (afg
& AFG_CHS_MODE
)
724 set16(&grub_mbr
,0x18,def_spt
);
725 else if ((afg
& AFG_IS_FLOPPY
)==0)
726 set16(&grub_mbr
,0x18,63);
728 set16(&grub_mbr
,0x1A,def_hds
);
729 else if ((afg
& AFG_IS_FLOPPY
)==0)
730 set16(&grub_mbr
,0x1A,255);
732 set32(&grub_mbr
,0x20,def_tsc
);
733 set32(&grub_mbr
,0x1C,ssec
);
735 if (prev_mbr
[1024+0x4C]) // s_rev_level
736 set16(&grub_mbr
,0x26,get16(&prev_mbr
[1024],0x58));
738 set16(&grub_mbr
,0x26,0x80);
739 // s_inodes_per_group
740 set32(&grub_mbr
,0x28,get32(&prev_mbr
[1024],0x28));
741 // s_first_data_block+1
742 set32(&grub_mbr
,0x2C,get32(&prev_mbr
[1024],0x14)+1);
747 print_apperr("Invalid file system");
751 if ((fs
==FST_FAT16
) || (fs
==FST_FAT32
) || (fs
==FST_NTFS
))
753 if (afg
& AFG_LBA_MODE
)
755 else if (afg
& AFG_CHS_MODE
)
758 grub_mbr
[2]=prev_mbr
[2];
761 if (afg
& AFG_VERBOSE
)
762 fprintf(stderr
,"Install mode\n");
764 // Patch the new MBR/BS with information from prev_mbr
766 memcpy(&grub_mbr
[0x1b8],&prev_mbr
[0x1b8],72);
767 else if (fs
==FST_FAT16
)
769 memcpy(&grub_mbr
[0xB],&prev_mbr
[0xB],0x3E - 0xB);
770 set32(grub_mbr
,0x1C,ssec
);
772 else if (fs
==FST_FAT32
)
774 memcpy(&grub_mbr
[0xB],&prev_mbr
[0xB],0x5A - 0xB);
775 set32(grub_mbr
,0x1C,ssec
);
777 else if (fs
==FST_NTFS
)
779 memcpy(&grub_mbr
[0xB],&prev_mbr
[0xB],0x54 - 0xB);
780 set32(grub_mbr
,0x1C,ssec
);
783 if (! (afg
& AFG_READ_ONLY
))
785 nn
=write(hd
,grub_mbr
,slen
);
788 print_syserr("write");
794 print_apperr("Can\'t write the whole mbr");
799 else if (afg
& AFG_VERBOSE
)
800 fprintf(stderr
,"Read only mode\n");
805 fputs("The MBR/BS has been successfully installed\n",stderr
);
811 int main(int argc
,char** argv
)
816 part_num
=def_drive
=def_part
=def_spt
=def_hds
=def_ssc
=def_tsc
=-1;
818 gfg
=GFG_PREVMBR_LAST
;
823 for (idx
=1;idx
<argc
;idx
++)
825 if (argv
[idx
][0]!='-')
827 if ((! strcmp(argv
[idx
],"--help"))
828 || (! strcmp(argv
[idx
],"-h")))
834 else if (! strcmp(argv
[idx
],"--version"))
836 fprintf(stderr
,"grubinst version : " VERSION
"\n");
840 else if ((! strcmp(argv
[idx
],"--verbose")) ||
841 (! strcmp(argv
[idx
],"-v")))
843 else if (! strcmp(argv
[idx
],"--pause"))
845 else if ((! strcmp(argv
[idx
],"--read-only"))
846 || (! strcmp(argv
[idx
],"-t")))
848 else if (! strcmp(argv
[idx
],"--no-backup-mbr"))
849 afg
|=AFG_NO_BACKUP_MBR
;
850 else if (! strcmp(argv
[idx
],"--force-backup-mbr"))
851 afg
|=AFG_FORCE_BACKUP_MBR
;
852 else if (! strcmp(argv
[idx
],"--mbr-enable-floppy"))
853 gfg
&=~GFG_DISABLE_FLOPPY
;
854 else if (! strcmp(argv
[idx
],"--mbr-disable-floppy"))
855 gfg
|=GFG_DISABLE_FLOPPY
;
856 else if (! strcmp(argv
[idx
],"--mbr-enable-osbr"))
857 gfg
&=~GFG_DISABLE_OSBR
;
858 else if (! strcmp(argv
[idx
],"--mbr-disable-osbr"))
859 gfg
|=GFG_DISABLE_OSBR
;
860 else if (! strcmp(argv
[idx
],"--duce"))
862 else if (! strcmp(argv
[idx
],"--boot-prevmbr-first"))
863 gfg
&=~GFG_PREVMBR_LAST
;
864 else if (! strcmp(argv
[idx
],"--boot-prevmbr-last"))
865 gfg
|=GFG_PREVMBR_LAST
;
866 else if (! strncmp(argv
[idx
],"--preferred-drive=",18))
868 def_drive
=strtol(&argv
[idx
][18],NULL
,0);
869 if ((def_drive
<0) || (def_drive
>=255))
871 print_apperr("Invalid preferred drive number");
875 else if (! strncmp(argv
[idx
],"--preferred-partition=",22))
877 def_part
=strtol(&argv
[idx
][22],NULL
,0);
878 if ((def_part
<0) || (def_part
>=255))
880 print_apperr("Invalid preferred partition number");
884 else if ((! strncmp(argv
[idx
],"--time-out=",11)) ||
885 (! strncmp(argv
[idx
],"-t=",3)))
887 time_out
=strtol((argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][11],NULL
,0);
888 if ((time_out
<0) || (time_out
>255))
890 print_apperr("Invalid timeout value");
894 else if ((! strncmp(argv
[idx
],"--key-name=",11)))
896 key_name
=&argv
[idx
][11];
897 if (strlen(key_name
)>13)
899 print_apperr("Key name too long");
903 else if ((! strcmp(argv
[idx
],"--restore-prevmbr")) ||
904 (! strcmp(argv
[idx
],"-r")))
905 afg
|=AFG_RESTORE_PREVMBR
;
906 else if ((! strncmp(argv
[idx
],"--save=",7)) ||
907 (! strncmp(argv
[idx
],"-s=",3)))
909 save_fn
=(argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][7];
912 print_apperr("Empty filename");
916 else if ((! strncmp(argv
[idx
],"--restore=",10)) ||
917 (! strncmp(argv
[idx
],"-r=",3)))
919 restore_fn
=(argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][10];
922 print_apperr("Empty filename");
926 else if ((! strcmp(argv
[idx
],"--list-part")) ||
927 (! strcmp(argv
[idx
],"-l")))
929 else if ((! strcmp(argv
[idx
],"--floppy")) ||
930 (! strcmp(argv
[idx
],"-f")))
932 else if ((! strncmp(argv
[idx
],"--floppy=",9)) ||
933 (! strncmp(argv
[idx
],"--install-partition=",20)) ||
934 (! strncmp(argv
[idx
],"-p=",3)))
938 if (argv
[idx
][2]=='f')
940 else if (argv
[idx
][2]=='i')
944 part_num
=strtoul(p
,NULL
,0);
945 if ((part_num
<0) || (part_num
>=MAX_PARTS
))
947 print_apperr("Invalid partition number");
951 else if (! strcmp(argv
[idx
],"--lba"))
953 else if (! strcmp(argv
[idx
],"--chs"))
955 else if (! strncmp(argv
[idx
],"--sectors-per-track=",20))
957 def_spt
=strtol(&argv
[idx
][10],NULL
,0);
958 if ((def_spt
<1) || (def_spt
>63))
960 print_apperr("Invalid sector per track");
964 else if (! strncmp(argv
[idx
],"--heads=",8))
966 def_hds
=strtol(&argv
[idx
][8],NULL
,0);
967 if ((def_hds
<1) || (def_hds
>255))
969 print_apperr("Invalid number of heads");
973 else if (! strncmp(argv
[idx
],"--start-sector=",15))
975 def_spt
=strtol(&argv
[idx
][15],NULL
,0);
978 print_apperr("Invalid start sector");
982 else if (! strncmp(argv
[idx
],"--total-sectors=",16))
984 def_tsc
=strtol(&argv
[idx
][16],NULL
,0);
987 print_apperr("Invalid total sectors");
991 else if ((! strncmp(argv
[idx
],"--boot-file=",12)) ||
992 (! strncmp(argv
[idx
],"-b=",3)))
994 if (SetBootFile((argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][12]))
996 print_apperr("Invalid boot file name");
1000 else if (! strncmp(argv
[idx
],"--load-seg=",11))
1002 load_seg
=strtoul(&argv
[idx
][11],NULL
,16);
1003 if (load_seg
<0x1000)
1005 print_apperr("Load address too small");
1009 else if ((! strcmp(argv
[idx
],"--grub2")) ||
1010 (! strcmp(argv
[idx
],"-2")))
1015 strcpy(boot_file_83
,"G2LDR ");
1018 else if ((! strcmp(argv
[idx
],"--output")) ||
1019 (! strcmp(argv
[idx
],"-o")))
1021 else if ((! strcmp(argv
[idx
],"--edit")) ||
1022 (! strcmp(argv
[idx
],"-e")))
1026 print_apperr("Invalid option, please use --help to see all valid options");
1032 print_apperr("No filename specified");
1037 print_apperr("Extra parameters");
1040 return install(parse_fname(argv
[idx
]));