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
|
#define _GNU_SOURCE /* for tdestroy */
#include "statduplcheck.h"
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <search.h>
struct stat_info {
dev_t st_dev;
ino_t st_ino;
};
static void * info_root = NULL;
/* compare function passed to tsearch */
static int stat_info_compare(const void *si1, const void * si2)
{
int res;
res = ((struct stat_info*)si1)->st_dev - ((struct stat_info*)si2)->st_dev;
if (!res)
res = ((struct stat_info*)si1)->st_ino - ((struct stat_info*)si2)->st_ino;
return res;
}
int is_statduplicate(const struct stat *st) {
static struct stat_info * stinfo = NULL;
struct stat_info ** res;
if (!stinfo) {
stinfo = (struct stat_info*) malloc (sizeof(*stinfo));
if (!stinfo) {
fprintf(stderr, "cannot allocate memory\n");
exit(1);
}
}
stinfo->st_dev = st->st_dev;
stinfo->st_ino = st->st_ino;
if (!(res = tsearch(stinfo, &info_root, stat_info_compare))) {
fprintf(stderr, "cannot allocate memory\n");
exit(1);
}
if (*res == stinfo) {
// new record
stinfo = NULL;
return 0;
}
return 1;
}
int is_fileduplicate(const char *dir, const char *name) {
static struct stat stbuf;
static char fullpath[255];
if (strlen(dir) + strlen(name) + 2 > sizeof(fullpath)) return (-1);
strcpy(fullpath, dir);
strcat(fullpath, "/");
strcat(fullpath, name);
if (stat(fullpath,&stbuf)!=0) return(-1); /* file does not exists */
return is_statduplicate(&stbuf);
}
void free_statduplicates(void) {
if (!info_root) return;
tdestroy(info_root, free);
info_root = NULL;
}
|