mirror of
				https://git.proxmox.com/git/grub2
				synced 2025-10-31 01:22:24 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			218 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			218 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  GRUB  --  GRand Unified Bootloader
 | |
|  *  Copyright (C) 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 <grub/types.h>
 | |
| #include <grub/misc.h>
 | |
| #include <grub/extcmd.h>
 | |
| #include <grub/mm.h>
 | |
| #include <grub/err.h>
 | |
| #include <grub/dl.h>
 | |
| #include <grub/file.h>
 | |
| #include <grub/normal.h>
 | |
| #include <grub/script_sh.h>
 | |
| #include <grub/i18n.h>
 | |
| #include <grub/term.h>
 | |
| #include <grub/syslinux_parse.h>
 | |
| #include <grub/crypto.h>
 | |
| #include <grub/auth.h>
 | |
| #include <grub/disk.h>
 | |
| #include <grub/partition.h>
 | |
| 
 | |
| GRUB_MOD_LICENSE ("GPLv3+");
 | |
| 
 | |
| /* Helper for syslinux_file.  */
 | |
| static grub_err_t
 | |
| syslinux_file_getline (char **line, int cont __attribute__ ((unused)),
 | |
| 		     void *data __attribute__ ((unused)))
 | |
| {
 | |
|   *line = 0;
 | |
|   return GRUB_ERR_NONE;
 | |
| }
 | |
| 
 | |
| static const struct grub_arg_option options[] =
 | |
|   {
 | |
|     {"root",  'r', 0,
 | |
|      N_("root directory of the syslinux disk [default=/]."),
 | |
|      N_("DIR"), ARG_TYPE_STRING},
 | |
|     {"cwd",  'c', 0,
 | |
|      N_("current directory of syslinux [default is parent directory of input file]."),
 | |
|      N_("DIR"), ARG_TYPE_STRING},
 | |
|     {"isolinux",     'i',  0, N_("assume input is an isolinux configuration file."), 0, 0},
 | |
|     {"pxelinux",     'p',  0, N_("assume input is a pxelinux configuration file."), 0, 0},
 | |
|     {"syslinux",     's',  0, N_("assume input is a syslinux configuration file."), 0, 0},
 | |
|     {0, 0, 0, 0, 0, 0}
 | |
|   };
 | |
| 
 | |
| enum
 | |
|   {
 | |
|     OPTION_ROOT,
 | |
|     OPTION_CWD,
 | |
|     OPTION_ISOLINUX,
 | |
|     OPTION_PXELINUX,
 | |
|     OPTION_SYSLINUX
 | |
|   };
 | |
| 
 | |
| static grub_err_t
 | |
| syslinux_file (grub_extcmd_context_t ctxt, const char *filename)
 | |
