aboutsummaryrefslogtreecommitdiffstats
path: root/usr/gen_init_cpio.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/gen_init_cpio.c')
-rw-r--r--usr/gen_init_cpio.c122
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... */
290static int cpio_mkfile(const char *name, const char *location, 290static 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
351error: 367error:
@@ -357,18 +373,51 @@ error:
357static int cpio_mkfile_line(const char *line) 373static 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"