mirror of
				https://git.proxmox.com/git/grub2
				synced 2025-10-31 05:04:05 +00:00 
			
		
		
		
	 5082ea6184
			
		
	
	
		5082ea6184
		
	
	
	
	
		
			
			grub_util_{info,warn,error} already add trailing newlines, so remove
them from format strings. Also trailing full stops are already added.
		
	
			
		
			
				
	
	
		
			222 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			222 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|   * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013  Free Software Foundation, Inc.
 | |
|   *
 | |
|   * GRUB is free software: you can redistribute it and/or modify
 | |
|   * it under the terms of the GNU General Public License as published by
 | |
|   * the Free Software Foundation, either version 3 of the License, or
 | |
|   * (at your option) any later version.
 | |
|   *
 | |
|   * GRUB is distributed in the hope that it will be useful,
 | |
|   * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|   * GNU General Public License for more details.
 | |
|   *
 | |
|   * You should have received a copy of the GNU General Public License
 | |
|   * along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
 | |
| */
 | |
| 
 | |
| #include <config.h>
 | |
| 
 | |
| #include <grub/util/install.h>
 | |
| #include <grub/emu/config.h>
 | |
| #include <grub/util/misc.h>
 | |
| 
 | |
| #include <string.h>
 | |
| #include <errno.h>
 | |
| 
 | |
| #pragma GCC diagnostic ignored "-Wmissing-prototypes"
 | |
| #pragma GCC diagnostic ignored "-Wmissing-declarations"
 | |
| #include <argp.h>
 | |
| #pragma GCC diagnostic error "-Wmissing-prototypes"
 | |
| #pragma GCC diagnostic error "-Wmissing-declarations"
 | |
| 
 | |
| static char *rootdir = NULL, *subdir = NULL;
 | |
| static char *debug_image = NULL;
 | |
| 
 | |
| enum
 | |
|   {
 | |
|     OPTION_NET_DIRECTORY = 0x301,
 | |
|     OPTION_SUBDIR,
 | |
|     OPTION_DEBUG,
 | |
|     OPTION_DEBUG_IMAGE
 | |
|   };
 | |
| 
 | |