| {
 | |
|   char *result;
 | |
|   const char *root = ctxt->state[OPTION_ROOT].set ? ctxt->state[OPTION_ROOT].arg : "/";
 | |
|   const char *cwd = ctxt->state[OPTION_CWD].set ? ctxt->state[OPTION_CWD].arg : NULL;
 | |
|   grub_syslinux_flavour_t flav = GRUB_SYSLINUX_UNKNOWN;
 | |
|   char *cwdf = NULL;
 | |
|   grub_menu_t menu;
 | |
| 
 | |
|   if (ctxt->state[OPTION_ISOLINUX].set)
 | |
|     flav = GRUB_SYSLINUX_ISOLINUX;
 | |
|   if (ctxt->state[OPTION_PXELINUX].set)
 | |
|     flav = GRUB_SYSLINUX_PXELINUX;
 | |
|   if (ctxt->state[OPTION_SYSLINUX].set)
 | |
|     flav = GRUB_SYSLINUX_SYSLINUX;
 | |
| 
 | |
|   if (!cwd)
 | |
|     {
 | |
|       char *p;
 | |
|       cwdf = grub_strdup (filename);
 | |
|       if (!cwdf)
 | |
| 	return grub_errno;
 | |
|       p = grub_strrchr (cwdf, '/');
 | |
|       if (!p)
 | |
| 	{
 | |
| 	  grub_free (cwdf);
 | |
| 	  cwd = "/";
 | |
| 	  cwdf = NULL;
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  *p = '\0';
 | |
| 	  cwd = cwdf;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   grub_dprintf ("syslinux",
 | |
| 		"transforming syslinux config %s, root = %s, cwd = %s\n",
 | |
| 		filename, root, cwd);
 | |
| 
 | |
|   result = grub_syslinux_config_file (root, root, cwd, cwd, filename, flav);
 | |
|   if (!result)
 | |
|     return grub_errno;
 | |
| 
 | |
|   grub_dprintf ("syslinux", "syslinux config transformed\n");
 | |
| 
 | |
|   menu = grub_env_get_menu ();
 | |
|   if (! menu)
 | |
|     {
 | |
|       menu = grub_zalloc (sizeof (*menu));
 | |
|       if (! menu)
 | |
| 	{
 | |
| 	  grub_free (result);
 | |
| 	  return grub_errno;
 | |
| 	}
 | |
| 
 | |
|       grub_env_set_menu (menu);
 | |
|     }
 | |
| 
 | |
|   grub_normal_parse_line (result, syslinux_file_getline, NULL);
 | |
|   grub_print_error ();
 | |
|   grub_free (result);
 | |
|   grub_free (cwdf);
 | |
| 
 | |
|   return GRUB_ERR_NONE;
 | |
| }
 | |
| 
 | |
| static grub_err_t
 | |
| grub_cmd_syslinux_source (grub_extcmd_context_t ctxt,
 | |
| 			  int argc, char **args)
 | |
| {
 | |
|   int new_env, extractor;
 | |
|   grub_err_t ret;
 | |
| 
 | |
|   if (argc != 1)
 | |
|     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 | |
| 
 | |
|   extractor = (ctxt->extcmd->cmd->name[0] == 'e');
 | |
|   new_env = (ctxt->extcmd->cmd->name[extractor ? (sizeof ("extract_syslinux_entries_") - 1)
 | |
| 			     : (sizeof ("syslinux_") - 1)] == 'c');
 | |
| 
 | |
|   if (new_env)
 | |
|     grub_cls ();
 | |
| 
 | |
|   if (new_env && !extractor)
 | |
|     grub_env_context_open ();
 | |
|   if (extractor)
 | |
|     grub_env_extractor_open (!new_env);
 | |
| 
 | |
|   ret = syslinux_file (ctxt, args[0]);
 | |
| 
 | |
|   if (new_env)
 | |
|     {
 | |
|       grub_menu_t menu;
 | |
|       menu = grub_env_get_menu ();
 | |
|       if (menu && menu->size)
 | |
| 	grub_show_menu (menu, 1, 0);
 | |
|       if (!extractor)
 | |
| 	grub_env_context_close ();
 | |
|     }
 | |
|   if (extractor)
 | |
|     grub_env_extractor_close (!new_env);
 | |
| 
 | |
|   return ret;
 | |
| }
 | |
| 
 | |
| 
 | |
| static grub_extcmd_t cmd_source, cmd_configfile;
 | |
| static grub_extcmd_t cmd_source_extract, cmd_configfile_extract;
 | |
| 
 | |
| GRUB_MOD_INIT(syslinuxcfg)
 | |
| {
 | |
|   cmd_source
 | |
|     = grub_register_extcmd ("syslinux_source",
 | |
| 			    grub_cmd_syslinux_source, 0,
 | |
| 			    N_("FILE"),
 | |
| 			    /* TRANSLATORS: "syslinux config" means
 | |
| 			       "config as used by syslinux".  */
 | |
| 			    N_("Execute syslinux config in same context"),
 | |
| 			    options);
 | |
|   cmd_configfile
 | |
|     = grub_register_extcmd ("syslinux_configfile",
 | |
| 			    grub_cmd_syslinux_source, 0,
 | |
| 			    N_("FILE"),
 | |
| 			    N_("Execute syslinux config in new context"),
 | |
| 			    options);
 | |
|   cmd_source_extract
 | |
|     = grub_register_extcmd ("extract_syslinux_entries_source",
 | |
| 			    grub_cmd_syslinux_source, 0,
 | |
| 			    N_("FILE"),
 | |
| 			    N_("Execute syslinux config in same context taking only menu entries"),
 | |
| 			    options);
 | |
|   cmd_configfile_extract
 | |
|     = grub_register_extcmd ("extract_syslinux_entries_configfile",
 | |
| 			    grub_cmd_syslinux_source, 0,
 | |
| 			    N_("FILE"),
 | |
| 			    N_("Execute syslinux config in new context taking only menu entries"),
 | |
| 			    options);
 | |
| }
 | |
| 
 | |
| GRUB_MOD_FINI(syslinuxcfg)
 | |
| {
 | |
|   grub_unregister_extcmd (cmd_source);
 | |
|   grub_unregister_extcmd (cmd_configfile);
 | |
|   grub_unregister_extcmd (cmd_source_extract);
 | |
|   grub_unregister_extcmd (cmd_configfile_extract);
 | |
| }
 | 
