redrust/
redis_check_aof.rs

1extern crate c2rust_bitfields;
2extern crate libc;
3extern crate core;
4extern "C" {
5    pub type _IO_wide_data;
6    pub type _IO_codecvt;
7    pub type _IO_marker;
8    static mut stdin: *mut FILE;
9    fn fclose(__stream: *mut FILE) -> libc::c_int;
10    fn fopen(_: *const libc::c_char, _: *const libc::c_char) -> *mut FILE;
11    fn printf(_: *const libc::c_char, _: ...) -> libc::c_int;
12    fn snprintf(
13        _: *mut libc::c_char,
14        _: libc::c_ulong,
15        _: *const libc::c_char,
16        _: ...
17    ) -> libc::c_int;
18    fn fgets(
19        __s: *mut libc::c_char,
20        __n: libc::c_int,
21        __stream: *mut FILE,
22    ) -> *mut libc::c_char;
23    fn fread(
24        _: *mut libc::c_void,
25        _: libc::c_ulong,
26        _: libc::c_ulong,
27        _: *mut FILE,
28    ) -> libc::c_ulong;
29    fn fseek(
30        __stream: *mut FILE,
31        __off: libc::c_long,
32        __whence: libc::c_int,
33    ) -> libc::c_int;
34    fn ftello(__stream: *mut FILE) -> __off64_t;
35    fn feof(__stream: *mut FILE) -> libc::c_int;
36    fn fileno(__stream: *mut FILE) -> libc::c_int;
37    fn sdsfree(s: sds);
38    fn __errno_location() -> *mut libc::c_int;
39    fn strtol(
40        _: *const libc::c_char,
41        _: *mut *mut libc::c_char,
42        _: libc::c_int,
43    ) -> libc::c_long;
44    fn exit(_: libc::c_int) -> !;
45    fn memcpy(
46        _: *mut libc::c_void,
47        _: *const libc::c_void,
48        _: libc::c_ulong,
49    ) -> *mut libc::c_void;
50    fn memcmp(
51        _: *const libc::c_void,
52        _: *const libc::c_void,
53        _: libc::c_ulong,
54    ) -> libc::c_int;
55    fn strcmp(_: *const libc::c_char, _: *const libc::c_char) -> libc::c_int;
56    fn strncmp(
57        _: *const libc::c_char,
58        _: *const libc::c_char,
59        _: libc::c_ulong,
60    ) -> libc::c_int;
61    fn strlen(_: *const libc::c_char) -> libc::c_ulong;
62    fn strerror(_: libc::c_int) -> *mut libc::c_char;
63    fn strcasecmp(__s1: *const libc::c_char, __s2: *const libc::c_char) -> libc::c_int;
64    fn strncasecmp(
65        __s1: *const libc::c_char,
66        __s2: *const libc::c_char,
67        __n: size_t,
68    ) -> libc::c_int;
69    fn ftruncate(__fd: libc::c_int, __length: __off64_t) -> libc::c_int;
70    fn listNext(iter: *mut listIter) -> *mut listNode;
71    fn listRewind(list: *mut list, li: *mut listIter);
72    fn zmalloc(size: size_t) -> *mut libc::c_void;
73    fn zfree(ptr: *mut libc::c_void);
74    fn makePath(path: *mut libc::c_char, filename: *mut libc::c_char) -> sds;
75    fn aofManifestFree(am: *mut aofManifest);
76    fn redis_check_rdb_main(
77        argc: libc::c_int,
78        argv: *mut *mut libc::c_char,
79        fp: *mut FILE,
80    ) -> libc::c_int;
81    fn __fxstat(
82        __ver: libc::c_int,
83        __fildes: libc::c_int,
84        __stat_buf: *mut stat,
85    ) -> libc::c_int;
86    fn dirname(__path: *mut libc::c_char) -> *mut libc::c_char;
87    fn aofLoadManifestFromFile(am_filepath: sds) -> *mut aofManifest;
88}
89pub type __dev_t = libc::c_ulong;
90pub type __uid_t = libc::c_uint;
91pub type __gid_t = libc::c_uint;
92pub type __ino64_t = libc::c_ulong;
93pub type __mode_t = libc::c_uint;
94pub type __nlink_t = libc::c_uint;
95pub type __off_t = libc::c_long;
96pub type __off64_t = libc::c_long;
97pub type __time_t = libc::c_long;
98pub type __blksize_t = libc::c_int;
99pub type __blkcnt64_t = libc::c_long;
100pub type __syscall_slong_t = libc::c_long;
101pub type size_t = libc::c_ulong;
102pub type off_t = __off64_t;
103#[derive(Copy, Clone)]
104#[repr(C)]
105pub struct timespec {
106    pub tv_sec: __time_t,
107    pub tv_nsec: __syscall_slong_t,
108}
109#[derive(Copy, Clone)]
110#[repr(C)]
111pub struct stat {
112    pub st_dev: __dev_t,
113    pub st_ino: __ino64_t,
114    pub st_mode: __mode_t,
115    pub st_nlink: __nlink_t,
116    pub st_uid: __uid_t,
117    pub st_gid: __gid_t,
118    pub st_rdev: __dev_t,
119    pub __pad1: __dev_t,
120    pub st_size: __off64_t,
121    pub st_blksize: __blksize_t,
122    pub __pad2: libc::c_int,
123    pub st_blocks: __blkcnt64_t,
124    pub st_atim: timespec,
125    pub st_mtim: timespec,
126    pub st_ctim: timespec,
127    pub __glibc_reserved: [libc::c_int; 2],
128}
129pub type time_t = __time_t;
130#[derive(Copy, Clone)]
131#[repr(C)]
132pub struct _IO_FILE {
133    pub _flags: libc::c_int,
134    pub _IO_read_ptr: *mut libc::c_char,
135    pub _IO_read_end: *mut libc::c_char,
136    pub _IO_read_base: *mut libc::c_char,
137    pub _IO_write_base: *mut libc::c_char,
138    pub _IO_write_ptr: *mut libc::c_char,
139    pub _IO_write_end: *mut libc::c_char,
140    pub _IO_buf_base: *mut libc::c_char,
141    pub _IO_buf_end: *mut libc::c_char,
142    pub _IO_save_base: *mut libc::c_char,
143    pub _IO_backup_base: *mut libc::c_char,
144    pub _IO_save_end: *mut libc::c_char,
145    pub _markers: *mut _IO_marker,
146    pub _chain: *mut _IO_FILE,
147    pub _fileno: libc::c_int,
148    pub _flags2: libc::c_int,
149    pub _old_offset: __off_t,
150    pub _cur_column: libc::c_ushort,
151    pub _vtable_offset: libc::c_schar,
152    pub _shortbuf: [libc::c_char; 1],
153    pub _lock: *mut libc::c_void,
154    pub _offset: __off64_t,
155    pub _codecvt: *mut _IO_codecvt,
156    pub _wide_data: *mut _IO_wide_data,
157    pub _freeres_list: *mut _IO_FILE,
158    pub _freeres_buf: *mut libc::c_void,
159    pub __pad5: size_t,
160    pub _mode: libc::c_int,
161    pub _unused2: [libc::c_char; 20],
162}
163pub type _IO_lock_t = ();
164pub type FILE = _IO_FILE;
165pub type sds = *mut libc::c_char;
166#[derive(Copy, Clone)]
167#[repr(C)]
168pub struct listNode {
169    pub prev: *mut listNode,
170    pub next: *mut listNode,
171    pub value: *mut libc::c_void,
172}
173#[derive(Copy, Clone)]
174#[repr(C)]
175pub struct listIter {
176    pub next: *mut listNode,
177    pub direction: libc::c_int,
178}
179#[derive(Copy, Clone)]
180#[repr(C)]
181pub struct list {
182    pub head: *mut listNode,
183    pub tail: *mut listNode,
184    pub dup: Option::<unsafe extern "C" fn(*mut libc::c_void) -> *mut libc::c_void>,
185    pub free: Option::<unsafe extern "C" fn(*mut libc::c_void) -> ()>,
186    pub match_0: Option::<
187        unsafe extern "C" fn(*mut libc::c_void, *mut libc::c_void) -> libc::c_int,
188    >,
189    pub len: libc::c_ulong,
190}
191pub type aof_file_type = libc::c_uint;
192pub const AOF_FILE_TYPE_INCR: aof_file_type = 105;
193pub const AOF_FILE_TYPE_HIST: aof_file_type = 104;
194pub const AOF_FILE_TYPE_BASE: aof_file_type = 98;
195#[derive(Copy, Clone)]
196#[repr(C)]
197pub struct aofInfo {
198    pub file_name: sds,
199    pub file_seq: libc::c_longlong,
200    pub file_type: aof_file_type,
201}
202#[derive(Copy, Clone)]
203#[repr(C)]
204pub struct aofManifest {
205    pub base_aof_info: *mut aofInfo,
206    pub incr_aof_list: *mut list,
207    pub history_aof_list: *mut list,
208    pub curr_base_file_seq: libc::c_longlong,
209    pub curr_incr_file_seq: libc::c_longlong,
210    pub dirty: libc::c_int,
211}
212pub const AOF_RDB_PREAMBLE: input_file_type = 1;
213pub const AOF_RESP: input_file_type = 0;
214pub const AOF_MULTI_PART: input_file_type = 2;
215pub type input_file_type = libc::c_uint;
216#[inline]
217unsafe extern "C" fn fstat(
218    mut __fd: libc::c_int,
219    mut __statbuf: *mut stat,
220) -> libc::c_int {
221    return __fxstat(0 as libc::c_int, __fd, __statbuf);
222}
223static mut error: [libc::c_char; 1044] = [0; 1044];
224static mut epos: off_t = 0;
225static mut line: libc::c_longlong = 1 as libc::c_int as libc::c_longlong;
226static mut to_timestamp: time_t = 0 as libc::c_int as time_t;
227#[no_mangle]
228pub unsafe extern "C" fn consumeNewline(mut buf: *mut libc::c_char) -> libc::c_int {
229    if strncmp(
230        buf,
231        b"\r\n\0" as *const u8 as *const libc::c_char,
232        2 as libc::c_int as libc::c_ulong,
233    ) != 0 as libc::c_int
234    {
235        let mut __buf: [libc::c_char; 1024] = [0; 1024];
236        snprintf(
237            __buf.as_mut_ptr(),
238            core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
239            b"Expected \\r\\n, got: %02x%02x\0" as *const u8 as *const libc::c_char,
240            *buf.offset(0 as libc::c_int as isize) as libc::c_int,
241            *buf.offset(1 as libc::c_int as isize) as libc::c_int,
242        );
243        snprintf(
244            error.as_mut_ptr(),
245            core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
246            b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
247            epos as libc::c_longlong,
248            __buf.as_mut_ptr(),
249        );
250        return 0 as libc::c_int;
251    }
252    line += 1 as libc::c_int as libc::c_longlong;
253    return 1 as libc::c_int;
254}
255#[no_mangle]
256pub unsafe extern "C" fn readLong(
257    mut fp: *mut FILE,
258    mut prefix: libc::c_char,
259    mut target: *mut libc::c_long,
260) -> libc::c_int {
261    let mut buf: [libc::c_char; 128] = [0; 128];
262    let mut eptr: *mut libc::c_char = 0 as *mut libc::c_char;
263    epos = ftello(fp);
264    if (fgets(
265        buf.as_mut_ptr(),
266        core::mem::size_of::<[libc::c_char; 128]>() as libc::c_ulong as libc::c_int,
267        fp,
268    ))
269        .is_null()
270    {
271        return 0 as libc::c_int;
272    }
273    if buf[0 as libc::c_int as usize] as libc::c_int != prefix as libc::c_int {
274        let mut __buf: [libc::c_char; 1024] = [0; 1024];
275        snprintf(
276            __buf.as_mut_ptr(),
277            core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
278            b"Expected prefix '%c', got: '%c'\0" as *const u8 as *const libc::c_char,
279            prefix as libc::c_int,
280            buf[0 as libc::c_int as usize] as libc::c_int,
281        );
282        snprintf(
283            error.as_mut_ptr(),
284            core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
285            b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
286            epos as libc::c_longlong,
287            __buf.as_mut_ptr(),
288        );
289        return 0 as libc::c_int;
290    }
291    *target = strtol(
292        buf.as_mut_ptr().offset(1 as libc::c_int as isize),
293        &mut eptr,
294        10 as libc::c_int,
295    );
296    return consumeNewline(eptr);
297}
298#[no_mangle]
299pub unsafe extern "C" fn readBytes(
300    mut fp: *mut FILE,
301    mut target: *mut libc::c_char,
302    mut length: libc::c_long,
303) -> libc::c_int {
304    let mut real: libc::c_long = 0;
305    epos = ftello(fp);
306    real = fread(
307        target as *mut libc::c_void,
308        1 as libc::c_int as libc::c_ulong,
309        length as libc::c_ulong,
310        fp,
311    ) as libc::c_long;
312    if real != length {
313        let mut __buf: [libc::c_char; 1024] = [0; 1024];
314        snprintf(
315            __buf.as_mut_ptr(),
316            core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
317            b"Expected to read %ld bytes, got %ld bytes\0" as *const u8
318                as *const libc::c_char,
319            length,
320            real,
321        );
322        snprintf(
323            error.as_mut_ptr(),
324            core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
325            b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
326            epos as libc::c_longlong,
327            __buf.as_mut_ptr(),
328        );
329        return 0 as libc::c_int;
330    }
331    return 1 as libc::c_int;
332}
333#[no_mangle]
334pub unsafe extern "C" fn readString(
335    mut fp: *mut FILE,
336    mut target: *mut *mut libc::c_char,
337) -> libc::c_int {
338    let mut len: libc::c_long = 0;
339    *target = 0 as *mut libc::c_char;
340    if readLong(fp, '$' as i32 as libc::c_char, &mut len) == 0 {
341        return 0 as libc::c_int;
342    }
343    if len < 0 as libc::c_int as libc::c_long
344        || len > 9223372036854775807 as libc::c_long - 2 as libc::c_int as libc::c_long
345    {
346        let mut __buf: [libc::c_char; 1024] = [0; 1024];
347        snprintf(
348            __buf.as_mut_ptr(),
349            core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
350            b"Expected to read string of %ld bytes, which is not in the suitable range\0"
351                as *const u8 as *const libc::c_char,
352            len,
353        );
354        snprintf(
355            error.as_mut_ptr(),
356            core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
357            b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
358            epos as libc::c_longlong,
359            __buf.as_mut_ptr(),
360        );
361        return 0 as libc::c_int;
362    }
363    len += 2 as libc::c_int as libc::c_long;
364    *target = zmalloc(len as size_t) as *mut libc::c_char;
365    if readBytes(fp, *target, len) == 0 {
366        zfree(*target as *mut libc::c_void);
367        *target = 0 as *mut libc::c_char;
368        return 0 as libc::c_int;
369    }
370    if consumeNewline(
371        (*target).offset(len as isize).offset(-(2 as libc::c_int as isize)),
372    ) == 0
373    {
374        zfree(*target as *mut libc::c_void);
375        *target = 0 as *mut libc::c_char;
376        return 0 as libc::c_int;
377    }
378    *(*target)
379        .offset(
380            (len - 2 as libc::c_int as libc::c_long) as isize,
381        ) = '\0' as i32 as libc::c_char;
382    return 1 as libc::c_int;
383}
384#[no_mangle]
385pub unsafe extern "C" fn readArgc(
386    mut fp: *mut FILE,
387    mut target: *mut libc::c_long,
388) -> libc::c_int {
389    return readLong(fp, '*' as i32 as libc::c_char, target);
390}
391#[no_mangle]
392pub unsafe extern "C" fn processRESP(
393    mut fp: *mut FILE,
394    mut filename: *mut libc::c_char,
395    mut out_multi: *mut libc::c_int,
396) -> libc::c_int {
397    let mut argc: libc::c_long = 0;
398    let mut str: *mut libc::c_char = 0 as *mut libc::c_char;
399    if readArgc(fp, &mut argc) == 0 {
400        return 0 as libc::c_int;
401    }
402    let mut i: libc::c_int = 0 as libc::c_int;
403    while (i as libc::c_long) < argc {
404        if readString(fp, &mut str) == 0 {
405            return 0 as libc::c_int;
406        }
407        if i == 0 as libc::c_int {
408            if strcasecmp(str, b"multi\0" as *const u8 as *const libc::c_char)
409                == 0 as libc::c_int
410            {
411                let fresh0 = *out_multi;
412                *out_multi = *out_multi + 1;
413                if fresh0 != 0 {
414                    let mut __buf: [libc::c_char; 1024] = [0; 1024];
415                    snprintf(
416                        __buf.as_mut_ptr(),
417                        core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
418                        b"Unexpected MULTI in AOF %s\0" as *const u8
419                            as *const libc::c_char,
420                        filename,
421                    );
422                    snprintf(
423                        error.as_mut_ptr(),
424                        core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
425                        b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
426                        epos as libc::c_longlong,
427                        __buf.as_mut_ptr(),
428                    );
429                    zfree(str as *mut libc::c_void);
430                    return 0 as libc::c_int;
431                }
432            } else if strcasecmp(str, b"exec\0" as *const u8 as *const libc::c_char)
433                == 0 as libc::c_int
434            {
435                *out_multi -= 1;
436                if *out_multi != 0 {
437                    let mut __buf_0: [libc::c_char; 1024] = [0; 1024];
438                    snprintf(
439                        __buf_0.as_mut_ptr(),
440                        core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
441                        b"Unexpected EXEC in AOF %s\0" as *const u8
442                            as *const libc::c_char,
443                        filename,
444                    );
445                    snprintf(
446                        error.as_mut_ptr(),
447                        core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
448                        b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
449                        epos as libc::c_longlong,
450                        __buf_0.as_mut_ptr(),
451                    );
452                    zfree(str as *mut libc::c_void);
453                    return 0 as libc::c_int;
454                }
455            }
456        }
457        zfree(str as *mut libc::c_void);
458        i += 1;
459    }
460    return 1 as libc::c_int;
461}
462#[no_mangle]
463pub unsafe extern "C" fn processAnnotations(
464    mut fp: *mut FILE,
465    mut filename: *mut libc::c_char,
466    mut last_file: libc::c_int,
467) -> libc::c_int {
468    let mut buf: [libc::c_char; 1024] = [0; 1024];
469    epos = ftello(fp);
470    if (fgets(
471        buf.as_mut_ptr(),
472        core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong as libc::c_int,
473        fp,
474    ))
475        .is_null()
476    {
477        printf(
478            b"Failed to read annotations from AOF %s, aborting...\n\0" as *const u8
479                as *const libc::c_char,
480            filename,
481        );
482        exit(1 as libc::c_int);
483    }
484    if to_timestamp != 0
485        && strncmp(
486            buf.as_mut_ptr(),
487            b"#TS:\0" as *const u8 as *const libc::c_char,
488            4 as libc::c_int as libc::c_ulong,
489        ) == 0 as libc::c_int
490    {
491        let mut endptr: *mut libc::c_char = 0 as *mut libc::c_char;
492        *__errno_location() = 0 as libc::c_int;
493        let mut ts: time_t = strtol(
494            buf.as_mut_ptr().offset(4 as libc::c_int as isize),
495            &mut endptr,
496            10 as libc::c_int,
497        );
498        if *__errno_location() != 0 as libc::c_int
499            || *endptr as libc::c_int != '\r' as i32
500        {
501            printf(
502                b"Invalid timestamp annotation\n\0" as *const u8 as *const libc::c_char,
503            );
504            exit(1 as libc::c_int);
505        }
506        if ts <= to_timestamp {
507            return 1 as libc::c_int;
508        }
509        if epos == 0 as libc::c_int as libc::c_long {
510            printf(
511                b"AOF %s has nothing before timestamp %ld, aborting...\n\0" as *const u8
512                    as *const libc::c_char,
513                filename,
514                to_timestamp,
515            );
516            exit(1 as libc::c_int);
517        }
518        if last_file == 0 {
519            printf(
520                b"Failed to truncate AOF %s to timestamp %ld to offset %ld because it is not the last file.\n\0"
521                    as *const u8 as *const libc::c_char,
522                filename,
523                to_timestamp,
524                epos,
525            );
526            printf(
527                b"If you insist, please delete all files after this file according to the manifest file and delete the corresponding records in manifest file manually. Then re-run redis-check-aof.\n\0"
528                    as *const u8 as *const libc::c_char,
529            );
530            exit(1 as libc::c_int);
531        }
532        if ftruncate(fileno(fp), epos) == -(1 as libc::c_int) {
533            printf(
534                b"Failed to truncate AOF %s to timestamp %ld\n\0" as *const u8
535                    as *const libc::c_char,
536                filename,
537                to_timestamp,
538            );
539            exit(1 as libc::c_int);
540        } else {
541            return 0 as libc::c_int
542        }
543    }
544    return 1 as libc::c_int;
545}
546#[no_mangle]
547pub unsafe extern "C" fn checkSingleAof(
548    mut aof_filename: *mut libc::c_char,
549    mut aof_filepath: *mut libc::c_char,
550    mut last_file: libc::c_int,
551    mut fix: libc::c_int,
552    mut preamble: libc::c_int,
553) -> libc::c_int {
554    let mut pos: off_t = 0 as libc::c_int as off_t;
555    let mut diff: off_t = 0;
556    let mut multi: libc::c_int = 0 as libc::c_int;
557    let mut buf: [libc::c_char; 2] = [0; 2];
558    let mut fp: *mut FILE = fopen(
559        aof_filepath,
560        b"r+\0" as *const u8 as *const libc::c_char,
561    );
562    if fp.is_null() {
563        printf(
564            b"Cannot open file %s: %s, aborting...\n\0" as *const u8
565                as *const libc::c_char,
566            aof_filepath,
567            strerror(*__errno_location()),
568        );
569        exit(1 as libc::c_int);
570    }
571    let mut sb: stat = stat {
572        st_dev: 0,
573        st_ino: 0,
574        st_mode: 0,
575        st_nlink: 0,
576        st_uid: 0,
577        st_gid: 0,
578        st_rdev: 0,
579        __pad1: 0,
580        st_size: 0,
581        st_blksize: 0,
582        __pad2: 0,
583        st_blocks: 0,
584        st_atim: timespec { tv_sec: 0, tv_nsec: 0 },
585        st_mtim: timespec { tv_sec: 0, tv_nsec: 0 },
586        st_ctim: timespec { tv_sec: 0, tv_nsec: 0 },
587        __glibc_reserved: [0; 2],
588    };
589    if fstat(fileno(fp), &mut sb) == -(1 as libc::c_int) {
590        printf(
591            b"Cannot stat file: %s, aborting...\n\0" as *const u8 as *const libc::c_char,
592            aof_filename,
593        );
594        exit(1 as libc::c_int);
595    }
596    let mut size: off_t = sb.st_size;
597    if size == 0 as libc::c_int as libc::c_long {
598        return 1 as libc::c_int;
599    }
600    if preamble != 0 {
601        let mut argv: [*mut libc::c_char; 2] = [0 as *mut libc::c_char, aof_filename];
602        if redis_check_rdb_main(2 as libc::c_int, argv.as_mut_ptr(), fp)
603            == -(1 as libc::c_int)
604        {
605            printf(
606                b"RDB preamble of AOF file is not sane, aborting.\n\0" as *const u8
607                    as *const libc::c_char,
608            );
609            exit(1 as libc::c_int);
610        } else {
611            printf(
612                b"RDB preamble is OK, proceeding with AOF tail...\n\0" as *const u8
613                    as *const libc::c_char,
614            );
615        }
616    }
617    loop {
618        if multi == 0 {
619            pos = ftello(fp);
620        }
621        if (fgets(
622            buf.as_mut_ptr(),
623            core::mem::size_of::<[libc::c_char; 2]>() as libc::c_ulong as libc::c_int,
624            fp,
625        ))
626            .is_null()
627        {
628            if feof(fp) != 0 {
629                break;
630            }
631            printf(
632                b"Failed to read from AOF %s, aborting...\n\0" as *const u8
633                    as *const libc::c_char,
634                aof_filename,
635            );
636            exit(1 as libc::c_int);
637        } else {
638            if fseek(fp, -(1 as libc::c_int) as libc::c_long, 1 as libc::c_int)
639                == -(1 as libc::c_int)
640            {
641                printf(
642                    b"Failed to fseek in AOF %s: %s\0" as *const u8
643                        as *const libc::c_char,
644                    aof_filename,
645                    strerror(*__errno_location()),
646                );
647                exit(1 as libc::c_int);
648            }
649            if buf[0 as libc::c_int as usize] as libc::c_int == '#' as i32 {
650                if processAnnotations(fp, aof_filepath, last_file) == 0 {
651                    fclose(fp);
652                    return 3 as libc::c_int;
653                }
654            } else if buf[0 as libc::c_int as usize] as libc::c_int == '*' as i32 {
655                if processRESP(fp, aof_filepath, &mut multi) == 0 {
656                    break;
657                }
658            } else {
659                printf(
660                    b"AOF %s format error\n\0" as *const u8 as *const libc::c_char,
661                    aof_filename,
662                );
663                break;
664            }
665        }
666    }
667    if feof(fp) != 0 && multi != 0
668        && strlen(error.as_mut_ptr()) == 0 as libc::c_int as libc::c_ulong
669    {
670        let mut __buf: [libc::c_char; 1024] = [0; 1024];
671        snprintf(
672            __buf.as_mut_ptr(),
673            core::mem::size_of::<[libc::c_char; 1024]>() as libc::c_ulong,
674            b"Reached EOF before reading EXEC for MULTI\0" as *const u8
675                as *const libc::c_char,
676        );
677        snprintf(
678            error.as_mut_ptr(),
679            core::mem::size_of::<[libc::c_char; 1044]>() as libc::c_ulong,
680            b"0x%16llx: %s\0" as *const u8 as *const libc::c_char,
681            epos as libc::c_longlong,
682            __buf.as_mut_ptr(),
683        );
684    }
685    if strlen(error.as_mut_ptr()) > 0 as libc::c_int as libc::c_ulong {
686        printf(b"%s\n\0" as *const u8 as *const libc::c_char, error.as_mut_ptr());
687    }
688    diff = size - pos;
689    if diff == 0 as libc::c_int as libc::c_long && to_timestamp != 0 {
690        printf(
691            b"Truncate nothing in AOF %s to timestamp %ld\n\0" as *const u8
692                as *const libc::c_char,
693            aof_filename,
694            to_timestamp,
695        );
696        fclose(fp);
697        return 0 as libc::c_int;
698    }
699    printf(
700        b"AOF analyzed: filename=%s, size=%lld, ok_up_to=%lld, ok_up_to_line=%lld, diff=%lld\n\0"
701            as *const u8 as *const libc::c_char,
702        aof_filename,
703        size as libc::c_longlong,
704        pos as libc::c_longlong,
705        line,
706        diff as libc::c_longlong,
707    );
708    if diff > 0 as libc::c_int as libc::c_long {
709        if fix != 0 {
710            if last_file == 0 {
711                printf(
712                    b"Failed to truncate AOF %s because it is not the last file\n\0"
713                        as *const u8 as *const libc::c_char,
714                    aof_filename,
715                );
716                exit(1 as libc::c_int);
717            }
718            let mut buf_0: [libc::c_char; 2] = [0; 2];
719            printf(
720                b"This will shrink the AOF %s from %lld bytes, with %lld bytes, to %lld bytes\n\0"
721                    as *const u8 as *const libc::c_char,
722                aof_filename,
723                size as libc::c_longlong,
724                diff as libc::c_longlong,
725                pos as libc::c_longlong,
726            );
727            printf(b"Continue? [y/N]: \0" as *const u8 as *const libc::c_char);
728            if (fgets(
729                buf_0.as_mut_ptr(),
730                core::mem::size_of::<[libc::c_char; 2]>() as libc::c_ulong
731                    as libc::c_int,
732                stdin,
733            ))
734                .is_null()
735                || strncasecmp(
736                    buf_0.as_mut_ptr(),
737                    b"y\0" as *const u8 as *const libc::c_char,
738                    1 as libc::c_int as size_t,
739                ) != 0 as libc::c_int
740            {
741                printf(b"Aborting...\n\0" as *const u8 as *const libc::c_char);
742                exit(1 as libc::c_int);
743            }
744            if ftruncate(fileno(fp), pos) == -(1 as libc::c_int) {
745                printf(
746                    b"Failed to truncate AOF %s\n\0" as *const u8 as *const libc::c_char,
747                    aof_filename,
748                );
749                exit(1 as libc::c_int);
750            } else {
751                fclose(fp);
752                return 2 as libc::c_int;
753            }
754        } else {
755            printf(
756                b"AOF %s is not valid. Use the --fix option to try fixing it.\n\0"
757                    as *const u8 as *const libc::c_char,
758                aof_filename,
759            );
760            exit(1 as libc::c_int);
761        }
762    }
763    fclose(fp);
764    return 0 as libc::c_int;
765}
766#[no_mangle]
767pub unsafe extern "C" fn fileIsRDB(mut filepath: *mut libc::c_char) -> libc::c_int {
768    let mut fp: *mut FILE = fopen(filepath, b"r\0" as *const u8 as *const libc::c_char);
769    if fp.is_null() {
770        printf(
771            b"Cannot open file %s: %s\n\0" as *const u8 as *const libc::c_char,
772            filepath,
773            strerror(*__errno_location()),
774        );
775        exit(1 as libc::c_int);
776    }
777    let mut sb: stat = stat {
778        st_dev: 0,
779        st_ino: 0,
780        st_mode: 0,
781        st_nlink: 0,
782        st_uid: 0,
783        st_gid: 0,
784        st_rdev: 0,
785        __pad1: 0,
786        st_size: 0,
787        st_blksize: 0,
788        __pad2: 0,
789        st_blocks: 0,
790        st_atim: timespec { tv_sec: 0, tv_nsec: 0 },
791        st_mtim: timespec { tv_sec: 0, tv_nsec: 0 },
792        st_ctim: timespec { tv_sec: 0, tv_nsec: 0 },
793        __glibc_reserved: [0; 2],
794    };
795    if fstat(fileno(fp), &mut sb) == -(1 as libc::c_int) {
796        printf(
797            b"Cannot stat file: %s\n\0" as *const u8 as *const libc::c_char,
798            filepath,
799        );
800        exit(1 as libc::c_int);
801    }
802    let mut size: off_t = sb.st_size;
803    if size == 0 as libc::c_int as libc::c_long {
804        fclose(fp);
805        return 0 as libc::c_int;
806    }
807    if size >= 8 as libc::c_int as libc::c_long {
808        let mut sig: [libc::c_char; 5] = [0; 5];
809        let mut rdb_file: libc::c_int = (fread(
810            sig.as_mut_ptr() as *mut libc::c_void,
811            core::mem::size_of::<[libc::c_char; 5]>() as libc::c_ulong,
812            1 as libc::c_int as libc::c_ulong,
813            fp,
814        ) == 1 as libc::c_int as libc::c_ulong
815            && memcmp(
816                sig.as_mut_ptr() as *const libc::c_void,
817                b"REDIS\0" as *const u8 as *const libc::c_char as *const libc::c_void,
818                core::mem::size_of::<[libc::c_char; 5]>() as libc::c_ulong,
819            ) == 0 as libc::c_int) as libc::c_int;
820        if rdb_file != 0 {
821            fclose(fp);
822            return 1 as libc::c_int;
823        }
824    }
825    fclose(fp);
826    return 0 as libc::c_int;
827}
828#[no_mangle]
829pub unsafe extern "C" fn fileIsManifest(mut filepath: *mut libc::c_char) -> libc::c_int {
830    let mut is_manifest: libc::c_int = 0 as libc::c_int;
831    let mut fp: *mut FILE = fopen(filepath, b"r\0" as *const u8 as *const libc::c_char);
832    if fp.is_null() {
833        printf(
834            b"Cannot open file %s: %s\n\0" as *const u8 as *const libc::c_char,
835            filepath,
836            strerror(*__errno_location()),
837        );
838        exit(1 as libc::c_int);
839    }
840    let mut sb: stat = stat {
841        st_dev: 0,
842        st_ino: 0,
843        st_mode: 0,
844        st_nlink: 0,
845        st_uid: 0,
846        st_gid: 0,
847        st_rdev: 0,
848        __pad1: 0,
849        st_size: 0,
850        st_blksize: 0,
851        __pad2: 0,
852        st_blocks: 0,
853        st_atim: timespec { tv_sec: 0, tv_nsec: 0 },
854        st_mtim: timespec { tv_sec: 0, tv_nsec: 0 },
855        st_ctim: timespec { tv_sec: 0, tv_nsec: 0 },
856        __glibc_reserved: [0; 2],
857    };
858    if fstat(fileno(fp), &mut sb) == -(1 as libc::c_int) {
859        printf(
860            b"Cannot stat file: %s\n\0" as *const u8 as *const libc::c_char,
861            filepath,
862        );
863        exit(1 as libc::c_int);
864    }
865    let mut size: off_t = sb.st_size;
866    if size == 0 as libc::c_int as libc::c_long {
867        fclose(fp);
868        return 0 as libc::c_int;
869    }
870    let mut buf: [libc::c_char; 1025] = [0; 1025];
871    loop {
872        if (fgets(buf.as_mut_ptr(), 1024 as libc::c_int + 1 as libc::c_int, fp))
873            .is_null()
874        {
875            if feof(fp) != 0 {
876                break;
877            }
878            printf(
879                b"Cannot read file: %s\n\0" as *const u8 as *const libc::c_char,
880                filepath,
881            );
882            exit(1 as libc::c_int);
883        } else {
884            if buf[0 as libc::c_int as usize] as libc::c_int == '#' as i32 {
885                continue;
886            }
887            if memcmp(
888                buf.as_mut_ptr() as *const libc::c_void,
889                b"file\0" as *const u8 as *const libc::c_char as *const libc::c_void,
890                strlen(b"file\0" as *const u8 as *const libc::c_char),
891            ) == 0
892            {
893                is_manifest = 1 as libc::c_int;
894            }
895        }
896    }
897    fclose(fp);
898    return is_manifest;
899}
900#[no_mangle]
901pub unsafe extern "C" fn getInputFileType(
902    mut filepath: *mut libc::c_char,
903) -> input_file_type {
904    if fileIsManifest(filepath) != 0 {
905        return AOF_MULTI_PART
906    } else if fileIsRDB(filepath) != 0 {
907        return AOF_RDB_PREAMBLE
908    } else {
909        return AOF_RESP
910    };
911}
912#[no_mangle]
913pub unsafe extern "C" fn checkMultiPartAof(
914    mut dirpath: *mut libc::c_char,
915    mut manifest_filepath: *mut libc::c_char,
916    mut fix: libc::c_int,
917) {
918    let mut total_num: libc::c_int = 0 as libc::c_int;
919    let mut aof_num: libc::c_int = 0 as libc::c_int;
920    let mut last_file: libc::c_int = 0;
921    let mut ret: libc::c_int = 0;
922    printf(b"Start checking Multi Part AOF\n\0" as *const u8 as *const libc::c_char);
923    let mut am: *mut aofManifest = aofLoadManifestFromFile(manifest_filepath);
924    if !((*am).base_aof_info).is_null() {
925        total_num += 1;
926    }
927    if !((*am).incr_aof_list).is_null() {
928        total_num = (total_num as libc::c_ulong).wrapping_add((*(*am).incr_aof_list).len)
929            as libc::c_int as libc::c_int;
930    }
931    if !((*am).base_aof_info).is_null() {
932        let mut aof_filename: sds = (*(*am).base_aof_info).file_name;
933        let mut aof_filepath: sds = makePath(dirpath, aof_filename);
934        aof_num += 1;
935        last_file = (aof_num == total_num) as libc::c_int;
936        let mut aof_preable: libc::c_int = fileIsRDB(aof_filepath);
937        printf(
938            b"Start to check BASE AOF (%s format).\n\0" as *const u8
939                as *const libc::c_char,
940            if aof_preable != 0 {
941                b"RDB\0" as *const u8 as *const libc::c_char
942            } else {
943                b"RESP\0" as *const u8 as *const libc::c_char
944            },
945        );
946        ret = checkSingleAof(aof_filename, aof_filepath, last_file, fix, aof_preable);
947        if ret == 0 as libc::c_int {
948            printf(
949                b"BASE AOF %s is valid\n\0" as *const u8 as *const libc::c_char,
950                aof_filename,
951            );
952        } else if ret == 1 as libc::c_int {
953            printf(
954                b"BASE AOF %s is empty\n\0" as *const u8 as *const libc::c_char,
955                aof_filename,
956            );
957        } else if ret == 3 as libc::c_int {
958            printf(
959                b"Successfully truncated AOF %s to timestamp %ld\n\0" as *const u8
960                    as *const libc::c_char,
961                aof_filename,
962                to_timestamp,
963            );
964        } else if ret == 2 as libc::c_int {
965            printf(
966                b"Successfully truncated AOF %s\n\0" as *const u8 as *const libc::c_char,
967                aof_filename,
968            );
969        }
970        sdsfree(aof_filepath);
971    }
972    if (*(*am).incr_aof_list).len != 0 {
973        let mut ln: *mut listNode = 0 as *mut listNode;
974        let mut li: listIter = listIter {
975            next: 0 as *mut listNode,
976            direction: 0,
977        };
978        printf(b"Start to check INCR files.\n\0" as *const u8 as *const libc::c_char);
979        listRewind((*am).incr_aof_list, &mut li);
980        loop {
981            ln = listNext(&mut li);
982            if ln.is_null() {
983                break;
984            }
985            let mut ai: *mut aofInfo = (*ln).value as *mut aofInfo;
986            let mut aof_filename_0: sds = (*ai).file_name;
987            let mut aof_filepath_0: sds = makePath(dirpath, aof_filename_0);
988            aof_num += 1;
989            last_file = (aof_num == total_num) as libc::c_int;
990            ret = checkSingleAof(
991                aof_filename_0,
992                aof_filepath_0,
993                last_file,
994                fix,
995                0 as libc::c_int,
996            );
997            if ret == 0 as libc::c_int {
998                printf(
999                    b"INCR AOF %s is valid\n\0" as *const u8 as *const libc::c_char,
1000                    aof_filename_0,
1001                );
1002            } else if ret == 1 as libc::c_int {
1003                printf(
1004                    b"INCR AOF %s is empty\n\0" as *const u8 as *const libc::c_char,
1005                    aof_filename_0,
1006                );
1007            } else if ret == 3 as libc::c_int {
1008                printf(
1009                    b"Successfully truncated AOF %s to timestamp %ld\n\0" as *const u8
1010                        as *const libc::c_char,
1011                    aof_filename_0,
1012                    to_timestamp,
1013                );
1014            } else if ret == 2 as libc::c_int {
1015                printf(
1016                    b"Successfully truncated AOF %s\n\0" as *const u8
1017                        as *const libc::c_char,
1018                    aof_filename_0,
1019                );
1020            }
1021            sdsfree(aof_filepath_0);
1022        }
1023    }
1024    aofManifestFree(am);
1025    printf(
1026        b"All AOF files and manifest are valid\n\0" as *const u8 as *const libc::c_char,
1027    );
1028}
1029#[no_mangle]
1030pub unsafe extern "C" fn checkOldStyleAof(
1031    mut filepath: *mut libc::c_char,
1032    mut fix: libc::c_int,
1033    mut preamble: libc::c_int,
1034) {
1035    printf(b"Start checking Old-Style AOF\n\0" as *const u8 as *const libc::c_char);
1036    let mut ret: libc::c_int = checkSingleAof(
1037        filepath,
1038        filepath,
1039        1 as libc::c_int,
1040        fix,
1041        preamble,
1042    );
1043    if ret == 0 as libc::c_int {
1044        printf(b"AOF %s is valid\n\0" as *const u8 as *const libc::c_char, filepath);
1045    } else if ret == 1 as libc::c_int {
1046        printf(b"AOF %s is empty\n\0" as *const u8 as *const libc::c_char, filepath);
1047    } else if ret == 3 as libc::c_int {
1048        printf(
1049            b"Successfully truncated AOF %s to timestamp %ld\n\0" as *const u8
1050                as *const libc::c_char,
1051            filepath,
1052            to_timestamp,
1053        );
1054    } else if ret == 2 as libc::c_int {
1055        printf(
1056            b"Successfully truncated AOF %s\n\0" as *const u8 as *const libc::c_char,
1057            filepath,
1058        );
1059    }
1060}
1061#[no_mangle]
1062pub unsafe extern "C" fn redis_check_aof_main(
1063    mut argc: libc::c_int,
1064    mut argv: *mut *mut libc::c_char,
1065) -> libc::c_int {
1066    let mut type_0: input_file_type = AOF_RESP;
1067    let mut current_block: u64;
1068    let mut filepath: *mut libc::c_char = 0 as *mut libc::c_char;
1069    let mut temp_filepath: [libc::c_char; 4097] = [0; 4097];
1070    let mut dirpath: *mut libc::c_char = 0 as *mut libc::c_char;
1071    let mut fix: libc::c_int = 0 as libc::c_int;
1072    if !(argc < 2 as libc::c_int) {
1073        if argc == 2 as libc::c_int {
1074            filepath = *argv.offset(1 as libc::c_int as isize);
1075            current_block = 13797916685926291137;
1076        } else if argc == 3 as libc::c_int {
1077            if strcmp(
1078                *argv.offset(1 as libc::c_int as isize),
1079                b"--fix\0" as *const u8 as *const libc::c_char,
1080            ) == 0
1081            {
1082                filepath = *argv.offset(2 as libc::c_int as isize);
1083                fix = 1 as libc::c_int;
1084                current_block = 13797916685926291137;
1085            } else {
1086                current_block = 12445938659794055887;
1087            }
1088        } else if argc == 4 as libc::c_int {
1089            if strcmp(
1090                *argv.offset(1 as libc::c_int as isize),
1091                b"--truncate-to-timestamp\0" as *const u8 as *const libc::c_char,
1092            ) == 0
1093            {
1094                let mut endptr: *mut libc::c_char = 0 as *mut libc::c_char;
1095                *__errno_location() = 0 as libc::c_int;
1096                to_timestamp = strtol(
1097                    *argv.offset(2 as libc::c_int as isize),
1098                    &mut endptr,
1099                    10 as libc::c_int,
1100                );
1101                if *__errno_location() != 0 as libc::c_int
1102                    || *endptr as libc::c_int != '\0' as i32
1103                {
1104                    printf(
1105                        b"Invalid timestamp, aborting...\n\0" as *const u8
1106                            as *const libc::c_char,
1107                    );
1108                    exit(1 as libc::c_int);
1109                }
1110                filepath = *argv.offset(3 as libc::c_int as isize);
1111                current_block = 13797916685926291137;
1112            } else {
1113                current_block = 12445938659794055887;
1114            }
1115        } else {
1116            current_block = 12445938659794055887;
1117        }
1118        match current_block {
1119            12445938659794055887 => {}
1120            _ => {
1121                memcpy(
1122                    temp_filepath.as_mut_ptr() as *mut libc::c_void,
1123                    filepath as *const libc::c_void,
1124                    (strlen(filepath)).wrapping_add(1 as libc::c_int as libc::c_ulong),
1125                );
1126                dirpath = dirname(temp_filepath.as_mut_ptr());
1127                type_0 = getInputFileType(filepath);
1128                match type_0 as libc::c_uint {
1129                    2 => {
1130                        checkMultiPartAof(dirpath, filepath, fix);
1131                    }
1132                    0 => {
1133                        checkOldStyleAof(filepath, fix, 0 as libc::c_int);
1134                    }
1135                    1 => {
1136                        checkOldStyleAof(filepath, fix, 1 as libc::c_int);
1137                    }
1138                    _ => {}
1139                }
1140                exit(0 as libc::c_int);
1141            }
1142        }
1143    }
1144    printf(
1145        b"Usage: %s [--fix|--truncate-to-timestamp $timestamp] <file.manifest|file.aof>\n\0"
1146            as *const u8 as *const libc::c_char,
1147        *argv.offset(0 as libc::c_int as isize),
1148    );
1149    exit(1 as libc::c_int);
1150}