1 /*
   2  *  GRUB  --  GRand Unified Bootloader
   3  *  Copyright (C) 2012 Daniil Lunev
   4  *
   5  *  GRUB 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 3 of the License, or
   8  *  (at your option) any later version.
   9  *
  10  *  GRUB 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.
  14  *
  15  *  You should have received a copy of the GNU General Public License
  16  *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  17  */
  18 
  19 #include <grub/types.h>
  20 #include <grub/file.h>
  21 #include <grub/disk.h>
  22 #include <grub/misc.h>
  23 #include <grub/err.h>
  24 #include <grub/dl.h>
  25 #include <grub/extcmd.h>
  26 #include <grub/i18n.h>
  27 #include <grub/normal.h>
  28 
  29 #include "menu_managing.c"
  30 
  31 GRUB_MOD_LICENSE ("GPLv3+");
  32 
  33 static const struct grub_arg_option options[] = {
  34   {0, 0, 0, 0, 0, 0}
  35 };
  36 
  37 static const char * globals[] = {
  38   "default_entry",
  39   "timeout",
  40   "serial",
  41   "terminal",
  42   NULL
  43 };
  44 
  45 static grub_err_t
  46 get_value(char * buf, char ** value)
  47 {
  48   *value = grub_strchr(buf, '=');
  49   if (! *value)
  50     return grub_error (GRUB_ERR_INVALID_COMMAND, N_("illumos syntax error"));
  51   **value = '\0';
  52   ++(*value);
  53   return 0;
  54 }
  55 
  56 static int
  57 check_param(char * param)
  58 {
  59   int i = 0;
  60   
  61   for (; params_list[i]; ++i)
  62     if (!grub_strcmp(param, params_list[i]))
  63       return i;
  64   
  65   return -1;
  66 }
  67 
  68 static int
  69 check_global(char * param)
  70 {
  71   int i = 0;
  72   
  73   for (; globals[i]; ++i)
  74     if (!grub_strcmp(param, globals[i]))
  75       return i;
  76   
  77   return -1;
  78 }
  79 
  80 static grub_err_t
  81 parse_config(grub_file_t file, entries * entry_list)
  82 {
  83   char * param;
  84   char * value;
  85   entries * current_entry = NULL;
  86   int param_id = 0;
  87   int global_id = 0;
  88   grub_err_t err;
  89   
  90   for(;;) {
  91     param = grub_file_getline(file);
  92     if (! param)
  93       return grub_errno;
  94 
  95     if ((*param == '#') || (*param == ' ') || 
  96       (*param == '\t') || (*param == '\n') ||
  97       (*param == 0)) {
  98       grub_free(param);
  99       continue;
 100     }
 101     global_id = -1;
 102       
 103     err = get_value(param, &value);
 104     if (err)
 105       return err;
 106 
 107     param_id = check_param(param);
 108     if (param_id < 0) {
 109       global_id = check_global(param);
 110       if (global_id < 0) {
 111         grub_free(param);
 112         return grub_error (GRUB_ERR_INVALID_COMMAND, N_("illumos syntax error"));
 113       }
 114     }
 115     if (err)
 116       return err;
 117     if (!value[0])
 118       return grub_error (GRUB_ERR_INVALID_COMMAND, N_("illumos syntax error"));
 119     if (global_id < 0) {
 120       if (param_id == 0) {
 121         current_entry = new_entry(value, entry_list);
 122         if (! current_entry) {
 123           grub_free(param);
 124           return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("memory can not be allocated"));
 125         }
 126       } else {
 127         grub_strcpy(current_entry->entry_info[param_id], value);
 128       }
 129     } else {
 130       char line[512];
 131       switch (global_id) {
 132       case 0:
 133         grub_env_set("default", value);
 134         break;
 135       case 1:
 136         grub_env_set("timeout", value);
 137         break;
 138       case 2:
 139         grub_strcpy(line, "serial ");
 140         grub_strcat(line, value);
 141         grub_normal_parse_line(line, NULL);
 142         break;
 143       case 3:
 144         grub_strcpy(line, "terminal_input ");
 145         grub_strcat(line, value);
 146         grub_strcat(line, "; terminal_output ");
 147         grub_strcat(line, value);
 148         grub_normal_parse_line(line, NULL);
 149         break;
 150       default:
 151         break;
 152       }
 153     }
 154     grub_free(param);
 155   }    
 156   return 0;
 157 }
 158 
 159 static grub_err_t
 160 grub_cmd_illumos_entries (grub_extcmd_context_t ctxt __attribute__ ((unused)), int argc, char **args)
 161 {
 162   grub_file_t file;
 163   entries * menu_entries = NULL;
 164   
 165   if (argc != 1)
 166     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 167   
 168   file = grub_file_open(args[0]);
 169   
 170   if (!file)
 171     return grub_errno;
 172     
 173   init_entries(&menu_entries);
 174   
 175   if (parse_config(file, menu_entries) == 0) {
 176     add_entries(menu_entries);
 177   }  
 178   clear_entries(menu_entries);
 179   
 180   grub_refresh();
 181   grub_file_close(file);
 182 
 183   return 0;
 184 }
 185 
 186 static grub_extcmd_t illumos_entries;
 187 
 188 GRUB_MOD_INIT(illumos_entries)
 189 {
 190   illumos_entries = grub_register_extcmd ("illumos_entries", grub_cmd_illumos_entries, 0,
 191             N_("FILE"), N_("Define an illumos menu entries."), options);
 192 }
 193 
 194 GRUB_MOD_FINI(illumos_entries)
 195 {
 196   grub_unregister_extcmd (illumos_entries);
 197 }