2009-11-21 Samuel Thibault <samuel.thibault@ens-lyon.org>
[grub2.git] / normal / dyncmd.c
blob154da61142545c63c0910c56562ad013b4a19787
1 /* dyncmd.c - support dynamic command */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2009 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <grub/dl.h>
21 #include <grub/mm.h>
22 #include <grub/env.h>
23 #include <grub/misc.h>
24 #include <grub/command.h>
25 #include <grub/normal.h>
27 static grub_err_t
28 grub_dyncmd_dispatcher (struct grub_command *cmd,
29 int argc, char **args)
31 char *modname = cmd->data;
32 grub_dl_t mod;
33 grub_err_t ret;
35 mod = grub_dl_load (modname);
36 if (mod)
38 char *name;
40 grub_free (modname);
41 grub_dl_ref (mod);
43 name = (char *) cmd->name;
44 grub_unregister_command (cmd);
46 cmd = grub_command_find (name);
47 if (cmd)
48 ret = (cmd->func) (cmd, argc, args);
49 else
50 ret = grub_errno;
52 grub_free (name);
54 else
55 ret = grub_errno;
57 return ret;
60 /* Read the file command.lst for auto-loading. */
61 void
62 read_command_list (void)
64 const char *prefix;
65 static int first_time = 1;
67 /* Make sure that this function does not get executed twice. */
68 if (! first_time)
69 return;
70 first_time = 0;
72 prefix = grub_env_get ("prefix");
73 if (prefix)
75 char *filename;
77 filename = grub_malloc (grub_strlen (prefix) + sizeof ("/command.lst"));
78 if (filename)
80 grub_file_t file;
82 grub_sprintf (filename, "%s/command.lst", prefix);
83 file = grub_file_open (filename);
84 if (file)
86 char *buf = 0;
87 for (;; grub_free(buf))
89 char *p, *name, *modname;
90 grub_command_t cmd;
91 int prio = 0;
93 buf = grub_file_getline (file);
95 if (! buf)
96 break;
98 name = buf;
99 if (*name == '*')
101 name++;
102 prio++;
105 if (! grub_isgraph (name[0]))
106 continue;
108 p = grub_strchr (name, ':');
109 if (! p)
110 continue;
112 *p = '\0';
113 while (*++p == ' ')
116 if (! grub_isgraph (*p))
117 continue;
119 if (grub_dl_get (p))
120 continue;
122 name = grub_strdup (name);
123 if (! name)
124 continue;
126 modname = grub_strdup (p);
127 if (! modname)
129 grub_free (name);
130 continue;
133 cmd = grub_register_command_prio (name,
134 grub_dyncmd_dispatcher,
135 0, "not loaded", prio);
136 if (! cmd)
138 grub_free (name);
139 grub_free (modname);
140 continue;
142 cmd->flags |= GRUB_COMMAND_FLAG_DYNCMD;
143 cmd->data = modname;
145 /* Update the active flag. */
146 grub_command_find (name);
149 grub_file_close (file);
152 grub_free (filename);
156 /* Ignore errors. */
157 grub_errno = GRUB_ERR_NONE;