]>
git.proxmox.com Git - grub2.git/blob - util/resolve.c
2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2002,2007 Free Software Foundation, Inc.
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.
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.
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/>.
26 #include <grub/emu/misc.h>
27 #include <grub/util/misc.h>
28 #include <grub/util/resolve.h>
34 struct mod_list
*next
;
41 struct mod_list
*list
;
42 struct dep_list
*next
;
45 static char buf
[1024];
48 free_mod_list (struct mod_list
*head
)
52 struct mod_list
*next
;
55 free ((void *) head
->name
);
62 free_dep_list (struct dep_list
*head
)
66 struct dep_list
*next
;
69 free ((void *) head
->name
);
70 free_mod_list (head
->list
);
76 /* Read the list of dependencies. */
77 static struct dep_list
*
78 read_dep_list (FILE *fp
)
80 struct dep_list
*dep_list
= 0;
82 while (fgets (buf
, sizeof (buf
), fp
))
87 /* Get the target name. */
88 p
= strchr (buf
, ':');
90 grub_util_error ("invalid line format: %s", buf
);
94 dep
= xmalloc (sizeof (*dep
));
95 dep
->name
= xstrdup (buf
);
101 /* Add dependencies. */
104 struct mod_list
*mod
;
107 /* Skip whitespace. */
108 while (*p
&& isspace (*p
))
116 /* Skip non-whitespace. */
117 while (*p
&& ! isspace (*p
))
122 mod
= (struct mod_list
*) xmalloc (sizeof (*mod
));
123 mod
->name
= xstrdup (name
);
124 mod
->next
= dep
->list
;
133 get_module_name (const char *str
)
138 base
= strrchr (str
, '/');
144 ext
= strrchr (base
, '.');
145 if (ext
&& strcmp (ext
, ".mod") == 0)
149 name
= xmalloc (ext
- base
+ 1);
150 memcpy (name
, base
, ext
- base
);
151 name
[ext
- base
] = '\0';
155 return xstrdup (base
);
159 get_module_path (const char *prefix
, const char *str
)
166 ext
= strrchr (str
, '.');
167 if (ext
&& strcmp (ext
, ".mod") == 0)
168 base
= xstrdup (str
);
171 base
= xmalloc (strlen (str
) + 4 + 1);
172 sprintf (base
, "%s.mod", str
);
175 dir
= strchr (str
, '/');
179 ret
= grub_util_get_path (prefix
, base
);
185 add_module (const char *dir
,
186 struct dep_list
*dep_list
,
187 struct mod_list
**mod_head
,
188 struct grub_util_path_list
**path_head
,
192 struct grub_util_path_list
*path
;
193 struct mod_list
*mod
;
194 struct dep_list
*dep
;
196 mod_name
= get_module_name (name
);
198 /* Check if the module has already been added. */
199 for (mod
= *mod_head
; mod
; mod
= mod
->next
)
200 if (strcmp (mod
->name
, mod_name
) == 0)
206 /* Resolve dependencies. */
207 for (dep
= dep_list
; dep
; dep
= dep
->next
)
208 if (strcmp (dep
->name
, mod_name
) == 0)
210 for (mod
= dep
->list
; mod
; mod
= mod
->next
)
211 add_module (dir
, dep_list
, mod_head
, path_head
, mod
->name
);
216 /* Add this module. */
217 mod
= (struct mod_list
*) xmalloc (sizeof (*mod
));
218 mod
->name
= mod_name
;
219 mod
->next
= *mod_head
;
223 path
= (struct grub_util_path_list
*) xmalloc (sizeof (*path
));
224 path
->name
= get_module_path (dir
, name
);
225 path
->next
= *path_head
;
229 struct grub_util_path_list
*
230 grub_util_resolve_dependencies (const char *prefix
,
231 const char *dep_list_file
,
236 struct dep_list
*dep_list
;
237 struct mod_list
*mod_list
= 0;
238 struct grub_util_path_list
*path_list
= 0;
240 path
= grub_util_get_path (prefix
, dep_list_file
);
241 fp
= fopen (path
, "r");
243 grub_util_error ("cannot open %s", path
);
246 dep_list
= read_dep_list (fp
);
251 add_module (prefix
, dep_list
, &mod_list
, &path_list
, *modules
);
255 free_dep_list (dep_list
);
256 free_mod_list (mod_list
);
258 { /* Reverse the path_list */
259 struct grub_util_path_list
*p
, *prev
, *next
;
261 for (p
= path_list
, prev
= NULL
; p
; p
= next
)