| static struct argp_option options[] = {
 | |
|   GRUB_INSTALL_OPTIONS,
 | |
|   {"net-directory", OPTION_NET_DIRECTORY, N_("DIR"),
 | |
|    0, N_("root directory of TFTP server"), 2},
 | |
|   {"subdir", OPTION_SUBDIR, N_("DIR"),
 | |
|    0, N_("relative subdirectory on network server"), 2},
 | |
|   {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
 | |
|   {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
 | |
|   {0, 0, 0, 0, 0, 0}
 | |
| };
 | |
| 
 | |
| static error_t 
 | |
| argp_parser (int key, char *arg, struct argp_state *state)
 | |
| {
 | |
|   if (grub_install_parse (key, arg))
 | |
|     return 0;
 | |
|   switch (key)
 | |
|     {
 | |
|     case OPTION_NET_DIRECTORY:
 | |
|       free (rootdir);
 | |
|       rootdir = xstrdup (arg);
 | |
|       return 0;
 | |
|     case OPTION_SUBDIR:
 | |
|       free (subdir);
 | |
|       subdir = xstrdup (arg);
 | |
|       return 0;
 | |
|       /* This is an undocumented feature...  */
 | |
|     case OPTION_DEBUG:
 | |
|       verbosity++;
 | |
|       return 0;
 | |
|     case OPTION_DEBUG_IMAGE:
 | |
|       free (debug_image);
 | |
|       debug_image = xstrdup (arg);
 | |
|       return 0;
 | |
| 
 | |
|     case ARGP_KEY_ARG:
 | |
|     default:
 | |
|       return ARGP_ERR_UNKNOWN;
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| struct argp argp = {
 | |
|   options, argp_parser, NULL,
 | |
|   "\v"N_("Prepares GRUB network boot images at net_directory/subdir "
 | |
| 	 "assuming net_directory being TFTP root."), 
 | |
|   NULL, grub_install_help_filter, NULL
 | |
| };
 | |
| 
 | |
| static char *base;
 | |
| 
 | |
| static const struct
 | |
| {
 | |
|   const char *mkimage_target;
 | |
|   const char *netmodule;
 | |
|   const char *ext;
 | |
| } targets[GRUB_INSTALL_PLATFORM_MAX] =
 | |
|   {
 | |
|     [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" },
 | |
|     [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" },
 | |
|     [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" },
 | |
|     [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" },
 | |
|     [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" },
 | |
|     [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" },
 | |
|     [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" },
 | |
|     [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }
 | |
|   };
 | |
| 
 | |
| static void
 | |
| process_input_dir (const char *input_dir, enum grub_install_plat platform)
 | |
| {
 | |
|   char *platsub = grub_install_get_platform_name (platform);
 | |
|   char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub);
 | |
|   char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg");
 | |
|   char *prefix;
 | |
|   char *output;
 | |
|   char *grub_cfg;
 | |
|   FILE *cfg;
 | |
| 
 | |
|   grub_install_copy_files (input_dir, base, platform);
 | |
|   grub_util_unlink (load_cfg);
 | |
| 
 | |
|   if (debug_image)
 | |
|     {
 | |
|       FILE *f = grub_util_fopen (load_cfg, "wb");
 | |
|       if (!f)
 | |
| 	grub_util_error (_("cannot open `%s': %s"), load_cfg,
 | |
| 			 strerror (errno));
 | |
|       fprintf (f, "set debug='%s'\n", debug_image);
 | |
|       fclose (f);
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       free (load_cfg);
 | |
|       load_cfg = 0;
 | |
|     }
 | |
| 
 | |
|   prefix = xasprintf ("/%s", subdir);
 | |
|   if (!targets[platform].mkimage_target)
 | |
|     grub_util_error (_("unsupported platform %s"), platsub);
 | |
| 
 | |
|   grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg");
 | |
|   cfg = grub_util_fopen (grub_cfg, "wb");
 | |
|   if (!cfg)
 | |
|     grub_util_error (_("cannot open `%s': %s"), grub_cfg,
 | |
| 		     strerror (errno));
 | |
|   fprintf (cfg, "source %s/grub.cfg", subdir);
 | |
|   fclose (cfg);
 | |
| 
 | |
|   grub_install_push_module (targets[platform].netmodule);
 | |
| 
 | |
|   output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext);
 | |
|   grub_install_make_image_wrap (input_dir, prefix, output,
 | |
| 				0, load_cfg,
 | |
| 				targets[platform].mkimage_target, 0);
 | |
|   grub_install_pop_module ();
 | |
| 
 | |
|   /* TRANSLATORS: First %s is replaced by platform name. Second one by filename.  */
 | |
|   printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"),
 | |
| 	  platsub, output);
 | |
| 
 | |
|   free (platsub);
 | |
|   free (output);
 | |
|   free (prefix);
 | |
|   free (grub_cfg);
 | |
|   free (grubdir);
 | |
| }
 | |
| 
 | |
| 
 | |
| int
 | |
| main (int argc, char *argv[])
 | |
| {
 | |
|   const char *pkglibdir;
 | |
| 
 | |
|   grub_util_host_init (&argc, &argv);
 | |
|   grub_util_disable_fd_syncs ();
 | |
|   rootdir = xstrdup ("/srv/tftp");
 | |
|   pkglibdir = grub_util_get_pkglibdir ();
 | |
| 
 | |
|   subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME);
 | |
| 
 | |
|   argp_parse (&argp, argc, argv, 0, 0, 0);
 | |
| 
 | |
|   base = grub_util_path_concat (2, rootdir, subdir);
 | |
|   /* Create the GRUB directory if it is not present.  */
 | |
| 
 | |
|   grub_install_mkdir_p (base);
 | |
| 
 | |
|   grub_install_push_module ("tftp");
 | |
| 
 | |
|   if (!grub_install_source_directory)
 | |
|     {
 | |
|       enum grub_install_plat plat;
 | |
| 
 | |
|       for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++)
 | |
| 	if (targets[plat].mkimage_target)
 | |
| 	  {
 | |
| 	    char *platdir = grub_util_path_concat (2, pkglibdir,
 | |
| 						   grub_install_get_platform_name (plat));
 | |
| 
 | |
| 	    grub_util_info ("Looking for `%s'", platdir);
 | |
| 
 | |
| 	    if (!grub_util_is_directory (platdir))
 | |
| 	      {
 | |
| 		free (platdir);
 | |
| 		continue;
 | |
| 	      }
 | |
| 	    process_input_dir (platdir, plat);
 | |
| 	  }
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       enum grub_install_plat plat;
 | |
|       plat = grub_install_get_target (grub_install_source_directory);
 | |
|       process_input_dir (grub_install_source_directory, plat);
 | |
|     }
 | |
|   return 0;
 | |
| }
 |