diff options
Diffstat (limited to 'usr')
-rw-r--r-- | usr/gen_init_cpio.c | 122 |
1 files changed, 86 insertions, 36 deletions
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 83acd6cc0b3c..8365db6cfe06 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c | |||
@@ -14,6 +14,7 @@ | |||
14 | * Original work by Jeff Garzik | 14 | * Original work by Jeff Garzik |
15 | * | 15 | * |
16 | * External file lists, symlink, pipe and fifo support by Thayne Harbaugh | 16 | * External file lists, symlink, pipe and fifo support by Thayne Harbaugh |
17 | * Hard link support by Luciano Rocha | ||
17 | */ | 18 | */ |
18 | 19 | ||
19 | #define xstr(s) #s | 20 | #define xstr(s) #s |
@@ -286,16 +287,19 @@ static int cpio_mknod_line(const char *line) | |||
286 | return rc; | 287 | return rc; |
287 | } | 288 | } |
288 | 289 | ||
289 | /* Not marked static to keep the compiler quiet, as no one uses this yet... */ | ||
290 | static int cpio_mkfile(const char *name, const char *location, | 290 | static int cpio_mkfile(const char *name, const char *location, |
291 | unsigned int mode, uid_t uid, gid_t gid) | 291 | unsigned int mode, uid_t uid, gid_t gid, |
292 | unsigned int nlinks) | ||
292 | { | 293 | { |
293 | char s[256]; | 294 | char s[256]; |
294 | char *filebuf = NULL; | 295 | char *filebuf = NULL; |
295 | struct stat buf; | 296 | struct stat buf; |
297 | long size; | ||
296 | int file = -1; | 298 | int file = -1; |
297 | int retval; | 299 | int retval; |
298 | int rc = -1; | 300 | int rc = -1; |
301 | int namesize; | ||
302 | int i; | ||
299 | 303 | ||
300 | mode |= S_IFREG; | 304 | mode |= S_IFREG; |
301 | 305 | ||
@@ -323,29 +327,41 @@ static int cpio_mkfile(const char *name, const char *location, | |||
323 | goto error; | 327 | goto error; |
324 | } | 328 | } |
325 | 329 | ||
326 | sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" | 330 | size = 0; |
327 | "%08X%08X%08X%08X%08X%08X%08X", | 331 | for (i = 1; i <= nlinks; i++) { |
328 | "070701", /* magic */ | 332 | /* data goes on last link */ |
329 | ino++, /* ino */ | 333 | if (i == nlinks) size = buf.st_size; |
330 | mode, /* mode */ | 334 | |
331 | (long) uid, /* uid */ | 335 | namesize = strlen(name) + 1; |
332 | (long) gid, /* gid */ | 336 | sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" |
333 | 1, /* nlink */ | 337 | "%08lX%08X%08X%08X%08X%08X%08X", |
334 | (long) buf.st_mtime, /* mtime */ | 338 | "070701", /* magic */ |
335 | (int) buf.st_size, /* filesize */ | 339 | ino, /* ino */ |
336 | 3, /* major */ | 340 | mode, /* mode */ |
337 | 1, /* minor */ | 341 | (long) uid, /* uid */ |
338 | 0, /* rmajor */ | 342 | (long) gid, /* gid */ |
339 | 0, /* rminor */ | 343 | nlinks, /* nlink */ |
340 | (unsigned)strlen(name) + 1,/* namesize */ | 344 | (long) buf.st_mtime, /* mtime */ |
341 | 0); /* chksum */ | 345 | size, /* filesize */ |
342 | push_hdr(s); | 346 | 3, /* major */ |
343 | push_string(name); | 347 | 1, /* minor */ |
344 | push_pad(); | 348 | 0, /* rmajor */ |
349 | 0, /* rminor */ | ||
350 | namesize, /* namesize */ | ||
351 | 0); /* chksum */ | ||
352 | push_hdr(s); | ||
353 | push_string(name); | ||
354 | push_pad(); | ||
355 | |||
356 | if (size) { | ||
357 | fwrite(filebuf, size, 1, stdout); | ||
358 | offset += size; | ||
359 | push_pad(); | ||
360 | } | ||
345 | 361 | ||
346 | fwrite(filebuf, buf.st_size, 1, stdout); | 362 | name += namesize; |
347 | offset += buf.st_size; | 363 | } |
348 | push_pad(); | 364 | ino++; |
349 | rc = 0; | 365 | rc = 0; |
350 | 366 | ||
351 | error: | 367 | error: |
@@ -357,18 +373,51 @@ error: | |||
357 | static int cpio_mkfile_line(const char *line) | 373 | static int cpio_mkfile_line(const char *line) |
358 | { | 374 | { |
359 | char name[PATH_MAX + 1]; | 375 | char name[PATH_MAX + 1]; |
376 | char *dname = NULL; /* malloc'ed buffer for hard links */ | ||
360 | char location[PATH_MAX + 1]; | 377 | char location[PATH_MAX + 1]; |
361 | unsigned int mode; | 378 | unsigned int mode; |
362 | int uid; | 379 | int uid; |
363 | int gid; | 380 | int gid; |
381 | int nlinks = 1; | ||
382 | int end = 0, dname_len = 0; | ||
364 | int rc = -1; | 383 | int rc = -1; |
365 | 384 | ||
366 | if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, location, &mode, &uid, &gid)) { | 385 | if (5 > sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) |
386 | "s %o %d %d %n", | ||
387 | name, location, &mode, &uid, &gid, &end)) { | ||
367 | fprintf(stderr, "Unrecognized file format '%s'", line); | 388 | fprintf(stderr, "Unrecognized file format '%s'", line); |
368 | goto fail; | 389 | goto fail; |
369 | } | 390 | } |
370 | rc = cpio_mkfile(name, location, mode, uid, gid); | 391 | if (end && isgraph(line[end])) { |
392 | int len; | ||
393 | int nend; | ||
394 | |||
395 | dname = malloc(strlen(line)); | ||
396 | if (!dname) { | ||
397 | fprintf (stderr, "out of memory (%d)\n", dname_len); | ||
398 | goto fail; | ||
399 | } | ||
400 | |||
401 | dname_len = strlen(name) + 1; | ||
402 | memcpy(dname, name, dname_len); | ||
403 | |||
404 | do { | ||
405 | nend = 0; | ||
406 | if (sscanf(line + end, "%" str(PATH_MAX) "s %n", | ||
407 | name, &nend) < 1) | ||
408 | break; | ||
409 | len = strlen(name) + 1; | ||
410 | memcpy(dname + dname_len, name, len); | ||
411 | dname_len += len; | ||
412 | nlinks++; | ||
413 | end += nend; | ||
414 | } while (isgraph(line[end])); | ||
415 | } else { | ||
416 | dname = name; | ||
417 | } | ||
418 | rc = cpio_mkfile(dname, location, mode, uid, gid, nlinks); | ||
371 | fail: | 419 | fail: |
420 | if (dname_len) free(dname); | ||
372 | return rc; | 421 | return rc; |
373 | } | 422 | } |
374 | 423 | ||
@@ -381,22 +430,23 @@ void usage(const char *prog) | |||
381 | "describe the files to be included in the initramfs archive:\n" | 430 | "describe the files to be included in the initramfs archive:\n" |
382 | "\n" | 431 | "\n" |
383 | "# a comment\n" | 432 | "# a comment\n" |
384 | "file <name> <location> <mode> <uid> <gid>\n" | 433 | "file <name> <location> <mode> <uid> <gid> [<hard links>]\n" |
385 | "dir <name> <mode> <uid> <gid>\n" | 434 | "dir <name> <mode> <uid> <gid>\n" |
386 | "nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n" | 435 | "nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n" |
387 | "slink <name> <target> <mode> <uid> <gid>\n" | 436 | "slink <name> <target> <mode> <uid> <gid>\n" |
388 | "pipe <name> <mode> <uid> <gid>\n" | 437 | "pipe <name> <mode> <uid> <gid>\n" |
389 | "sock <name> <mode> <uid> <gid>\n" | 438 | "sock <name> <mode> <uid> <gid>\n" |
390 | "\n" | 439 | "\n" |
391 | "<name> name of the file/dir/nod/etc in the archive\n" | 440 | "<name> name of the file/dir/nod/etc in the archive\n" |
392 | "<location> location of the file in the current filesystem\n" | 441 | "<location> location of the file in the current filesystem\n" |
393 | "<target> link target\n" | 442 | "<target> link target\n" |
394 | "<mode> mode/permissions of the file\n" | 443 | "<mode> mode/permissions of the file\n" |
395 | "<uid> user id (0=root)\n" | 444 | "<uid> user id (0=root)\n" |
396 | "<gid> group id (0=root)\n" | 445 | "<gid> group id (0=root)\n" |
397 | "<dev_type> device type (b=block, c=character)\n" | 446 | "<dev_type> device type (b=block, c=character)\n" |
398 | "<maj> major number of nod\n" | 447 | "<maj> major number of nod\n" |
399 | "<min> minor number of nod\n" | 448 | "<min> minor number of nod\n" |
449 | "<hard links> space separated list of other links to file\n" | ||
400 | "\n" | 450 | "\n" |
401 | "example:\n" | 451 | "example:\n" |
402 | "# A simple initramfs\n" | 452 | "# A simple initramfs\n" |