padjffs2.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * Copyright (C) 2011 Gabor Juhos <[email protected]>
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License version 2 as published
  6. * by the Free Software Foundation.
  7. *
  8. */
  9. #include <errno.h>
  10. #include <fcntl.h>
  11. #include <libgen.h>
  12. #include <stdio.h>
  13. #include <stdint.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <unistd.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. static char *progname;
  20. static unsigned char eof_mark[4] = {0xde, 0xad, 0xc0, 0xde};
  21. #define ERR(fmt, ...) do { \
  22. fflush(0); \
  23. fprintf(stderr, "[%s] *** error: " fmt "\n", \
  24. progname, ## __VA_ARGS__ ); \
  25. } while (0)
  26. #define ERRS(fmt, ...) do { \
  27. int save = errno; \
  28. fflush(0); \
  29. fprintf(stderr, "[%s] *** error: " fmt ", %s\n", \
  30. progname, ## __VA_ARGS__, strerror(save)); \
  31. } while (0)
  32. #define BUF_SIZE (64 * 1024)
  33. #define ALIGN(_x,_y) (((_x) + ((_y) - 1)) & ~((_y) - 1))
  34. static int pad_image(char *name, uint32_t pad_mask)
  35. {
  36. char *buf;
  37. int fd;
  38. ssize_t in_len;
  39. ssize_t out_len;
  40. int ret = -1;
  41. buf = malloc(BUF_SIZE);
  42. if (!buf) {
  43. ERR("No memory for buffer");
  44. goto out;
  45. }
  46. fd = open(name, O_RDWR);
  47. if (fd < 0) {
  48. ERRS("Unable to open %s", name);
  49. goto free_buf;
  50. }
  51. in_len = lseek(fd, 0, SEEK_END);
  52. if (in_len < 0)
  53. goto close;
  54. memset(buf, '\xff', BUF_SIZE);
  55. out_len = in_len;
  56. while (pad_mask) {
  57. uint32_t mask;
  58. ssize_t t;
  59. int i;
  60. for (i = 10; i < 32; i++) {
  61. mask = 1UL << i;
  62. if (pad_mask & mask)
  63. break;
  64. }
  65. in_len = ALIGN(in_len, mask);
  66. for (i = 10; i < 32; i++) {
  67. mask = 1UL << i;
  68. if ((in_len & (mask - 1)) == 0)
  69. pad_mask &= ~mask;
  70. }
  71. printf("padding image to %08x\n", (unsigned int) in_len);
  72. while (out_len < in_len) {
  73. ssize_t len;
  74. len = in_len - out_len;
  75. if (len > BUF_SIZE)
  76. len = BUF_SIZE;
  77. t = write(fd, buf, len);
  78. if (t != len) {
  79. ERRS("Unable to write to %s", name);
  80. goto close;
  81. }
  82. out_len += len;
  83. }
  84. /* write out the JFFS end-of-filesystem marker */
  85. t = write(fd, eof_mark, 4);
  86. if (t != 4) {
  87. ERRS("Unable to write to %s", name);
  88. goto close;
  89. }
  90. out_len += 4;
  91. }
  92. ret = 0;
  93. close:
  94. close(fd);
  95. free_buf:
  96. free(buf);
  97. out:
  98. return ret;
  99. }
  100. int main(int argc, char* argv[])
  101. {
  102. uint32_t pad_mask;
  103. int ret = EXIT_FAILURE;
  104. int err;
  105. int i;
  106. progname = basename(argv[0]);
  107. if (argc < 2) {
  108. fprintf(stderr,
  109. "Usage: %s file [pad0] [pad1] [padN]\n",
  110. progname);
  111. goto out;
  112. }
  113. pad_mask = 0;
  114. for (i = 2; i < argc; i++)
  115. pad_mask |= strtoul(argv[i], NULL, 0) * 1024;
  116. if (pad_mask == 0)
  117. pad_mask = (4 * 1024) | (8 * 1024) | (64 * 1024) |
  118. (128 * 1024);
  119. err = pad_image(argv[1], pad_mask);
  120. if (err)
  121. goto out;
  122. ret = EXIT_SUCCESS;
  123. out:
  124. return ret;
  125. }