1
1

Implemented hardlink detection

Этот коммит содержится в:
Yorhel 2009-05-05 19:13:52 +02:00
родитель 188265c594
Коммит 757bdff7ed

Просмотреть файл

@ -53,7 +53,12 @@ struct dir *root; /* root directory struct we're calculating */
struct dir *orig; /* original directory, when recalculating */
dev_t curdev; /* current device we're calculating on */
int anpos; /* position of the animation string */
int curpathl = 0, lasterrl = 0;
struct link_inode { /* list of all non-dirs with nlink > 1 */
dev_t dev;
ino_t ino;
} *links = NULL;
int curpathl = 0, lasterrl = 0, linksl = 0, linkst = 0;
/* adds name to curpath */
@ -86,6 +91,7 @@ void calc_leavepath() {
int calc_item(struct dir *par, char *name) {
struct dir *t, *d;
struct stat fs;
int i;
if(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
return 0;
@ -130,6 +136,31 @@ int calc_item(struct dir *par, char *name) {
for(t=d->parent; t!=NULL; t=t->parent)
t->items++;
/* check for hard links.
An item is only considered a hard link if it's not a directory,
has st_nlink > 1, and is already present in the links array */
if(!S_ISDIR(fs.st_mode) && fs.st_nlink > 1) {
for(i=0; i<linkst; i++)
if(links[i].dev == fs.st_dev && links[i].ino == fs.st_ino)
break;
/* found in the list, set size = 0 */
if(i != linkst)
fs.st_blocks = fs.st_size = 0;
/* not found, add to the list */
else {
if(++linkst > linksl) {
linksl *= 2;
if(!linksl) {
linksl = 64;
links = malloc(linksl);
} else
links = realloc(links, linksl);
}
links[i].dev = fs.st_dev;
links[i].ino = fs.st_ino;
}
}
/* count the size */
if(!(d->flags & FF_EXL || d->flags & FF_OTHFS)) {
d->size = fs.st_blocks * S_BLKSIZE;
@ -297,6 +328,7 @@ void calc_process() {
char *path, *name;
struct stat fs;
struct dir *t;
int n;
/* check root directory */
if((path = path_real(curpath)) == NULL) {
@ -365,11 +397,20 @@ void calc_process() {
} else
curpath[0] = 0;
/* start calculating */
if(!calc_dir(root, name) && !failed) {
if(!path[1] && strcmp(name, "."))
free(name);
free(path);
/* calculate */
n = calc_dir(root, name);
/* free some resources */
if(!path[1] && strcmp(name, "."))
free(name);
free(path);
if(linksl) {
linksl = linkst = 0;
free(links);
}
/* success */
if(!n && !failed) {
if(root->sub == NULL) {
freedir(root);
failed = 1;
@ -403,9 +444,6 @@ void calc_process() {
}
/* something went wrong... */
if(!path[1] && strcmp(name, "."))
free(name);
free(path);
freedir(root);
calc_fail:
while(failed && !input_handle(0))