Mirror of CollapseOS
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.

94 lines
1.9KB

  1. #include <stdio.h>
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5. #include <sys/stat.h>
  6. #define BLKSIZE 0x100
  7. #define HEADERSIZE 0x20
  8. #define MAX_FN_LEN 25 // 26 - null char
  9. bool ensuredir(char *path)
  10. {
  11. char *s = path;
  12. while (*s != '\0') {
  13. if (*s == '/') {
  14. *s = '\0';
  15. struct stat path_stat;
  16. if (stat(path, &path_stat) != 0) {
  17. if (mkdir(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) {
  18. return false;
  19. }
  20. }
  21. *s = '/';
  22. }
  23. s++;
  24. }
  25. return true;
  26. }
  27. bool unpackblk(char *dstpath)
  28. {
  29. char buf[MAX_FN_LEN+1];
  30. if (fgets(buf, 3+1, stdin) == NULL) {
  31. return false;
  32. }
  33. if (strcmp(buf, "CFS") != 0) {
  34. return false;
  35. }
  36. int c = getchar();
  37. uint8_t blkcnt = c;
  38. if (blkcnt == 0) {
  39. return false;
  40. }
  41. c = getchar();
  42. uint16_t fsize = c & 0xff;
  43. c = getchar();
  44. fsize |= (c & 0xff) << 8;
  45. if (fgets(buf, MAX_FN_LEN+1+1, stdin) == NULL) {
  46. return false;
  47. }
  48. char fullpath[0x1000];
  49. strcpy(fullpath, dstpath);
  50. strcat(fullpath, "/");
  51. strcat(fullpath, buf);
  52. if (!ensuredir(fullpath)) {
  53. return false;
  54. }
  55. int blksize = (BLKSIZE-HEADERSIZE)+(BLKSIZE*(blkcnt-1));
  56. int skipcount = blksize - fsize;
  57. FILE *fp = fopen(fullpath, "w");
  58. while (fsize) {
  59. c = getchar();
  60. if (c == EOF) {
  61. return false;
  62. }
  63. fputc(c, fp);
  64. fsize--;
  65. }
  66. fclose(fp);
  67. while (skipcount) {
  68. getchar();
  69. skipcount--;
  70. }
  71. return true;
  72. }
  73. int main(int argc, char *argv[])
  74. {
  75. if (argc != 2) {
  76. fprintf(stderr, "Usage: cfspack /path/to/dest\n");
  77. return 1;
  78. }
  79. char *dstpath = argv[1];
  80. // we fail if there isn't at least one block
  81. if (!unpackblk(dstpath)) {
  82. return 1;
  83. }
  84. while (unpackblk(dstpath));
  85. return 0;
  86. }