Indentation fix, cleanup.
[AROS.git] / arch / all-pc / boot / grub2-aros / grub-core / loader / linux.c
blob117232f0c951bd1b24685acc4df107a96d6b2704
1 #include <grub/types.h>
2 #include <grub/err.h>
3 #include <grub/linux.h>
4 #include <grub/misc.h>
5 #include <grub/file.h>
6 #include <grub/mm.h>
8 struct newc_head
10 char magic[6];
11 char ino[8];
12 char mode[8];
13 char uid[8];
14 char gid[8];
15 char nlink[8];
16 char mtime[8];
17 char filesize[8];
18 char devmajor[8];
19 char devminor[8];
20 char rdevmajor[8];
21 char rdevminor[8];
22 char namesize[8];
23 char check[8];
24 } GRUB_PACKED;
26 struct grub_linux_initrd_component
28 grub_file_t file;
29 char *newc_name;
30 grub_off_t size;
33 struct dir
35 char *name;
36 struct dir *next;
37 struct dir *child;
40 static char
41 hex (grub_uint8_t val)
43 if (val < 10)
44 return '0' + val;
45 return 'a' + val - 10;
48 static void
49 set_field (char *var, grub_uint32_t val)
51 int i;
52 char *ptr = var;
53 for (i = 28; i >= 0; i -= 4)
54 *ptr++ = hex((val >> i) & 0xf);
57 static grub_uint8_t *
58 make_header (grub_uint8_t *ptr,
59 const char *name, grub_size_t len,
60 grub_uint32_t mode,
61 grub_off_t fsize)
63 struct newc_head *head = (struct newc_head *) ptr;
64 grub_uint8_t *optr;
65 grub_size_t oh = 0;
66 grub_memcpy (head->magic, "070701", 6);
67 set_field (head->ino, 0);
68 set_field (head->mode, mode);
69 set_field (head->uid, 0);
70 set_field (head->gid, 0);
71 set_field (head->nlink, 1);
72 set_field (head->mtime, 0);
73 set_field (head->filesize, fsize);
74 set_field (head->devmajor, 0);
75 set_field (head->devminor, 0);
76 set_field (head->rdevmajor, 0);
77 set_field (head->rdevminor, 0);
78 set_field (head->namesize, len);
79 set_field (head->check, 0);
80 optr = ptr;
81 ptr += sizeof (struct newc_head);
82 grub_memcpy (ptr, name, len);
83 ptr += len;
84 oh = ALIGN_UP_OVERHEAD (ptr - optr, 4);
85 grub_memset (ptr, 0, oh);
86 ptr += oh;
87 return ptr;
90 static void
91 free_dir (struct dir *root)
93 if (!root)
94 return;
95 free_dir (root->next);
96 free_dir (root->child);
97 grub_free (root->name);
98 grub_free (root);
101 static grub_size_t
102 insert_dir (const char *name, struct dir **root,
103 grub_uint8_t *ptr)
105 struct dir *cur, **head = root;
106 const char *cb, *ce = name;
107 grub_size_t size = 0;
108 while (1)
110 for (cb = ce; *cb == '/'; cb++);
111 for (ce = cb; *ce && *ce != '/'; ce++);
112 if (!*ce)
113 break;
115 for (cur = *root; cur; cur = cur->next)
116 if (grub_memcmp (cur->name, cb, ce - cb)
117 && cur->name[ce - cb] == 0)
118 break;
119 if (!cur)
121 struct dir *n;
122 n = grub_zalloc (sizeof (*n));
123 if (!n)
124 return 0;
125 n->next = *head;
126 n->name = grub_strndup (cb, ce - cb);
127 if (ptr)
129 grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce);
130 ptr = make_header (ptr, name, ce - name,
131 040777, 0);
133 size += ALIGN_UP ((ce - (char *) name)
134 + sizeof (struct newc_head), 4);
135 *head = n;
136 cur = n;
138 root = &cur->next;
140 return size;
143 grub_err_t
144 grub_initrd_init (int argc, char *argv[],
145 struct grub_linux_initrd_context *initrd_ctx)
147 int i;
148 int newc = 0;
149 struct dir *root = 0;
151 initrd_ctx->nfiles = 0;
152 initrd_ctx->components = 0;
154 initrd_ctx->components = grub_zalloc (argc
155 * sizeof (initrd_ctx->components[0]));
156 if (!initrd_ctx->components)
157 return grub_errno;
159 initrd_ctx->size = 0;
161 for (i = 0; i < argc; i++)
163 const char *fname = argv[i];
164 if (grub_memcmp (argv[i], "newc:", 5) == 0)
166 const char *ptr, *eptr;
167 ptr = argv[i] + 5;
168 while (*ptr == '/')
169 ptr++;
170 eptr = grub_strchr (ptr, ':');
171 if (eptr)
173 grub_file_filter_disable_compression ();
174 initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
175 if (!initrd_ctx->components[i].newc_name)
177 grub_initrd_close (initrd_ctx);
178 return grub_errno;
180 initrd_ctx->size
181 += ALIGN_UP (sizeof (struct newc_head)
182 + grub_strlen (initrd_ctx->components[i].newc_name),
184 initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
185 &root, 0);
186 newc = 1;
187 fname = eptr + 1;
190 else if (newc)
192 initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
193 + sizeof ("TRAILER!!!") - 1, 4);
194 free_dir (root);
195 root = 0;
196 newc = 0;
198 grub_file_filter_disable_compression ();
199 initrd_ctx->components[i].file = grub_file_open (fname);
200 if (!initrd_ctx->components[i].file)
202 grub_initrd_close (initrd_ctx);
203 return grub_errno;
205 initrd_ctx->nfiles++;
206 initrd_ctx->components[i].size
207 = grub_file_size (initrd_ctx->components[i].file);
208 initrd_ctx->size += ALIGN_UP (initrd_ctx->components[i].size, 4);
211 if (newc)
213 initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
214 + sizeof ("TRAILER!!!") - 1, 4);
215 free_dir (root);
216 root = 0;
219 return GRUB_ERR_NONE;
222 grub_size_t
223 grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx)
225 return initrd_ctx->size;
228 void
229 grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx)
231 int i;
232 if (!initrd_ctx->components)
233 return;
234 for (i = 0; i < initrd_ctx->nfiles; i++)
236 grub_free (initrd_ctx->components[i].newc_name);
237 grub_file_close (initrd_ctx->components[i].file);
239 grub_free (initrd_ctx->components);
240 initrd_ctx->components = 0;
243 grub_err_t
244 grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
245 char *argv[], void *target)
247 grub_uint8_t *ptr = target;
248 int i;
249 int newc = 0;
250 struct dir *root = 0;
252 for (i = 0; i < initrd_ctx->nfiles; i++)
254 grub_ssize_t cursize;
256 if (initrd_ctx->components[i].newc_name)
258 ptr += insert_dir (initrd_ctx->components[i].newc_name,
259 &root, ptr);
260 ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
261 grub_strlen (initrd_ctx->components[i].newc_name),
262 0100777,
263 initrd_ctx->components[i].size);
264 newc = 1;
266 else if (newc)
268 ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1,
269 0, 0);
270 free_dir (root);
271 root = 0;
272 newc = 0;
275 cursize = initrd_ctx->components[i].size;
276 if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize)
277 != cursize)
279 if (!grub_errno)
280 grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
281 argv[i]);
282 grub_initrd_close (initrd_ctx);
283 return grub_errno;
285 ptr += cursize;
286 grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4));
287 ptr += ALIGN_UP_OVERHEAD (cursize, 4);
289 if (newc)
290 ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0);
291 free_dir (root);
292 root = 0;
293 return GRUB_ERR_NONE;