mkdlinkfw-lib.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * mkdlinkfw
  3. *
  4. * Copyright (C) 2018 Paweł Dembicki <paweldembicki@gmail.com>
  5. *
  6. * This tool is based on mktplinkfw.
  7. * Copyright (C) 2009 Gabor Juhos <juhosg@openwrt.org>
  8. * Copyright (C) 2008,2009 Wang Jian <lark@linux.net.cn>
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the Free
  12. * Software Foundation; either version 2 of the License, or (at your option)
  13. * any later version.
  14. */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <stdint.h>
  18. #include <string.h>
  19. #include <unistd.h> /* for unlink() */
  20. #include <libgen.h>
  21. #include <getopt.h> /* for getopt() */
  22. #include <stdarg.h>
  23. #include <stdbool.h>
  24. #include <endian.h>
  25. #include <errno.h>
  26. #include <time.h>
  27. #include <sys/stat.h>
  28. #include <zlib.h> /*for crc32 */
  29. #include "mkdlinkfw-lib.h"
  30. extern char *progname;
  31. uint32_t jboot_timestamp(void)
  32. {
  33. char *env = getenv("SOURCE_DATE_EPOCH");
  34. char *endptr = env;
  35. time_t fixed_timestamp = -1;
  36. errno = 0;
  37. if (env && *env) {
  38. fixed_timestamp = strtoull(env, &endptr, 10);
  39. if (errno || (endptr && *endptr != '\0')) {
  40. fprintf(stderr, "Invalid SOURCE_DATE_EPOCH");
  41. fixed_timestamp = -1;
  42. }
  43. }
  44. if (fixed_timestamp == -1)
  45. time(&fixed_timestamp);
  46. return (((uint32_t) fixed_timestamp) - TIMESTAMP_MAGIC) >> 2;
  47. }
  48. uint16_t jboot_checksum(uint16_t start_val, uint16_t *data, int size)
  49. {
  50. uint32_t counter = start_val;
  51. uint16_t *ptr = data;
  52. while (size > 1) {
  53. counter += *ptr;
  54. ++ptr;
  55. while (counter >> 16)
  56. counter = (uint16_t) counter + (counter >> 16);
  57. size -= 2;
  58. }
  59. if (size > 0) {
  60. counter += *(uint8_t *) ptr;
  61. counter -= 0xFF;
  62. }
  63. while (counter >> 16)
  64. counter = (uint16_t) counter + (counter >> 16);
  65. return counter;
  66. }
  67. int get_file_stat(struct file_info *fdata)
  68. {
  69. struct stat st;
  70. int res;
  71. if (fdata->file_name == NULL)
  72. return 0;
  73. res = stat(fdata->file_name, &st);
  74. if (res) {
  75. ERRS("stat failed on %s", fdata->file_name);
  76. return res;
  77. }
  78. fdata->file_size = st.st_size;
  79. return 0;
  80. }
  81. int read_to_buf(const struct file_info *fdata, char *buf)
  82. {
  83. FILE *f;
  84. int ret = EXIT_FAILURE;
  85. size_t read;
  86. f = fopen(fdata->file_name, "r");
  87. if (f == NULL) {
  88. ERRS("could not open \"%s\" for reading", fdata->file_name);
  89. goto out;
  90. }
  91. read = fread(buf, fdata->file_size, 1, f);
  92. if (ferror(f) || read != 1) {
  93. ERRS("unable to read from file \"%s\"", fdata->file_name);
  94. goto out_close;
  95. }
  96. ret = EXIT_SUCCESS;
  97. out_close:
  98. fclose(f);
  99. out:
  100. return ret;
  101. }
  102. int write_fw(const char *ofname, const char *data, int len)
  103. {
  104. FILE *f;
  105. int ret = EXIT_FAILURE;
  106. f = fopen(ofname, "w");
  107. if (f == NULL) {
  108. ERRS("could not open \"%s\" for writing", ofname);
  109. goto out;
  110. }
  111. errno = 0;
  112. fwrite(data, len, 1, f);
  113. if (errno) {
  114. ERRS("unable to write output file");
  115. goto out_flush;
  116. }
  117. DBG("firmware file \"%s\" completed", ofname);
  118. ret = EXIT_SUCCESS;
  119. out_flush:
  120. fflush(f);
  121. fclose(f);
  122. if (ret != EXIT_SUCCESS)
  123. unlink(ofname);
  124. out:
  125. return ret;
  126. }