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