]>
git.saurik.com Git - redis.git/blob - src/redis-check-aof.c
11 sprintf(__buf, __VA_ARGS__); \
12 sprintf(error, "0x%08lx: %s", epos, __buf); \
15 static char error
[1024];
18 int consumeNewline(char *buf
) {
19 if (strncmp(buf
,"\r\n",2) != 0) {
20 ERROR("Expected \\r\\n, got: %02x%02x",buf
[0],buf
[1]);
26 int readLong(FILE *fp
, char prefix
, long *target
) {
29 if (fgets(buf
,sizeof(buf
),fp
) == NULL
) {
32 if (buf
[0] != prefix
) {
33 ERROR("Expected prefix '%c', got: '%c'",buf
[0],prefix
);
36 *target
= strtol(buf
+1,&eptr
,10);
37 return consumeNewline(eptr
);
40 int readBytes(FILE *fp
, char *target
, long length
) {
43 real
= fread(target
,1,length
,fp
);
45 ERROR("Expected to read %ld bytes, got %ld bytes",length
,real
);
51 int readString(FILE *fp
, char** target
) {
54 if (!readLong(fp
,'$',&len
)) {
58 /* Increase length to also consume \r\n */
60 *target
= (char*)malloc(len
);
61 if (!readBytes(fp
,*target
,len
)) {
64 if (!consumeNewline(*target
+len
-2)) {
67 (*target
)[len
-2] = '\0';
71 int readArgc(FILE *fp
, long *target
) {
72 return readLong(fp
,'*',target
);
75 long process(FILE *fp
) {
81 if (!multi
) pos
= ftell(fp
);
82 if (!readArgc(fp
, &argc
)) break;
84 for (i
= 0; i
< argc
; i
++) {
85 if (!readString(fp
,&str
)) break;
87 if (strcasecmp(str
, "multi") == 0) {
89 ERROR("Unexpected MULTI");
92 } else if (strcasecmp(str
, "exec") == 0) {
94 ERROR("Unexpected EXEC");
102 /* Stop if the loop did not finish */
109 if (feof(fp
) && multi
&& strlen(error
) == 0) {
110 ERROR("Reached EOF before reading EXEC for MULTI");
112 if (strlen(error
) > 0) {
113 printf("%s\n", error
);
118 int main(int argc
, char **argv
) {
123 printf("Usage: %s [--fix] <file.aof>\n", argv
[0]);
125 } else if (argc
== 2) {
127 } else if (argc
== 3) {
128 if (strcmp(argv
[1],"--fix") != 0) {
129 printf("Invalid argument: %s\n", argv
[1]);
135 printf("Invalid arguments\n");
139 FILE *fp
= fopen(filename
,"r+");
141 printf("Cannot open file: %s\n", filename
);
145 struct redis_stat sb
;
146 if (redis_fstat(fileno(fp
),&sb
) == -1) {
147 printf("Cannot stat file: %s\n", filename
);
151 long size
= sb
.st_size
;
153 printf("Empty file: %s\n", filename
);
157 long pos
= process(fp
);
158 long diff
= size
-pos
;
162 printf("This will shrink the AOF from %ld bytes, with %ld bytes, to %ld bytes\n",size
,diff
,pos
);
163 printf("Continue? [y/N]: ");
164 if (fgets(buf
,sizeof(buf
),stdin
) == NULL
||
165 strncasecmp(buf
,"y",1) != 0) {
166 printf("Aborting...\n");
169 if (ftruncate(fileno(fp
), pos
) == -1) {
170 printf("Failed to truncate AOF\n");
173 printf("Successfully truncated AOF\n");
176 printf("AOF is not valid\n");
180 printf("AOF is valid\n");