Add-in development tools for fx-9860G and fx-CG 50, to use with GCC and gint.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

file.c 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <sys/types.h>
  2. #include <sys/stat.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <fxg1a.h>
  9. /* invert_header(): Bit-invert a standard header
  10. Part of the header is stored inverted in files for obfuscation purposes. */
  11. static void invert_header(struct g1a *g1a)
  12. {
  13. uint8_t *data = (void *)&g1a->header;
  14. for(size_t i = 0; i < 0x20; i++) data[i] = ~data[i];
  15. }
  16. #define fail(msg, ...) { \
  17. fprintf(stderr, "error: " msg ": %m\n", ##__VA_ARGS__); \
  18. close(fd); \
  19. free(data); \
  20. return NULL; \
  21. }
  22. /* load(): Fully load a file into memory
  23. Allocates a buffer with @prepend leading bytes initialized to zero. */
  24. static void *load(const char *filename, size_t *size, size_t prepend)
  25. {
  26. int fd;
  27. struct stat statbuf;
  28. void *data = NULL;
  29. size_t filesize;
  30. fd = open(filename, O_RDONLY);
  31. if(fd < 0) fail("cannot open %s", filename);
  32. int x = fstat(fd, &statbuf);
  33. if(x > 0) fail("cannot stat %s", filename);
  34. filesize = statbuf.st_size;
  35. data = malloc(prepend + filesize);
  36. if(!data) fail("cannot load %s", filename);
  37. size_t remaining = filesize;
  38. while(remaining > 0)
  39. {
  40. size_t offset = prepend + filesize - remaining;
  41. ssize_t y = read(fd, data + offset, remaining);
  42. if(y < 0) fail("cannot read from %s", filename);
  43. remaining -= y;
  44. }
  45. close(fd);
  46. memset(data, 0, prepend);
  47. if(size) *size = prepend + filesize;
  48. return data;
  49. }
  50. /* load_g1a(): Load a g1a file into memory */
  51. struct g1a *load_g1a(const char *filename, size_t *size)
  52. {
  53. struct g1a *ret = load(filename, size, 0);
  54. if(ret) invert_header(ret);
  55. return ret;
  56. }
  57. /* load_binary(): Load a binary file into memory */
  58. struct g1a *load_binary(const char *filename, size_t *size)
  59. {
  60. struct g1a *ret = load(filename, size, 0x200);
  61. if(ret) memset(ret, 0xff, 0x20);
  62. return ret;
  63. }
  64. #undef fail
  65. #define fail(msg, ...) { \
  66. fprintf(stderr, "error: " msg ": %m\n", ##__VA_ARGS__); \
  67. close(fd); \
  68. invert_header(g1a); \
  69. return 1; \
  70. }
  71. /* save_g1a(): Save a g1a file to disk */
  72. int save_g1a(const char *filename, struct g1a *g1a, size_t size)
  73. {
  74. /* Invert header before saving */
  75. invert_header(g1a);
  76. int fd = creat(filename, 0644);
  77. if(fd < 0) fail("cannot open %s", filename);
  78. void const *raw = g1a;
  79. ssize_t status;
  80. size_t written = 0;
  81. while(written < size)
  82. {
  83. status = write(fd, raw + written, size - written);
  84. if(status < 0) fail("cannot write to %s", filename);
  85. written += status;
  86. }
  87. close(fd);
  88. /* Before returning, re-invert header for further use */
  89. invert_header(g1a);
  90. return 0;
  91. }