2009-09-24 Robert Millan <rmh.grub@aybabtu.com>
[grub2/phcoder/solaris.git] / normal / handler.c
blobfe31478fef7ea3c83c21ea77c339cd346d42c0b8
1 /* handler.c - support handler loading */
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/err.h>
23 #include <grub/env.h>
24 #include <grub/misc.h>
25 #include <grub/command.h>
26 #include <grub/handler.h>
27 #include <grub/normal.h>
29 struct grub_handler_list
31 struct grub_handler_list *next;
32 char *name;
33 grub_command_t cmd;
36 static grub_list_t handler_list;
38 static grub_err_t
39 grub_handler_cmd (struct grub_command *cmd,
40 int argc __attribute__ ((unused)),
41 char **args __attribute__ ((unused)))
43 char *p;
44 grub_handler_class_t class;
45 grub_handler_t handler;
47 p = grub_strchr (cmd->name, '.');
48 if (! p)
49 return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid command name");
51 if (cmd->data)
53 if (! grub_dl_get (cmd->data))
55 grub_dl_t mod;
57 mod = grub_dl_load (cmd->data);
58 if (mod)
59 grub_dl_ref (mod);
60 else
61 return grub_errno;
63 grub_free (cmd->data);
64 cmd->data = 0;
67 *p = 0;
68 class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list),
69 cmd->name);
70 *p = '.';
72 if (! class)
73 return grub_error (GRUB_ERR_FILE_NOT_FOUND, "class not found");
76 handler = grub_named_list_find (GRUB_AS_NAMED_LIST (class->handler_list),
77 p + 1);
78 if (! handler)
79 return grub_error (GRUB_ERR_FILE_NOT_FOUND, "handler not found");
81 grub_handler_set_current (class, handler);
83 return 0;
86 static void
87 insert_handler (char *name, char *module)
89 struct grub_handler_list *item;
90 char *data;
92 if (grub_command_find (name))
93 return;
95 item = grub_malloc (sizeof (*item));
96 if (! item)
97 return;
99 item->name = grub_strdup (name);
100 if (! item->name)
102 grub_free (item);
103 return;
106 if (module)
108 data = grub_strdup (module);
109 if (! data)
111 grub_free (item->name);
112 grub_free (item);
113 return;
116 else
117 data = 0;
119 item->cmd = grub_register_command (item->name, grub_handler_cmd, 0,
120 "Set active handler");
121 if (! item->cmd)
123 grub_free (data);
124 grub_free (item->name);
125 grub_free (item);
126 return;
129 item->cmd->data = data;
130 grub_list_push (&handler_list, GRUB_AS_LIST (item));
133 /* Read the file handler.lst for auto-loading. */
134 void
135 read_handler_list (void)
137 const char *prefix;
138 static int first_time = 1;
139 const char *class_name;
141 auto int iterate_handler (grub_handler_t handler);
142 int iterate_handler (grub_handler_t handler)
144 char name[grub_strlen (class_name) + grub_strlen (handler->name) + 2];
146 grub_strcpy (name, class_name);
147 grub_strcat (name, ".");
148 grub_strcat (name, handler->name);
150 insert_handler (name, 0);
152 return 0;
155 auto int iterate_class (grub_handler_class_t class);
156 int iterate_class (grub_handler_class_t class)
158 class_name = class->name;
159 grub_list_iterate (GRUB_AS_LIST (class->handler_list),
160 (grub_list_hook_t) iterate_handler);
162 return 0;
165 /* Make sure that this function does not get executed twice. */
166 if (! first_time)
167 return;
168 first_time = 0;
170 prefix = grub_env_get ("prefix");
171 if (prefix)
173 char *filename;
175 filename = grub_malloc (grub_strlen (prefix) + sizeof ("/handler.lst"));
176 if (filename)
178 grub_file_t file;
180 grub_sprintf (filename, "%s/handler.lst", prefix);
181 file = grub_file_open (filename);
182 if (file)
184 char *buf = 0;
185 for (;; grub_free(buf))
187 char *p;
189 buf = grub_file_getline (file);
191 if (! buf)
192 break;
194 if (! grub_isgraph (buf[0]))
195 continue;
197 p = grub_strchr (buf, ':');
198 if (! p)
199 continue;
201 *p = '\0';
202 while (*++p == ' ')
205 insert_handler (buf, p);
207 grub_file_close (file);
209 grub_free (filename);
213 grub_list_iterate (GRUB_AS_LIST (grub_handler_class_list),
214 (grub_list_hook_t) iterate_class);
216 /* Ignore errors. */
217 grub_errno = GRUB_ERR_NONE;
220 void
221 free_handler_list (void)
223 struct grub_handler_list *item;
225 while ((item = grub_list_pop (&handler_list)) != 0)
227 grub_free (item->cmd->data);
228 grub_unregister_command (item->cmd);
229 grub_free (item->name);
230 grub_free (item);