summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2021-10-25 10:41:37 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2021-10-25 10:41:37 +0900
commitff382fde104ffe6b03a4913cf48bfe8617276346 (patch)
tree52973fd57ff93b365b64a3422a4f04178cc97864
parentb84ead28bd5ff6581cda4511883c97301e541010 (diff)
downloadfdupes-ff382fde104ffe6b03a4913cf48bfe8617276346.tar.gz
fdupes-ff382fde104ffe6b03a4913cf48bfe8617276346.tar.bz2
fdupes-ff382fde104ffe6b03a4913cf48bfe8617276346.zip
Imported Upstream version 2.1.1upstream/2.1.1
-rw-r--r--CHANGES6
-rw-r--r--configure.ac2
-rw-r--r--fdupes.c118
-rw-r--r--fdupes.h3
-rw-r--r--ncurses-interface.c8
5 files changed, 58 insertions, 79 deletions
diff --git a/CHANGES b/CHANGES
index 13dc67d..1959c8e 100644
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,12 @@ who contributed the patch or idea appears first, followed by
those who've otherwise worked on that item. For a list of
contributors names and identifiers please see the CONTRIBUTORS file.
+Changes from 2.1.0 to 2.1.1:
+
+ - Break mtime ties using ctime when sorting by time.
+ - Reduce number of calls to stat(), for speed.
+ - Clear last command status when new command is entered.
+
Changes from 2.0.0 to 2.1.0:
- Rename cs command ("clear all selections") from cs to csel.
diff --git a/configure.ac b/configure.ac
index 1ee4308..22b4503 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([fdupes], [2.1.0])
+AC_INIT([fdupes], [2.1.1])
AM_INIT_AUTOMAKE([foreign subdir-objects])
diff --git a/fdupes.c b/fdupes.c
index 7bab2a8..61f31f7 100644
--- a/fdupes.c
+++ b/fdupes.c
@@ -126,14 +126,6 @@ void escapefilename(char *escape_list, char **filename_ptr)
}
}
-off_t filesize(char *filename) {
- struct stat s;
-
- if (stat(filename, &s) != 0) return -1;
-
- return s.st_size;
-}
-
dev_t getdevice(char *filename) {
struct stat s;
@@ -150,27 +142,11 @@ ino_t getinode(char *filename) {
return s.st_ino;
}
-time_t getmtime(char *filename) {
- struct stat s;
-
- if (stat(filename, &s) != 0) return 0;
-
- return s.st_mtime;
-}
-
-time_t getctime(char *filename) {
- struct stat s;
-
- if (stat(filename, &s) != 0) return 0;
-
- return s.st_ctime;
-}
-
-char *fmtmtime(char *filename) {
+char *fmttime(time_t t) {
static char buf[64];
- time_t t = getmtime(filename);
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", localtime(&t));
+
return buf;
}
@@ -230,22 +206,13 @@ int nonoptafter(char *option, int argc, char **oldargv,
return x;
}
-void getfilestats(file_t *file)
+void getfilestats(file_t *file, struct stat *info, struct stat *linfo)
{
- file->size = filesize(file->d_name);
- file->inode = getinode(file->d_name);
- file->device = getdevice(file->d_name);
-
- switch (ordertype)
- {
- case ORDER_CTIME:
- file->sorttime = getctime(file->d_name);
- break;
- case ORDER_MTIME:
- default:
- file->sorttime = getmtime(file->d_name);
- break;
- }
+ file->size = info->st_size;;
+ file->inode = info->st_ino;
+ file->device = info->st_dev;
+ file->ctime = info->st_ctime;
+ file->mtime = info->st_mtime;
}
int grokdir(char *dir, file_t **filelistp, struct stat *logfile_status)
@@ -260,7 +227,6 @@ int grokdir(char *dir, file_t **filelistp, struct stat *logfile_status)
static int progress = 0;
static char indicator[] = "-\\|/";
char *fullname, *name;
- off_t size;
cd = opendir(dir);
@@ -330,8 +296,7 @@ int grokdir(char *dir, file_t **filelistp, struct stat *logfile_status)
continue;
}
- size = filesize(newfile->d_name);
- if (!S_ISDIR(info.st_mode) && (((size == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) || size < minsize || (size > maxsize && maxsize != -1)))) {
+ if (!S_ISDIR(info.st_mode) && (((info.st_size == 0 && ISFLAG(flags, F_EXCLUDEEMPTY)) || info.st_size < minsize || (info.st_size > maxsize && maxsize != -1)))) {
free(newfile->d_name);
free(newfile);
continue;
@@ -357,7 +322,7 @@ int grokdir(char *dir, file_t **filelistp, struct stat *logfile_status)
free(newfile);
} else {
if (S_ISREG(linfo.st_mode) || (S_ISLNK(linfo.st_mode) && ISFLAG(flags, F_FOLLOWLINKS))) {
- getfilestats(newfile);
+ getfilestats(newfile, &info, &linfo);
*filelistp = newfile;
filecount++;
} else {
@@ -373,9 +338,8 @@ int grokdir(char *dir, file_t **filelistp, struct stat *logfile_status)
return filecount;
}
-md5_byte_t *getcrcsignatureuntil(char *filename, off_t max_read)
+md5_byte_t *getcrcsignatureuntil(char *filename, off_t fsize, off_t max_read)
{
- off_t fsize;
off_t toread;
md5_state_t state;
static md5_byte_t digest[MD5_DIGEST_LENGTH];
@@ -383,9 +347,6 @@ md5_byte_t *getcrcsignatureuntil(char *filename, off_t max_read)
FILE *file;
md5_init(&state);
-
-
- fsize = filesize(filename);
if (max_read != 0 && fsize > max_read)
fsize = max_read;
@@ -414,14 +375,14 @@ md5_byte_t *getcrcsignatureuntil(char *filename, off_t max_read)
return digest;
}
-md5_byte_t *getcrcsignature(char *filename)
+md5_byte_t *getcrcsignature(char *filename, off_t fsize)
{
- return getcrcsignatureuntil(filename, 0);
+ return getcrcsignatureuntil(filename, fsize, 0);
}
-md5_byte_t *getcrcpartialsignature(char *filename)
+md5_byte_t *getcrcpartialsignature(char *filename, off_t fsize)
{
- return getcrcsignatureuntil(filename, PARTIAL_MD5_SIZE);
+ return getcrcsignatureuntil(filename, fsize, PARTIAL_MD5_SIZE);
}
int md5cmp(const md5_byte_t *a, const md5_byte_t *b)
@@ -606,7 +567,6 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
{
int cmpresult;
md5_byte_t *crcsignature;
- off_t fsize;
if (ISFLAG(flags, F_CONSIDERHARDLINKS))
{
@@ -625,20 +585,18 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
if (is_hardlink(checktree, file))
return NULL;
}
-
- fsize = filesize(file->d_name);
- if (fsize < checktree->file->size)
+ if (file->size < checktree->file->size)
cmpresult = -1;
else
- if (fsize > checktree->file->size) cmpresult = 1;
+ if (file->size > checktree->file->size) cmpresult = 1;
else
if (ISFLAG(flags, F_PERMISSIONS) &&
!same_permissions(file->d_name, checktree->file->d_name))
cmpresult = -1;
else {
if (checktree->file->crcpartial == NULL) {
- crcsignature = getcrcpartialsignature(checktree->file->d_name);
+ crcsignature = getcrcpartialsignature(checktree->file->d_name, checktree->file->size);
if (crcsignature == NULL) {
errormsg ("cannot read file %s\n", checktree->file->d_name);
return NULL;
@@ -653,7 +611,7 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
}
if (file->crcpartial == NULL) {
- crcsignature = getcrcpartialsignature(file->d_name);
+ crcsignature = getcrcpartialsignature(file->d_name, file->size);
if (crcsignature == NULL) {
errormsg ("cannot read file %s\n", file->d_name);
return NULL;
@@ -672,7 +630,7 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
if (cmpresult == 0) {
if (checktree->file->crcsignature == NULL) {
- crcsignature = getcrcsignature(checktree->file->d_name);
+ crcsignature = getcrcsignature(checktree->file->d_name, checktree->file->size);
if (crcsignature == NULL) return NULL;
checktree->file->crcsignature = (md5_byte_t*) malloc(MD5_DIGEST_LENGTH * sizeof(md5_byte_t));
@@ -684,7 +642,7 @@ file_t **checkmatch(filetree_t **root, filetree_t *checktree, file_t *file)
}
if (file->crcsignature == NULL) {
- crcsignature = getcrcsignature(file->d_name);
+ crcsignature = getcrcsignature(file->d_name, file->size);
if (crcsignature == NULL) return NULL;
file->crcsignature = (md5_byte_t*) malloc(MD5_DIGEST_LENGTH * sizeof(md5_byte_t));
@@ -797,14 +755,14 @@ void printmatches(file_t *files)
if (ISFLAG(flags, F_SHOWSIZE)) printf("%lld byte%seach:\n", (long long int)files->size,
(files->size != 1) ? "s " : " ");
if (ISFLAG(flags, F_SHOWTIME))
- printf("%s ", fmtmtime(files->d_name));
+ printf("%s ", fmttime(files->mtime));
if (ISFLAG(flags, F_DSAMELINE)) escapefilename("\\ ", &files->d_name);
printf("%s%c", files->d_name, ISFLAG(flags, F_DSAMELINE)?' ':'\n');
}
tmpfile = files->duplicates;
while (tmpfile != NULL) {
if (ISFLAG(flags, F_SHOWTIME))
- printf("%s ", fmtmtime(tmpfile->d_name));
+ printf("%s ", fmttime(tmpfile->mtime));
if (ISFLAG(flags, F_DSAMELINE)) escapefilename("\\ ", &tmpfile->d_name);
printf("%s%c", tmpfile->d_name, ISFLAG(flags, F_DSAMELINE)?' ':'\n');
tmpfile = tmpfile->duplicates;
@@ -939,7 +897,7 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)
if (prompt)
{
if (ISFLAG(flags, F_SHOWTIME))
- printf("[%d] [%s] %s\n", counter, fmtmtime(files->d_name), files->d_name);
+ printf("[%d] [%s] %s\n", counter, fmttime(files->mtime), files->d_name);
else
printf("[%d] %s\n", counter, files->d_name);
}
@@ -951,7 +909,7 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)
if (prompt)
{
if (ISFLAG(flags, F_SHOWTIME))
- printf("[%d] [%s] %s\n", counter, fmtmtime(tmpfile->d_name), tmpfile->d_name);
+ printf("[%d] [%s] %s\n", counter, fmttime(tmpfile->mtime), tmpfile->d_name);
else
printf("[%d] %s\n", counter, tmpfile->d_name);
}
@@ -1101,16 +1059,26 @@ int sort_pairs_by_arrival(file_t *f1, file_t *f2)
return !ISFLAG(flags, F_REVERSE) ? -1 : 1;
}
-int sort_pairs_by_time(file_t *f1, file_t *f2)
+int sort_pairs_by_ctime(file_t *f1, file_t *f2)
{
- if (f1->sorttime < f2->sorttime)
+ if (f1->ctime < f2->ctime)
return !ISFLAG(flags, F_REVERSE) ? -1 : 1;
- else if (f1->sorttime > f2->sorttime)
+ else if (f1->ctime > f2->ctime)
return !ISFLAG(flags, F_REVERSE) ? 1 : -1;
return 0;
}
+int sort_pairs_by_mtime(file_t *f1, file_t *f2)
+{
+ if (f1->mtime < f2->mtime)
+ return !ISFLAG(flags, F_REVERSE) ? -1 : 1;
+ else if (f1->mtime > f2->mtime)
+ return !ISFLAG(flags, F_REVERSE) ? 1 : -1;
+ else
+ return sort_pairs_by_ctime(f1, f2);
+}
+
int sort_pairs_by_filename(file_t *f1, file_t *f2)
{
int strvalue = strcmp(f1->d_name, f2->d_name);
@@ -1507,12 +1475,14 @@ int main(int argc, char **argv) {
if (confirmmatch(file1, file2)) {
if (ISFLAG(flags, F_DELETEFILES) && ISFLAG(flags, F_IMMEDIATE))
deletesuccessor(match, curfile,
- (ordertype == ORDER_MTIME ||
- ordertype == ORDER_CTIME) ? sort_pairs_by_time : sort_pairs_by_filename, loginfo );
+ ordertype == ORDER_MTIME ? sort_pairs_by_mtime :
+ ordertype == ORDER_CTIME ? sort_pairs_by_ctime :
+ sort_pairs_by_filename, loginfo );
else
registerpair(match, curfile,
- (ordertype == ORDER_MTIME ||
- ordertype == ORDER_CTIME) ? sort_pairs_by_time : sort_pairs_by_filename );
+ ordertype == ORDER_MTIME ? sort_pairs_by_mtime :
+ ordertype == ORDER_CTIME ? sort_pairs_by_ctime :
+ sort_pairs_by_filename );
}
fclose(file1);
diff --git a/fdupes.h b/fdupes.h
index 4f58c12..1f5d0fd 100644
--- a/fdupes.h
+++ b/fdupes.h
@@ -32,7 +32,8 @@ typedef struct _file {
md5_byte_t *crcsignature;
dev_t device;
ino_t inode;
- time_t sorttime;
+ time_t mtime;
+ time_t ctime;
int hasdupes; /* true only if file is first on duplicate chain */
struct _file *duplicates;
struct _file *next;
diff --git a/ncurses-interface.c b/ncurses-interface.c
index 6c80f7f..6c9a0cc 100644
--- a/ncurses-interface.c
+++ b/ncurses-interface.c
@@ -43,7 +43,7 @@
#include "sigint.h"
#include "flags.h"
-char *fmtmtime(char *filename);
+char *fmttime(time_t t);
enum linestyle
{
@@ -650,7 +650,7 @@ void deletefiles_ncurses(file_t *files, char *logfile)
wprintw(filewin, " [%c] ", groups[groupindex].files[f].action > 0 ? '+' : groups[groupindex].files[f].action < 0 ? '-' : ' ');
if (ISFLAG(flags, F_SHOWTIME))
- wprintw(filewin, "[%s] ", fmtmtime(groups[groupindex].files[f].file->d_name));
+ wprintw(filewin, "[%s] ", fmttime(groups[groupindex].files[f].file->mtime));
}
cy = getcury(filewin);
@@ -679,7 +679,7 @@ void deletefiles_ncurses(file_t *files, char *logfile)
wprintw(filewin, " ");
if (ISFLAG(flags, F_SHOWTIME))
- wprintw(filewin, "[%s] ", fmtmtime(groups[groupindex].files[f].file->d_name));
+ wprintw(filewin, "[%s] ", fmttime(groups[groupindex].files[f].file->mtime));
}
cy = getcury(filewin);
@@ -761,6 +761,8 @@ void deletefiles_ncurses(file_t *files, char *logfile)
switch (get_command_text(&commandbuffer, &commandbuffersize, promptwin, prompt, 1, 1))
{
case GET_COMMAND_OK:
+ format_status_left(status, L"Ready");
+
get_command_arguments(&commandarguments, commandbuffer);
switch (identify_command(commandidentifier, commandbuffer, 0))