55
55
56
56
static char * target ;
57
57
static int removable = 0 ;
58
+ static int force_extra_removable = 0 ;
58
59
static int recheck = 0 ;
59
60
static int update_nvram = 1 ;
60
61
static char * install_device = NULL ;
109
110
OPTION_LABEL_FONT ,
110
111
OPTION_LABEL_COLOR ,
111
112
OPTION_LABEL_BGCOLOR ,
112
- OPTION_PRODUCT_VERSION
113
+ OPTION_PRODUCT_VERSION ,
114
+ OPTION_FORCE_EXTRA_REMOVABLE ,
113
115
};
114
116
115
117
static int fs_probe = 1 ;
@@ -212,6 +214,10 @@ argp_parser (int key, char *arg, struct argp_state *state)
212
214
removable = 1 ;
213
215
return 0 ;
214
216
217
+ case OPTION_FORCE_EXTRA_REMOVABLE :
218
+ force_extra_removable = 1 ;
219
+ return 0 ;
220
+
215
221
case OPTION_ALLOW_FLOPPY :
216
222
allow_floppy = 1 ;
217
223
return 0 ;
@@ -302,6 +308,9 @@ static struct argp_option options[] = {
302
308
{"label-color" , OPTION_LABEL_COLOR , N_ ("COLOR" ), 0 , N_ ("use COLOR for label" ), 2 },
303
309
{"label-bgcolor" , OPTION_LABEL_BGCOLOR , N_ ("COLOR" ), 0 , N_ ("use COLOR for label background" ), 2 },
304
310
{"product-version" , OPTION_PRODUCT_VERSION , N_ ("STRING" ), 0 , N_ ("use STRING as product version" ), 2 },
311
+ {"force-extra-removable" , OPTION_FORCE_EXTRA_REMOVABLE , 0 , 0 ,
312
+ N_ ("force installation to the removable media path also. "
313
+ "This option is only available on EFI." ), 2 },
305
314
{0 , 0 , 0 , 0 , 0 , 0 }
306
315
};
307
316
@@ -843,12 +852,92 @@ try_open (const char *path)
843
852
}
844
853
#endif
845
854
855
+ /* Helper routine for also_install_removable() below. Walk through the
856
+ specified dir, looking to see if there is a file/dir that matches
857
+ the search string exactly, but in a case-insensitive manner. If so,
858
+ return a copy of the exact file/dir that *does* exist. If not,
859
+ return NULL */
860
+ static char *
861
+ check_component_exists (const char * dir ,
862
+ const char * search )
863
+ {
864
+ grub_util_fd_dir_t d ;
865
+ grub_util_fd_dirent_t de ;
866
+ char * found = NULL ;
867
+
868
+ d = grub_util_fd_opendir (dir );
869
+ if (!d )
870
+ grub_util_error (_ ("cannot open directory `%s': %s" ),
871
+ dir , grub_util_fd_strerror ());
872
+
873
+ while ((de = grub_util_fd_readdir (d )))
874
+ {
875
+ if (strcasecmp (de -> d_name , search ) == 0 )
876
+ {
877
+ found = xstrdup (de -> d_name );
878
+ break ;
879
+ }
880
+ }
881
+ grub_util_fd_closedir (d );
882
+ return found ;
883
+ }
884
+
885
+ /* Some complex directory-handling stuff in here, to cope with
886
+ * case-insensitive FAT/VFAT filesystem semantics. Ugh. */
887
+ static void
888
+ also_install_removable (const char * src ,
889
+ const char * base_efidir ,
890
+ const char * efi_file )
891
+ {
892
+ char * dst = NULL ;
893
+ char * cur = NULL ;
894
+ char * found = NULL ;
895
+
896
+ /* We need to install in $base_efidir/EFI/BOOT/$efi_file, but we
897
+ * need to cope with case-insensitive stuff here. Build the path one
898
+ * component at a time, checking for existing matches each time. */
899
+
900
+ /* Look for "EFI" in base_efidir. Make it if it does not exist in
901
+ * some form. */
902
+ found = check_component_exists (base_efidir , "EFI" );
903
+ if (found == NULL )
904
+ found = xstrdup ("EFI" );
905
+ dst = grub_util_path_concat (2 , base_efidir , found );
906
+ cur = xstrdup (dst );
907
+ free (dst );
908
+ free (found );
909
+ grub_install_mkdir_p (cur );
910
+
911
+ /* Now BOOT */
912
+ found = check_component_exists (cur , "BOOT" );
913
+ if (found == NULL )
914
+ found = xstrdup ("BOOT" );
915
+ dst = grub_util_path_concat (2 , cur , found );
916
+ cur = xstrdup (dst );
917
+ free (dst );
918
+ free (found );
919
+ grub_install_mkdir_p (cur );
920
+
921
+ /* Now $efi_file */
922
+ found = check_component_exists (cur , efi_file );
923
+ if (found == NULL )
924
+ found = xstrdup (efi_file );
925
+ dst = grub_util_path_concat (2 , cur , found );
926
+ cur = xstrdup (dst );
927
+ free (dst );
928
+ free (found );
929
+ grub_install_copy_file (src , cur , 1 );
930
+
931
+ free (cur );
932
+ }
933
+
846
934
int
847
935
main (int argc , char * argv [])
848
936
{
849
937
int is_efi = 0 ;
850
938
const char * efi_distributor = NULL ;
851
939
const char * efi_file = NULL ;
940
+ const char * removeable_efi_file = NULL ;
852
941
char * * grub_devices ;
853
942
grub_fs_t grub_fs ;
854
943
grub_device_t grub_dev = NULL ;
@@ -859,6 +948,7 @@ main (int argc, char *argv[])
859
948
char * relative_grubdir ;
860
949
char * * efidir_device_names = NULL ;
861
950
grub_device_t efidir_grub_dev = NULL ;
951
+ char * base_efidir = NULL ;
862
952
char * efidir_grub_devname ;
863
953
int efidir_is_mac = 0 ;
864
954
int is_prep = 0 ;
@@ -891,6 +981,9 @@ main (int argc, char *argv[])
891
981
bootloader_id = xstrdup ("grub" );
892
982
}
893
983
984
+ if (removable && force_extra_removable )
985
+ grub_util_error (_ ("Invalid to use both --removable and --force_extra_removable" ));
986
+
894
987
if (!grub_install_source_directory )
895
988
{
896
989
if (!target )
@@ -1141,6 +1234,8 @@ main (int argc, char *argv[])
1141
1234
grub_util_error (_ ("%s doesn't look like an EFI partition" ), efidir );
1142
1235
}
1143
1236
1237
+ base_efidir = xstrdup (efidir );
1238
+
1144
1239
/* The EFI specification requires that an EFI System Partition must
1145
1240
contain an "EFI" subdirectory, and that OS loaders are stored in
1146
1241
subdirectories below EFI. Vendors are expected to pick names that do
@@ -1149,14 +1244,17 @@ main (int argc, char *argv[])
1149
1244
*/
1150
1245
char * t ;
1151
1246
efi_distributor = bootloader_id ;
1152
- if (removable )
1247
+ if (removable || force_extra_removable )
1153
1248
{
1154
1249
/* The specification makes stricter requirements of removable
1155
1250
devices, in order that only one image can be automatically loaded
1156
1251
from them. The image must always reside under /EFI/BOOT, and it
1157
1252
must have a specific file name depending on the architecture.
1158
1253
*/
1159
- efi_distributor = "BOOT" ;
1254
+ if (removable )
1255
+ {
1256
+ efi_distributor = "BOOT" ;
1257
+ }
1160
1258
switch (platform )
1161
1259
{
1162
1260
case GRUB_INSTALL_PLATFORM_I386_EFI :
@@ -1187,8 +1285,12 @@ main (int argc, char *argv[])
1187
1285
grub_util_error ("%s" , _ ("You've found a bug" ));
1188
1286
break ;
1189
1287
}
1288
+ if (force_extra_removable )
1289
+ {
1290
+ removeable_efi_file = efi_file ;
1291
+ }
1190
1292
}
1191
- else
1293
+ if (! removable )
1192
1294
{
1193
1295
/* It is convenient for each architecture to have a different
1194
1296
efi_file, so that different versions can be installed in parallel.
@@ -1989,6 +2091,9 @@ main (int argc, char *argv[])
1989
2091
char * dst = grub_util_path_concat (2 , efidir , efi_file );
1990
2092
grub_install_copy_file (imgfile , dst , 1 );
1991
2093
2094
+ if (force_extra_removable )
2095
+ also_install_removable (imgfile , base_efidir , removeable_efi_file );
2096
+
1992
2097
grub_set_install_backup_ponr ();
1993
2098
1994
2099
free (dst );
0 commit comments