forked from simonsj/fdupes-jody
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjdupes.h
293 lines (255 loc) · 7.27 KB
/
jdupes.h
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/* jdupes main program header
* See jdupes.c for license information */
#ifndef JDUPES_H
#define JDUPES_H
#ifdef __cplusplus
extern "C" {
#endif
/* Detect Windows and modify as needed */
#if defined _WIN32 || defined __MINGW32__
#ifndef ON_WINDOWS
#define ON_WINDOWS 1
#endif
#define NO_SYMLINKS 1
#define NO_PERMS 1
#define NO_SIGACTION 1
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include <io.h>
#include "win_stat.h"
#endif /* Win32 */
#include <limits.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include "string_malloc.h"
#include "jody_sort.h"
#include "version.h"
#include "xxhash.h"
/* Set hash type (change this if swapping in a different hash function) */
typedef XXH64_hash_t jdupes_hash_t;
/* Some types are different on Windows */
#ifdef ON_WINDOWS
typedef uint64_t jdupes_ino_t;
typedef uint32_t jdupes_mode_t;
extern const char dir_sep;
#ifdef UNICODE
extern const wchar_t *FILE_MODE_RO;
#else
extern const char *FILE_MODE_RO;
#endif /* UNICODE */
#else /* Not Windows */
#include <sys/stat.h>
typedef ino_t jdupes_ino_t;
typedef mode_t jdupes_mode_t;
extern const char *FILE_MODE_RO;
extern const char dir_sep;
#ifdef UNICODE
#error Do not define UNICODE on non-Windows platforms.
#undef UNICODE
#endif
#endif /* _WIN32 || __MINGW32__ */
/* Windows + Unicode compilation */
#ifdef UNICODE
#define WPATH_MAX 8192
#define PATHBUF_SIZE WPATH_MAX
typedef wchar_t wpath_t[WPATH_MAX];
extern int out_mode;
extern int err_mode;
#define M2W(a,b) MultiByteToWideChar(CP_UTF8, 0, a, -1, (LPWSTR)b, WPATH_MAX)
#define W2M(a,b) WideCharToMultiByte(CP_UTF8, 0, a, -1, (LPSTR)b, WPATH_MAX, NULL, NULL)
#endif /* UNICODE */
#ifndef NO_SYMLINKS
#include "jody_paths.h"
#endif
#define ISFLAG(a,b) ((a & b) == b)
#define SETFLAG(a,b) (a |= b)
#define CLEARFLAG(a,b) (a &= (~b))
/* Low memory option overrides */
#ifdef LOW_MEMORY
#ifndef NO_PERMS
#define NO_PERMS 1
#endif
#endif
/* Aggressive verbosity for deep debugging */
#ifdef LOUD_DEBUG
#ifndef DEBUG
#define DEBUG
#endif
#define LOUD(...) if ISFLAG(flags, F_LOUD) __VA_ARGS__
#else
#define LOUD(a)
#endif
/* Compile out debugging stat counters unless requested */
#ifdef DEBUG
#define DBG(a) a
#ifndef TREE_DEPTH_STATS
#define TREE_DEPTH_STATS
#endif
#else
#define DBG(a)
#endif
/* Behavior modification flags */
extern uint_fast32_t flags, a_flags;
#define F_RECURSE (1U << 0)
#define F_HIDEPROGRESS (1U << 1)
#define F_SOFTABORT (1U << 2)
#define F_FOLLOWLINKS (1U << 3)
#define F_INCLUDEEMPTY (1U << 4)
#define F_CONSIDERHARDLINKS (1U << 5)
#define F_RECURSEAFTER (1U << 6)
#define F_NOPROMPT (1U << 7)
#define F_EXCLUDEHIDDEN (1U << 8)
#define F_PERMISSIONS (1U << 9)
#define F_EXCLUDESIZE (1U << 10)
#define F_QUICKCOMPARE (1U << 11)
#define F_USEPARAMORDER (1U << 12)
#define F_REVERSESORT (1U << 13)
/* #define F_ISOLATE (1U << 14) removed, may be re-added one day */
#define F_ONEFS (1U << 15)
#define F_PARTIALONLY (1U << 16)
#define F_NOCHANGECHECK (1U << 17)
#define F_NOTRAVCHECK (1U << 18)
#define F_SKIPHASH (1U << 19)
#define F_LOUD (1U << 30)
#define F_DEBUG (1U << 31)
/* Action-related flags */
#define FA_PRINTMATCHES (1U << 0)
#define FA_PRINTUNIQUE (1U << 1)
#define FA_OMITFIRST (1U << 2)
#define FA_SUMMARIZEMATCHES (1U << 3)
#define FA_DELETEFILES (1U << 4)
#define FA_SHOWSIZE (1U << 5)
#define FA_HARDLINKFILES (1U << 6)
#define FA_DEDUPEFILES (1U << 7)
#define FA_MAKESYMLINKS (1U << 8)
#define FA_PRINTNULL (1U << 9)
#define FA_PRINTJSON (1U << 10)
/* Per-file true/false flags */
#define FF_VALID_STAT (1U << 0)
#define FF_HASH_PARTIAL (1U << 1)
#define FF_HASH_FULL (1U << 2)
#define FF_HAS_DUPES (1U << 3)
#define FF_IS_SYMLINK (1U << 4)
#define FF_NOT_UNIQUE (1U << 5)
/* Extra print flags */
#define PF_PARTIAL (1U << 0)
#define PF_EARLYMATCH (1U << 1)
#define PF_FULLHASH (1U << 2)
typedef enum {
ORDER_NAME = 0,
ORDER_TIME
} ordertype_t;
#ifndef PARTIAL_HASH_SIZE
#define PARTIAL_HASH_SIZE 4096
#endif
/* Maximum path buffer size to use; must be large enough for a path plus
* any work that might be done to the array it's stored in. PATH_MAX is
* not always true. Read this article on the false promises of PATH_MAX:
* http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
* Windows + Unicode needs a lot more space than UTF-8 in Linux/Mac OS X
*/
#ifndef PATHBUF_SIZE
#define PATHBUF_SIZE 4096
#endif
/* Per-file information */
typedef struct _file {
struct _file *duplicates;
struct _file *next;
char *d_name;
uint32_t flags; /* Status flags */
jdupes_mode_t mode;
off_t size;
dev_t device;
jdupes_ino_t inode;
jdupes_hash_t filehash_partial;
jdupes_hash_t filehash;
#ifndef NO_MTIME
time_t mtime;
#endif
#ifndef NO_ATIME
time_t atime;
#endif
#ifndef NO_USER_ORDER
unsigned int user_order; /* Order of the originating command-line parameter */
#endif
#ifndef NO_HARDLINKS
#ifndef ON_WINDOWS
nlink_t nlink;
#else
uint32_t nlink; /* link count on Windows is always a DWORD */
#endif
#endif
#ifndef NO_PERMS
uid_t uid;
gid_t gid;
#endif
} file_t;
typedef struct _filetree {
file_t *file;
struct _filetree *left;
struct _filetree *right;
} filetree_t;
/* This gets used in many functions */
#ifdef ON_WINDOWS
extern struct winstat s;
#define STAT win_stat
#else
extern struct stat s;
#define STAT stat
#endif
/* -X extended filter parameter stack */
struct extfilter {
struct extfilter *next;
unsigned int flags;
int64_t size; /* also used for other large integers */
char param[];
};
/* Extended filter parameter flags */
#define XF_EXCL_EXT 0x00000001U
#define XF_SIZE_EQ 0x00000002U
#define XF_SIZE_GT 0x00000004U
#define XF_SIZE_LT 0x00000008U
#define XF_ONLY_EXT 0x00000010U
#define XF_EXCL_STR 0x00000020U
#define XF_ONLY_STR 0x00000040U
#define XF_DATE_NEWER 0x00000080U
#define XF_DATE_OLDER 0x00000100U
/* The X-than-or-equal are combination flags */
#define XF_SIZE_GTEQ 0x00000006U
#define XF_SIZE_LTEQ 0x0000000aU
/* Flags that use a numeric size with optional suffix */
#define XF_REQ_NUMBER 0x0000000eU
/* Flags that require a data parameter (after a colon) */
#define XF_REQ_VALUE 0x0000001fU
/* Flags that take a date that needs to be converted to time_t seconds */
#define XF_REQ_DATE 0x00000180U
/* Exclude definition array */
struct extfilter_tags {
const char * const tag;
const uint32_t flags;
};
extern const struct extfilter_tags extfilter_tags[];
extern struct extfilter *extfilter_head;
/* Suffix definitions (treat as case-insensitive) */
struct size_suffix {
const char * const suffix;
const int64_t multiplier;
};
extern const struct size_suffix size_suffix[];
extern char tempname[PATHBUF_SIZE * 2];
extern const char *extensions[];
extern void nullptr(const char * restrict func);
extern int file_has_changed(file_t * const restrict file);
extern int getdirstats(const char * const restrict name,
jdupes_ino_t * const restrict inode, dev_t * const restrict dev,
jdupes_mode_t * const restrict mode);
extern int check_conditions(const file_t * const restrict file1, const file_t * const restrict file2);
extern unsigned int get_max_dupes(const file_t *files, unsigned int * const restrict max,
unsigned int * const restrict n_files);
#ifdef __cplusplus
}
#endif
#endif /* JDUPES_H */