gcda.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <stdio.h>
  2. //#include <stdlib.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. static int search_gcda(const char *str, int len)
  6. {
  7. int i;
  8. for (i = 0; i < len - 6; i++)
  9. if (str[i] == '.' && str[i+1] == 'g' && str[i+2] == 'c' &&
  10. str[i+3] == 'd' && str[i+4] == 'a' && str[i+5] == 0)
  11. return i;
  12. return -1;
  13. }
  14. static int is_good_char(char c)
  15. {
  16. return c >= ' ' && c < 0x7f;
  17. }
  18. static int is_good_path(char *path)
  19. {
  20. int len = strlen(path);
  21. path[len-2] = 'n';
  22. path[len-1] = 'o';
  23. FILE *f = fopen(path, "rb");
  24. path[len-2] = 'd';
  25. path[len-1] = 'a';
  26. if (f) {
  27. fclose(f);
  28. return 1;
  29. }
  30. printf("not good path: %s\n", path);
  31. return 0;
  32. }
  33. int main(int argc, char *argv[])
  34. {
  35. char buff[1024], *p;
  36. char cwd[4096];
  37. FILE *f;
  38. int l, pos, pos1, old_len, cwd_len;
  39. if (argc != 2) return 1;
  40. getcwd(cwd, sizeof(cwd));
  41. cwd_len = strlen(cwd);
  42. if (cwd[cwd_len-1] != '/') {
  43. cwd[cwd_len++] = '/';
  44. cwd[cwd_len] = 0;
  45. }
  46. f = fopen(argv[1], "rb+");
  47. if (f == NULL) return 2;
  48. while (1)
  49. {
  50. readnext:
  51. l = fread(buff, 1, sizeof(buff), f);
  52. if (l <= 16) break;
  53. pos = 0;
  54. while (pos < l)
  55. {
  56. pos1 = search_gcda(buff + pos, l - pos);
  57. if (pos1 < 0) {
  58. fseek(f, -6, SEEK_CUR);
  59. goto readnext;
  60. }
  61. pos += pos1;
  62. while (pos > 0 && is_good_char(buff[pos-1])) pos--;
  63. if (pos == 0) {
  64. fseek(f, -(sizeof(buff) + 16), SEEK_CUR);
  65. goto readnext;
  66. }
  67. // paths must start with /
  68. while (pos < l && buff[pos] != '/') pos++;
  69. p = buff + pos;
  70. old_len = strlen(p);
  71. if (!is_good_path(p)) {
  72. pos += old_len;
  73. continue;
  74. }
  75. if (strncmp(p, cwd, cwd_len) != 0) {
  76. printf("can't handle: %s\n", p);
  77. pos += old_len;
  78. continue;
  79. }
  80. memmove(p, p + cwd_len, old_len - cwd_len + 1);
  81. fseek(f, -(sizeof(buff) - pos), SEEK_CUR);
  82. fwrite(p, 1, old_len, f);
  83. goto readnext;
  84. }
  85. }
  86. fclose(f);
  87. return 0;
  88. }