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.
37 // Application flags, used by this program
41 #define AFG_READ_ONLY 4
42 #define AFG_NO_BACKUP_MBR 8
43 #define AFG_FORCE_BACKUP_MBR 16
44 #define AFG_RESTORE_PREVMBR 32
45 #define AFG_LIST_PART 64
46 #define AFG_IS_FLOPPY 128
47 #define AFG_LBA_MODE 256
48 #define AFG_CHS_MODE 512
49 #define AFG_OUTPUT 1024
52 // Grldr flags, this flag is used by grldr.mbr
54 #define GFG_DISABLE_FLOPPY 1
55 #define GFG_DISABLE_OSBR 2
57 #define GFG_PREVMBR_LAST 128
59 #define APP_NAME "grubinst: "
61 #define print_pause if (afg & AFG_PAUSE) {fputs("Press <ENTER> to continue ...\n",stderr); fflush(stderr); fgetc(stdin);}
63 #define print_apperr(a) { fprintf(stderr,APP_NAME "%s\n",a); print_pause; }
64 #define print_syserr(a) { perror(APP_NAME a); print_pause; }
69 "\tgrubinst [OPTIONS] DEVICE_OR_FILE\n\n"
71 "\t--help,-h\t\tShow usage information\n\n"
72 "\t--pause\t\t\tPause before exiting\n\n"
73 "\t--version\t\tShow version information\n\n"
74 "\t--verbose,-v\t\tVerbose output\n\n"
75 "\t--list-part,-l\t\tList all logical partitions in DEVICE_OR_FILE\n\n"
76 "\t--save=FN,-s=FN\t\tSave the orginal MBR/BS to FN\n\n"
77 "\t--restore=FN,-r=FN\tRestore MBR/BS from previously saved FN\n\n"
78 "\t--restore-prevmbr,-r\tRestore previous MBR saved in the second sector\n"
79 "\t\t\t\tof DEVICE_OR_FILE\n\n"
80 "\t--read-only,-t\t\tdo everything except the actual write to the\n"
81 "\t\t\t\tspecified DEVICE_OR_FILE. (test mode)\n\n"
82 "\t--no-backup-mbr\t\tdo not copy the old MBR to the second sector of\n"
83 "\t\t\t\tDEVICE_OR_FILE.\n\n"
84 "\t--force-backup-mbr\tforce the copy of old MBR to the second sector\n"
85 "\t\t\t\tof DEVICE_OR_FILE.(default)\n\n"
86 "\t--mbr-enable-floppy\tenable the search for GRLDR on floppy.(default)\n\n"
87 "\t--mbr-disable-floppy\tdisable the search for GRLDR on floppy.\n\n"
88 "\t--mbr-enable-osbr\tenable the boot of PREVIOUS MBR with invalid\n"
89 "\t\t\t\tpartition table (usually an OS boot sector).\n"
90 "\t\t\t\t(default)\n\n"
91 "\t--mbr-disable-osbr\tdisable the boot of PREVIOUS MBR with invalid\n"
92 "\t\t\t\tpartition table (usually an OS boot sector).\n\n"
93 "\t--duce\t\t\tdisable the feature of unconditional entrance\n"
94 "\t\t\t\tto the command-line.\n\n"
95 "\t--boot-prevmbr-first\ttry to boot PREVIOUS MBR before the search for\n"
97 "\t--boot-prevmbr-last\ttry to boot PREVIOUS MBR after the search for\n"
98 "\t\t\t\tGRLDR.(default)\n\n"
99 "\t--preferred-drive=D\tpreferred boot drive number, 0 <= D < 255.\n\n"
100 "\t--preferred-partition=P\tpreferred partition number, 0 <= P < 255.\n\n"
101 "\t--time-out=T,-t=T\twait T seconds before booting PREVIOUS MBR. if\n"
102 "\t\t\t\tT is 0xff, wait forever. The default is 5.\n\n"
103 "\t\t\t\tbefore booting PREVIOUS MBR. K is a word\n"
104 "\t\t\t\tvalue, just as the value in AX register\n"
105 "\t\t\t\treturned from int16/AH=1. The high byte is the\n"
106 "\t\t\t\tscan code and the low byte is ASCII code. The\n"
107 "\t\t\t\tdefault is 0x3920 for space bar.\n\n"
108 "\t--key-name=S\t\tSpecify the name of the hot key.\n\n"
109 "\t--floppy,-f\t\tif DEVICE_OR_FILE is floppy, use this option.\n\n"
110 "\t--floppy=N\t\tif DEVICE_OR_FILE is a partition on a hard\n"
111 "\t\t\t\tdrive, use this option. N is used to specify\n"
112 "\t\t\t\tthe partition number: 0,1,2 and 3 for the\n"
113 "\t\t\t\tprimary partitions, and 4,5,6,... for the\n"
114 "\t\t\t\tlogical partitions.\n\n"
115 "\t--sectors-per-track=S\tspecifies sectors per track for --floppy.\n"
116 "\t\t\t\t1 <= S <= 63, default is 63.\n\n"
117 "\t--heads=H\t\tspecifies number of heads for --floppy.\n"
118 "\t\t\t\t1 <= H <= 256, default is 255.\n\n"
119 "\t--start-sector=B\tspecifies hidden sectors for --floppy=N.\n\n"
120 "\t--total-sectors=C\tspecifies total sectors for --floppy.\n"
121 "\t\t\t\tdefault is 0.\n\n"
122 "\t--lba\t\t\tuse lba mode for --floppy. If the floppy BIOS\n"
123 "\t\t\t\thas LBA support, you can specify --lba here.\n"
124 "\t\t\t\tIt is assumed that all floppy BIOSes have CHS\n"
125 "\t\t\t\tsupport. So you would rather specify --chs.\n"
126 "\t\t\t\tIf neither --chs nor --lba is specified, then\n"
127 "\t\t\t\tthe LBA indicator(i.e., the third byte of the\n"
128 "\t\t\t\tboot sector) will not be touched.\n\n"
129 "\t--chs\t\t\tuse chs mode for --floppy. You should specify\n"
130 "\t\t\t\t--chs if the floppy BIOS does not support LBA.\n"
131 "\t\t\t\tWe assume all floppy BIOSes have CHS support.\n"
132 "\t\t\t\tSo it is likely you want to specify --chs.\n"
133 "\t\t\t\tIf neither --chs nor --lba is specified, then\n"
134 "\t\t\t\tthe LBA indicator(i.e., the third byte of the\n"
135 "\t\t\t\tboot sector) will not be touched.\n\n"
136 "\t--install-partition=I\tInstall the boot record onto the boot area of\n"
137 "\t-p=I\t\t\tpartition number I of the specified hard drive\n"
138 "\t\t\t\tor harddrive image DEVICE_OR_FILE.\n\n"
139 "\t--boot-file=F,-b=F\tChange the name of boot file.\n\n"
140 "\t--load-seg=S\t\tChange load segment for boot file.\n\n"
141 "\t--grub2,-2\t\tLoad grub2 kernel g2ldr instead of grldr.\n\n"
142 "\t--output,-o\t\tSave embeded grldr.mbr to DEVICE_OR_FILE.\n\n"
143 "\t--edit,-e\t\tEdit external grldr/grldr.mbr.\n",
147 int afg
,gfg
,def_drive
,def_part
,time_out
,hot_key
,part_num
;
148 int def_spt
,def_hds
,def_ssc
,def_tsc
;
149 char *save_fn
,*restore_fn
,*boot_file
,boot_file_83
[12],*key_name
;
150 unsigned short load_seg
;
152 static char fn_buf
[24];
154 char* get_disk_name(int n
)
157 sprintf(fn_buf
,"\\\\.\\PhysicalDrive%d",n
);
159 sprintf(fn_buf
,"/dev/hd%c",'a'+n
);
160 #elif defined(FREEBSD)
161 sprintf(fn_buf
,"/dev/ad%d",n
);
163 print_apperr("Disk device is not supported in your system");
169 char* get_flop_name(int n
)
174 print_apperr("Only two floppy drives are supported");
177 sprintf(fn_buf
,"\\\\.\\%c:",'A'+n
);
178 #elif defined(LINUX) || defined(FREEBSD)
179 sprintf(fn_buf
,"/dev/fd%d",n
);
181 print_apperr("Floppy device is not supported in your system");
187 char* parse_fname(char* fn
)
189 if ((afg
& AFG_OUTPUT
) && (fn
[0]=='('))
191 print_apperr("Can\'t use device name while using --output option");
194 if ((! strncmp(fn
,"(hd",3)) || (! strncmp(fn
,"(fd",3)))
199 n
=strtol(&fn
[3],&p
,0);
200 if ((n
<0) || (n
>=MAX_DISKS
))
202 print_apperr("Invalid device number");
207 part_num
=strtol(p
+1,&p
,0);
208 if ((part_num
<0) || (part_num
>=MAX_PARTS
))
210 print_apperr("Invalid partition number");
214 if ((*p
!=')') || (*(p
+1)!=0))
216 print_apperr("Invalid device name");
230 char* str_upcase(char* str
)
235 if ((str
[i
]>='a') && (str
[i
]<='z'))
241 char* str_lowcase(char* str
)
246 if ((str
[i
]>='A') && (str
[i
]<='Z'))
252 int SetBootFile(char* fn
)
262 if ((pc
==fn
) || (pc
-fn
>8) || (strlen(pc
+1)>3))
265 memset(boot_file_83
,' ',sizeof(boot_file_83
)-1);
268 memcpy(boot_file_83
,fn
,pc
-fn
);
269 memcpy(&boot_file_83
[8],pc
+1,strlen(pc
+1));
272 memcpy(boot_file_83
,fn
,strlen(fn
));
278 int chk_mbr(unsigned char* buf
);
285 fprintf(stderr
," # id base leng\n");
286 while (! xd_enum(hd
,&xe
))
287 fprintf(stderr
,"%2d %02X %8X %8X\n",xe
.cur
,xe
.dfs
,xe
.bse
,xe
.len
);
290 int is_grldr_mbr(char* buf
)
295 n
=sizeof("Missing MBR-helper.")-1;
297 while ((i
>n
) && (buf
[i
]==0))
299 return (! strcmp(&buf
[i
-n
+1],"Missing MBR-helper."));
302 int install(char* fn
)
305 char prev_mbr
[sizeof(grub_mbr
)];
313 unsigned short r1
,r2
;
315 if (afg
& AFG_VERBOSE
)
316 fprintf(stderr
,"Edit mode\n");
317 hd
=open(fn
,O_RDWR
| O_BINARY
,0644);
320 print_syserr("open");
323 r1
=valueat(grub_mbr
[0x1FFA],0,unsigned short);
324 nn
=read(hd
,grub_mbr
,sizeof(grub_mbr
));
327 print_syserr("read");
331 if (nn
<sizeof(grub_mbr
))
333 print_apperr("The input file is too short");
337 if (valueat(grub_mbr
[0x1FFC],0,unsigned long)!=0xAA555247)
339 print_apperr("Invalid input file");
343 r2
=valueat(grub_mbr
[0x1FFA],0,unsigned short);
348 sprintf(buf
,"Version number mismatched (old=%d new=%d)",r2
,r1
);
359 unsigned short ofs
,len
;
361 // Patching the FAT32 boot sector
362 ofs
=valueat(grub_mbr
,0x400+0x1EC,unsigned short) & 0x7FF;
363 strcpy(&grub_mbr
[0x400+ofs
],boot_file_83
);
365 valueat(grub_mbr
,0x400+0x1EA,unsigned short)=load_seg
;
367 // Patching the FAT12/FAT16 boot sector
368 ofs
=valueat(grub_mbr
,0x600+0x1EC,unsigned short) & 0x7FF;
369 strcpy(&grub_mbr
[0x600+ofs
],boot_file_83
);
371 valueat(grub_mbr
,0x600+0x1EA,unsigned short)=load_seg
;
373 // Patching the EXT2 boot sector
374 ofs
=valueat(grub_mbr
,0x800+0x1EE,unsigned short) & 0x7FF;
375 strcpy(&grub_mbr
[0x800+ofs
],boot_file
);
377 // Patching the NTFS sector
378 ofs
=valueat(grub_mbr
,0xA00+0x1EC,unsigned short) & 0x7FF;
379 strcpy(&grub_mbr
[0xA00+ofs
],boot_file
);
381 valueat(grub_mbr
,0xA00+0x1EA,unsigned short)=load_seg
;
383 if (afg
& AFG_VERBOSE
)
385 fprintf(stderr
,"Boot file changed to %s\n",boot_file
);
387 fprintf(stderr
,"Load segment changed to %04X\n",load_seg
);
391 if (afg
& AFG_OUTPUT
)
395 mode
=(! (afg
& AFG_READ_ONLY
))?(O_TRUNC
| O_CREAT
):0;
396 if (! (afg
& AFG_EDIT
))
398 if (afg
& AFG_VERBOSE
)
399 fprintf(stderr
,"Extract mode\n");
400 hd
=open(fn
,O_RDWR
| O_BINARY
| mode
,0644);
403 print_syserr("open");
407 if (! (afg
& AFG_READ_ONLY
))
408 if (write(hd
,grub_mbr
,sizeof(grub_mbr
))!=sizeof(grub_mbr
))
410 print_apperr("Write to output file fails");
417 memset(&grub_mbr
[512],0,512);
418 valueat(grub_mbr
,2,unsigned char)=gfg
;
419 valueat(grub_mbr
,3,unsigned char)=time_out
;
420 valueat(grub_mbr
,4,unsigned short)=hot_key
;
421 valueat(grub_mbr
,6,unsigned char)=def_drive
;
422 valueat(grub_mbr
,7,unsigned char)=def_part
;
423 if ((key_name
==NULL
) && (hot_key
==0x3920))
426 strcpy(&grub_mbr
[0x1fec],key_name
);
428 hd
=open(fn
,O_RDWR
| O_BINARY
,S_IREAD
| S_IWRITE
);
431 print_syserr("open");
434 if (afg
& AFG_LIST_PART
)
452 print_apperr("Partition not found");
457 if (afg
& AFG_VERBOSE
)
458 fprintf(stderr
,"Part Fs: %02X (%s)\nPart Leng: %u\n",xe
.dfs
,dfs2str(xe
.dfs
),xe
.len
);
463 if (afg
& AFG_VERBOSE
)
464 fprintf(stderr
,"Start sector: %u\n",ssec
);
465 if ((ssec
) && (go_sect(hd
,ssec
)))
467 print_apperr("Can\'t seek to the start sector");
471 nn
=read(hd
,prev_mbr
,sizeof(prev_mbr
));
474 print_syserr("read");
478 if (nn
<sizeof(prev_mbr
))
480 print_apperr("The input file is too short");
484 fs
=get_fstype(prev_mbr
);
485 if (afg
& AFG_VERBOSE
)
487 fprintf(stderr
,"Image type: %s\n",fst2str(fs
));
489 fprintf(stderr
,"Num of heads: %d\nSectors per track: %d\n",mbr_nhd
,mbr_spt
);
493 print_apperr("Unknown image type");
497 if (((part_num
!=-1) || (afg
& AFG_IS_FLOPPY
)) && (fs
==FST_MBR
))
499 print_apperr("Should be a file system image");
503 if ((part_num
==-1) && ((afg
& AFG_IS_FLOPPY
)==0) && (fs
!=FST_MBR
))
505 print_apperr("Should be a disk image");
516 for (n
=0x1BE;n
<0x1FE;n
+=16)
519 if (ofs
>valueat(prev_mbr
[n
],8,unsigned long))
520 ofs
=valueat(prev_mbr
[n
],8,unsigned long);
522 if (ofs
<(sizeof(prev_mbr
)>>9))
524 print_apperr("Not enough room to install mbr");
528 slen
=sizeof(prev_mbr
);
531 print_apperr("Can\'t seek to the first partition");
535 if (read(hd
,bs
,sizeof(bs
))!=sizeof(bs
))
537 print_apperr("Fail to read boot sector");
544 else if (nfs
==FST_FAT16
)
550 memcpy(&grub_mbr
[0xB],&bs
[0xB],sln
);
551 valueat(grub_mbr
[0],0x1C,unsigned long)=0;
552 valueat(grub_mbr
[0],0xE,unsigned short)+=ofs
;
555 else if (fs
==FST_NTFS
)
560 if (go_sect(hd
,ssec
))
562 print_apperr("Can\'t seek to the start sector");
571 h2
=open(save_fn
,O_CREAT
| O_TRUNC
| O_RDWR
| O_BINARY
,S_IREAD
| S_IWRITE
);
574 print_syserr("open save file");
578 nn
=write(h2
,prev_mbr
,slen
);
581 print_syserr("write save file");
588 print_apperr("Can\'t write the whole MBR to the save file");
595 if (afg
& AFG_RESTORE_PREVMBR
)
599 print_apperr("Not a disk image");
603 if (strncmp(&prev_mbr
[1024+3],"GRLDR",5))
605 print_apperr("GRLDR is not installed");
609 if (valueat(prev_mbr
,512+510,unsigned short)!=0xAA55)
611 print_apperr("No previous saved MBR");
615 memset(&grub_mbr
,0,sizeof(grub_mbr
));
616 memcpy(&grub_mbr
,&prev_mbr
[512],512);
617 memcpy(&grub_mbr
[0x1b8],&prev_mbr
[0x1b8],72);
619 if (afg
& AFG_VERBOSE
)
620 fprintf(stderr
,"Restore previous MBR mode\n");
624 // Load MBR/BS from restore file or configure grub_mbr
629 h2
=open(restore_fn
,O_RDONLY
| O_BINARY
,S_IREAD
);
632 print_syserr("open restore file");
636 nn
=read(h2
,grub_mbr
,slen
);
639 print_syserr("read restore file");
644 if ((nn
<512) || (nn
& 0x1FF!=0) ||
645 (fs
!=FST_EXT2
) && (valueat(grub_mbr
,510,unsigned short)!=0xAA55))
647 print_apperr("Invalid restore file");
654 memset(&grub_mbr
[nn
],0,slen
-nn
);
656 //if ((fs==FST_FAT16) || (fs==FST_FAT32) || (fs==FST_NTFS))
661 new_fs
=get_fstype(grub_mbr
);
664 print_apperr("Invalid restore file");
670 if (afg
& AFG_VERBOSE
)
671 fprintf(stderr
,"Restore mode\n");
677 if (! (afg
& AFG_NO_BACKUP_MBR
))
681 if (afg
& AFG_FORCE_BACKUP_MBR
)
685 if (prev_mbr
[512+i
]!=prev_mbr
[512])
688 if ((i
==512) && (! is_grldr_mbr(prev_mbr
)))
689 memcpy(&grub_mbr
[512],prev_mbr
,512);
691 memcpy(&grub_mbr
[512],&prev_mbr
[512],512);
693 memcpy(&grub_mbr
[0x1b8],&prev_mbr
[0x1b8],72);
695 else if (fs
==FST_FAT16
)
697 memcpy(grub_mbr
,&grub_mbr
[0x600],slen
);
698 grub_mbr
[0x41]=part_num
;
700 else if (fs
==FST_FAT32
)
702 memcpy(grub_mbr
,&grub_mbr
[0x400],slen
);
703 grub_mbr
[0x5D]=part_num
;
705 else if (fs
==FST_NTFS
)
707 memcpy(grub_mbr
,&grub_mbr
[0xA00],slen
);
708 grub_mbr
[0x57]=part_num
;
710 else if (fs
==FST_EXT2
)
712 memcpy(grub_mbr
,&grub_mbr
[0x800],slen
);
713 grub_mbr
[0x25]=part_num
;
714 if (afg
& AFG_LBA_MODE
)
716 else if (afg
& AFG_CHS_MODE
)
719 valueat(grub_mbr
,0x18,unsigned short)=def_spt
;
720 else if ((afg
& AFG_IS_FLOPPY
)==0)
721 valueat(grub_mbr
,0x18,unsigned short)=63;
723 valueat(grub_mbr
,0x1A,unsigned short)=def_hds
;
724 else if ((afg
& AFG_IS_FLOPPY
)==0)
725 valueat(grub_mbr
,0x1A,unsigned short)=255;
727 valueat(grub_mbr
,0x20,unsigned long)=def_tsc
;
728 valueat(grub_mbr
,0x1C,unsigned long)=ssec
;
729 // s_inodes_per_group
730 valueat(grub_mbr
,0x28,unsigned long)=valueat(prev_mbr
[1024],0x28,unsigned long);
731 // s_first_data_block+1
732 valueat(grub_mbr
,0x2C,unsigned long)=valueat(prev_mbr
[1024],0x14,unsigned long)+1;
737 print_apperr("Invalid file system");
741 if ((fs
==FST_FAT16
) || (fs
==FST_FAT32
) || (fs
==FST_NTFS
))
743 if (afg
& AFG_LBA_MODE
)
745 else if (afg
& AFG_CHS_MODE
)
748 grub_mbr
[2]=prev_mbr
[2];
751 if (afg
& AFG_VERBOSE
)
752 fprintf(stderr
,"Install mode\n");
754 // Patch the new MBR/BS with information from prev_mbr
756 memcpy(&grub_mbr
[0x1b8],&prev_mbr
[0x1b8],72);
757 else if (fs
==FST_FAT16
)
759 memcpy(&grub_mbr
[0xB],&prev_mbr
[0xB],0x3E - 0xB);
760 valueat(grub_mbr
,0x1C,unsigned long)=ssec
;
762 else if (fs
==FST_FAT32
)
764 memcpy(&grub_mbr
[0xB],&prev_mbr
[0xB],0x5A - 0xB);
765 valueat(grub_mbr
,0x1C,unsigned long)=ssec
;
767 else if (fs
==FST_NTFS
)
769 memcpy(&grub_mbr
[0xB],&prev_mbr
[0xB],0x54 - 0xB);
770 valueat(grub_mbr
,0x1C,unsigned long)=ssec
;
773 if (! (afg
& AFG_READ_ONLY
))
775 nn
=write(hd
,grub_mbr
,slen
);
778 print_syserr("write");
784 print_apperr("Can\'t write the whole mbr");
789 else if (afg
& AFG_VERBOSE
)
790 fprintf(stderr
,"Read only mode\n");
795 fputs("The MBR/BS has been successfully installed\n",stderr
);
801 int main(int argc
,char** argv
)
806 part_num
=def_drive
=def_part
=def_spt
=def_hds
=def_ssc
=def_tsc
=-1;
808 gfg
=GFG_PREVMBR_LAST
;
813 for (idx
=1;idx
<argc
;idx
++)
815 if (argv
[idx
][0]!='-')
817 if ((! strcmp(argv
[idx
],"--help"))
818 || (! strcmp(argv
[idx
],"-h")))
824 else if (! strcmp(argv
[idx
],"--version"))
826 fprintf(stderr
,"grubinst version : " VERSION
"\n");
830 else if ((! strcmp(argv
[idx
],"--verbose")) ||
831 (! strcmp(argv
[idx
],"-v")))
833 else if (! strcmp(argv
[idx
],"--pause"))
835 else if ((! strcmp(argv
[idx
],"--read-only"))
836 || (! strcmp(argv
[idx
],"-t")))
838 else if (! strcmp(argv
[idx
],"--no-backup-mbr"))
839 afg
|=AFG_NO_BACKUP_MBR
;
840 else if (! strcmp(argv
[idx
],"--force-backup-mbr"))
841 afg
|=AFG_FORCE_BACKUP_MBR
;
842 else if (! strcmp(argv
[idx
],"--mbr-enable-floppy"))
843 gfg
&=~GFG_DISABLE_FLOPPY
;
844 else if (! strcmp(argv
[idx
],"--mbr-disable-floppy"))
845 gfg
|=GFG_DISABLE_FLOPPY
;
846 else if (! strcmp(argv
[idx
],"--mbr-enable-osbr"))
847 gfg
&=~GFG_DISABLE_OSBR
;
848 else if (! strcmp(argv
[idx
],"--mbr-disable-osbr"))
849 gfg
|=GFG_DISABLE_OSBR
;
850 else if (! strcmp(argv
[idx
],"--duce"))
852 else if (! strcmp(argv
[idx
],"--boot-prevmbr-first"))
853 gfg
&=~GFG_PREVMBR_LAST
;
854 else if (! strcmp(argv
[idx
],"--boot-prevmbr-last"))
855 gfg
|=GFG_PREVMBR_LAST
;
856 else if (! strncmp(argv
[idx
],"--preferred-drive=",18))
858 def_drive
=strtol(&argv
[idx
][18],NULL
,0);
859 if ((def_drive
<0) || (def_drive
>=255))
861 print_apperr("Invalid preferred drive number");
865 else if (! strncmp(argv
[idx
],"--preferred-partition=",22))
867 def_part
=strtol(&argv
[idx
][22],NULL
,0);
868 if ((def_part
<0) || (def_part
>=255))
870 print_apperr("Invalid preferred partition number");
874 else if ((! strncmp(argv
[idx
],"--time-out=",11)) ||
875 (! strncmp(argv
[idx
],"-t=",3)))
877 time_out
=strtol((argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][11],NULL
,0);
878 if ((time_out
<0) || (time_out
>255))
880 print_apperr("Invalid timeout value");
884 else if ((! strncmp(argv
[idx
],"--key-name=",11)))
886 key_name
=&argv
[idx
][11];
887 if (strlen(key_name
)>13)
889 print_apperr("Key name too long");
893 else if ((! strcmp(argv
[idx
],"--restore-prevmbr")) ||
894 (! strcmp(argv
[idx
],"-r")))
895 afg
|=AFG_RESTORE_PREVMBR
;
896 else if ((! strncmp(argv
[idx
],"--save=",7)) ||
897 (! strncmp(argv
[idx
],"-s=",3)))
899 save_fn
=(argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][7];
902 print_apperr("Empty filename");
906 else if ((! strncmp(argv
[idx
],"--restore=",10)) ||
907 (! strncmp(argv
[idx
],"-r=",3)))
909 restore_fn
=(argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][10];
912 print_apperr("Empty filename");
916 else if ((! strcmp(argv
[idx
],"--list-part")) ||
917 (! strcmp(argv
[idx
],"-l")))
919 else if ((! strcmp(argv
[idx
],"--floppy")) ||
920 (! strcmp(argv
[idx
],"-f")))
922 else if ((! strncmp(argv
[idx
],"--floppy=",9)) ||
923 (! strncmp(argv
[idx
],"--install-partition=",20)) ||
924 (! strncmp(argv
[idx
],"-p=",3)))
928 if (argv
[idx
][2]=='f')
930 else if (argv
[idx
][2]=='i')
934 part_num
=strtoul(p
,NULL
,0);
935 if ((part_num
<0) || (part_num
>=MAX_PARTS
))
937 print_apperr("Invalid partition number");
941 else if (! strcmp(argv
[idx
],"--lba"))
943 else if (! strcmp(argv
[idx
],"--chs"))
945 else if (! strncmp(argv
[idx
],"--sectors-per-track=",20))
947 def_spt
=strtol(&argv
[idx
][10],NULL
,0);
948 if ((def_spt
<1) || (def_spt
>63))
950 print_apperr("Invalid sector per track");
954 else if (! strncmp(argv
[idx
],"--heads=",8))
956 def_hds
=strtol(&argv
[idx
][8],NULL
,0);
957 if ((def_hds
<1) || (def_hds
>255))
959 print_apperr("Invalid number of heads");
963 else if (! strncmp(argv
[idx
],"--start-sector=",15))
965 def_spt
=strtol(&argv
[idx
][15],NULL
,0);
968 print_apperr("Invalid start sector");
972 else if (! strncmp(argv
[idx
],"--total-sectors=",16))
974 def_tsc
=strtol(&argv
[idx
][16],NULL
,0);
977 print_apperr("Invalid total sectors");
981 else if ((! strncmp(argv
[idx
],"--boot-file=",12)) ||
982 (! strncmp(argv
[idx
],"-b=",3)))
984 if (SetBootFile((argv
[idx
][2]=='=')?&argv
[idx
][3]:&argv
[idx
][12]))
986 print_apperr("Invalid boot file name");
990 else if (! strncmp(argv
[idx
],"--load-seg=",11))
992 load_seg
=strtoul(&argv
[idx
][11],NULL
,16);
995 print_apperr("Load address too small");
999 else if ((! strcmp(argv
[idx
],"--grub2")) ||
1000 (! strcmp(argv
[idx
],"-2")))
1005 strcpy(boot_file_83
,"G2LDR ");
1008 else if ((! strcmp(argv
[idx
],"--output")) ||
1009 (! strcmp(argv
[idx
],"-o")))
1011 else if ((! strcmp(argv
[idx
],"--edit")) ||
1012 (! strcmp(argv
[idx
],"-e")))
1016 print_apperr("Invalid option, please use --help to see all valid options");
1022 print_apperr("No filename specified");
1027 print_apperr("Extra parameters");
1030 return install(parse_fname(argv
[idx
]));