1 /* handler.c - support handler loading */
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/>.
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
;
36 static grub_list_t handler_list
;
39 grub_handler_cmd (struct grub_command
*cmd
,
40 int argc
__attribute__ ((unused
)),
41 char **args
__attribute__ ((unused
)))
44 grub_handler_class_t
class;
45 grub_handler_t handler
;
47 p
= grub_strchr (cmd
->name
, '.');
49 return grub_error (GRUB_ERR_BAD_ARGUMENT
, "invalid command name");
53 if (! grub_dl_get (cmd
->data
))
57 mod
= grub_dl_load (cmd
->data
);
63 grub_free (cmd
->data
);
68 class = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_handler_class_list
),
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
),
79 return grub_error (GRUB_ERR_FILE_NOT_FOUND
, "handler not found");
81 grub_handler_set_current (class, handler
);
87 insert_handler (char *name
, char *module
)
89 struct grub_handler_list
*item
;
92 if (grub_command_find (name
))
95 item
= grub_malloc (sizeof (*item
));
99 item
->name
= grub_strdup (name
);
108 data
= grub_strdup (module
);
111 grub_free (item
->name
);
119 item
->cmd
= grub_register_command (item
->name
, grub_handler_cmd
, 0,
120 "Set active handler");
124 grub_free (item
->name
);
129 item
->cmd
->data
= data
;
130 grub_list_push (&handler_list
, GRUB_AS_LIST (item
));
133 /* Read the file handler.lst for auto-loading. */
135 read_handler_list (void)
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);
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
);
165 /* Make sure that this function does not get executed twice. */
170 prefix
= grub_env_get ("prefix");
175 filename
= grub_malloc (grub_strlen (prefix
) + sizeof ("/handler.lst"));
180 grub_sprintf (filename
, "%s/handler.lst", prefix
);
181 file
= grub_file_open (filename
);
185 for (;; grub_free(buf
))
189 buf
= grub_file_getline (file
);
194 if (! grub_isgraph (buf
[0]))
197 p
= grub_strchr (buf
, ':');
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
);
217 grub_errno
= GRUB_ERR_NONE
;
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
);