2009-04-10 08:16:33 -08:00
|
|
|
/* ncdu - NCurses Disk Usage
|
|
|
|
|
|
2009-01-11 00:34:19 -09:00
|
|
|
Copyright (c) 2007-2009 Yoran Heling
|
2007-07-20 03:15:46 -08:00
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
|
|
|
a copy of this software and associated documentation files (the
|
|
|
|
|
"Software"), to deal in the Software without restriction, including
|
|
|
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
|
|
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
|
|
|
|
permit persons to whom the Software is furnished to do so, subject to
|
|
|
|
|
the following conditions:
|
2009-04-10 08:16:33 -08:00
|
|
|
|
2007-07-20 03:15:46 -08:00
|
|
|
The above copyright notice and this permission notice shall be included
|
|
|
|
|
in all copies or substantial portions of the Software.
|
2009-04-10 08:16:33 -08:00
|
|
|
|
2007-07-20 03:15:46 -08:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
|
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
|
|
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
|
|
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
|
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
|
|
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "ncdu.h"
|
2009-04-11 00:03:24 -08:00
|
|
|
#include "calc.h"
|
2009-04-11 00:48:24 -08:00
|
|
|
#include "exclude.h"
|
2009-04-11 01:37:45 -08:00
|
|
|
#include "util.h"
|
2009-04-13 07:25:46 -08:00
|
|
|
#include "browser.h"
|
2009-04-11 00:03:24 -08:00
|
|
|
|
2009-04-11 03:47:55 -08:00
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <dirent.h>
|
|
|
|
|
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2009-04-18 03:45:32 -08:00
|
|
|
/* set S_BLKSIZE if not defined already in sys/stat.h */
|
|
|
|
|
#ifndef S_BLKSIZE
|
|
|
|
|
# define S_BLKSIZE 512
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef LINK_MAX
|
|
|
|
|
# ifdef _POSIX_LINK_MAX
|
|
|
|
|
# define LINK_MAX _POSIX_LINK_MAX
|
|
|
|
|
# else
|
|
|
|
|
# define LINK_MAX 32
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef S_ISLNK
|
|
|
|
|
# ifndef S_IFLNK
|
|
|
|
|
# define S_IFLNK 0120000
|
|
|
|
|
# endif
|
|
|
|
|
# define S_ISLNK(x) (x & S_IFLNK)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
2009-04-18 03:51:45 -08:00
|
|
|
int calc_delay;
|
|
|
|
|
|
2009-04-16 08:26:39 -08:00
|
|
|
struct {
|
|
|
|
|
char err; /* 1/0, error or not */
|
|
|
|
|
char cur[PATH_MAX]; /* current dir/item */
|
|
|
|
|
char lasterr[PATH_MAX]; /* last unreadable dir/item */
|
|
|
|
|
char errmsg[128]; /* error message, when err=1 */
|
|
|
|
|
struct dir *parent; /* parent directory for the calculation */
|
|
|
|
|
struct dir *orig; /* original directory, when recalculating */
|
|
|
|
|
dev_t curdev; /* current device we're calculating on */
|
|
|
|
|
suseconds_t lastupdate; /* time of the last screen update */
|
|
|
|
|
int anpos; /* position of the animation string */
|
|
|
|
|
} stcalc;
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2007-07-20 03:15:46 -08:00
|
|
|
/* My own implementation of realpath()
|
|
|
|
|
- assumes that *every* possible path fits in PATH_MAX bytes
|
|
|
|
|
- does not set errno on error
|
|
|
|
|
- has not yet been fully tested
|
|
|
|
|
*/
|
|
|
|
|
char *rpath(const char *from, char *to) {
|
|
|
|
|
char tmp[PATH_MAX], cwd[PATH_MAX], cur[PATH_MAX], app[PATH_MAX];
|
|
|
|
|
int i, j, l, k, last, ll = 0;
|
|
|
|
|
struct stat st;
|
|
|
|
|
|
|
|
|
|
getcwd(cwd, PATH_MAX);
|
|
|
|
|
strcpy(cur, from);
|
|
|
|
|
app[0] = 0;
|
|
|
|
|
|
|
|
|
|
loop:
|
2009-04-10 08:16:33 -08:00
|
|
|
/* not an absolute path, add current directory */
|
2007-07-20 03:15:46 -08:00
|
|
|
if(cur[0] != '/') {
|
|
|
|
|
if(!(cwd[0] == '/' && cwd[1] == 0))
|
|
|
|
|
strcpy(tmp, cwd);
|
|
|
|
|
else
|
|
|
|
|
tmp[0] = 0;
|
2007-11-01 11:40:30 -08:00
|
|
|
if(strlen(cur) + 2 > PATH_MAX - strlen(tmp))
|
|
|
|
|
return(NULL);
|
2007-07-20 03:15:46 -08:00
|
|
|
strcat(tmp, "/");
|
|
|
|
|
strcat(tmp, cur);
|
|
|
|
|
} else
|
|
|
|
|
strcpy(tmp, cur);
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* now fix things like '.' and '..' */
|
2007-07-20 03:15:46 -08:00
|
|
|
i = j = last = 0;
|
|
|
|
|
l = strlen(tmp);
|
|
|
|
|
while(1) {
|
|
|
|
|
if(tmp[i] == 0)
|
|
|
|
|
break;
|
|
|
|
|
/* . */
|
|
|
|
|
if(l >= i+2 && tmp[i] == '/' && tmp[i+1] == '.' && (tmp[i+2] == 0 || tmp[i+2] == '/')) {
|
|
|
|
|
i+= 2;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* .. */
|
|
|
|
|
if(l >= i+3 && tmp[i] == '/' && tmp[i+1] == '.' && tmp[i+2] == '.' && (tmp[i+3] == 0 || tmp[i+3] == '/')) {
|
|
|
|
|
for(k=j; --k>0;)
|
|
|
|
|
if(to[k] == '/' && k != j-1)
|
|
|
|
|
break;
|
|
|
|
|
j -= j-k;
|
|
|
|
|
if(j < 1) j = 1;
|
|
|
|
|
i += 3;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
/* remove double slashes */
|
|
|
|
|
if(tmp[i] == '/' && i>0 && tmp[i-1] == '/') {
|
|
|
|
|
i++;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
to[j++] = tmp[i++];
|
|
|
|
|
}
|
2009-04-10 08:16:33 -08:00
|
|
|
/* remove leading slashes */
|
2007-07-20 03:15:46 -08:00
|
|
|
while(--j > 0) {
|
|
|
|
|
if(to[j] != '/')
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
to[j+1] = 0;
|
2009-04-10 08:16:33 -08:00
|
|
|
/* make sure we do have something left in case our path is / */
|
2009-01-11 00:30:53 -09:00
|
|
|
if(to[0] == 0) {
|
|
|
|
|
to[0] = '/';
|
|
|
|
|
to[1] = 0;
|
|
|
|
|
}
|
2009-04-10 08:16:33 -08:00
|
|
|
/* append 'app' */
|
2007-07-20 03:15:46 -08:00
|
|
|
if(app[0] != 0)
|
|
|
|
|
strcat(to, app);
|
2009-04-10 08:16:33 -08:00
|
|
|
|
2007-07-20 03:15:46 -08:00
|
|
|
j = strlen(to);
|
2009-04-10 08:16:33 -08:00
|
|
|
/* check for symlinks */
|
2007-07-20 03:15:46 -08:00
|
|
|
for(i=1; i<=j; i++) {
|
|
|
|
|
if(to[i] == '/' || to[i] == 0) {
|
|
|
|
|
strncpy(tmp, to, i);
|
|
|
|
|
tmp[i] = 0;
|
|
|
|
|
if(lstat(tmp, &st) < 0)
|
|
|
|
|
return(NULL);
|
|
|
|
|
if(S_ISLNK(st.st_mode)) {
|
|
|
|
|
if(++ll > LINK_MAX || (k = readlink(tmp, cur, PATH_MAX)) < 0)
|
|
|
|
|
return(NULL);
|
|
|
|
|
cur[k] = 0;
|
|
|
|
|
if(to[i] != 0)
|
|
|
|
|
strcpy(app, &to[i]);
|
|
|
|
|
strcpy(cwd, tmp);
|
|
|
|
|
for(k=strlen(cwd); --k>0;)
|
|
|
|
|
if(cwd[k] == '/')
|
|
|
|
|
break;
|
|
|
|
|
cwd[k] = 0;
|
|
|
|
|
goto loop;
|
|
|
|
|
}
|
|
|
|
|
if(!S_ISDIR(st.st_mode))
|
|
|
|
|
return(NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return(to);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
int calc_item(struct dir *par, char *path, char *name) {
|
|
|
|
|
char tmp[PATH_MAX];
|
|
|
|
|
struct dir *t, *d;
|
|
|
|
|
struct stat fs;
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
if(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
/* path too long - ignore file */
|
|
|
|
|
if(strlen(path)+strlen(name)+1 > PATH_MAX)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
/* allocate dir and fix references */
|
|
|
|
|
d = calloc(sizeof(struct dir), 1);
|
|
|
|
|
d->parent = par;
|
|
|
|
|
if(par->sub == NULL)
|
|
|
|
|
par->sub = d;
|
|
|
|
|
else {
|
|
|
|
|
for(t=par->sub; t->next!=NULL; t=t->next)
|
|
|
|
|
;
|
|
|
|
|
t->next = d;
|
2007-07-25 10:38:49 -08:00
|
|
|
}
|
2009-04-10 08:16:33 -08:00
|
|
|
d->name = malloc(strlen(name)+1);
|
|
|
|
|
strcpy(d->name, name);
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
#ifdef __CYGWIN__
|
|
|
|
|
/* /proc/registry names may contain slashes */
|
|
|
|
|
if(strchr(d->name, '/') || strchr(d->name, '\\')) {
|
|
|
|
|
d->flags |= FF_ERR;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* lstat */
|
|
|
|
|
strcpy(tmp, path);
|
|
|
|
|
strcat(tmp, name);
|
2009-04-13 08:38:07 -08:00
|
|
|
strcpy(stcalc.cur, tmp);
|
2009-04-10 08:16:33 -08:00
|
|
|
if(lstat(tmp, &fs)) {
|
|
|
|
|
d->flags |= FF_ERR;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* check for excludes and same filesystem */
|
2009-04-11 00:48:24 -08:00
|
|
|
if(exclude_match(tmp))
|
2009-04-10 08:16:33 -08:00
|
|
|
d->flags |= FF_EXL;
|
|
|
|
|
|
2009-04-10 23:58:33 -08:00
|
|
|
if(sflags & SF_SMFS && stcalc.curdev != fs.st_dev)
|
2009-04-10 08:16:33 -08:00
|
|
|
d->flags |= FF_OTHFS;
|
|
|
|
|
|
|
|
|
|
/* determine type of this item */
|
|
|
|
|
if(S_ISREG(fs.st_mode))
|
|
|
|
|
d->flags |= FF_FILE;
|
|
|
|
|
else if(S_ISDIR(fs.st_mode))
|
|
|
|
|
d->flags |= FF_DIR;
|
|
|
|
|
|
|
|
|
|
/* update parent dirs */
|
|
|
|
|
if(!(d->flags & FF_EXL))
|
2009-04-16 09:00:13 -08:00
|
|
|
for(t=d->parent; t!=NULL; t=t->parent)
|
2009-04-10 08:16:33 -08:00
|
|
|
t->items++;
|
|
|
|
|
|
|
|
|
|
/* count the size */
|
|
|
|
|
if(!(d->flags & FF_EXL || d->flags & FF_OTHFS)) {
|
|
|
|
|
d->size = fs.st_blocks * S_BLKSIZE;
|
|
|
|
|
d->asize = fs.st_size;
|
2009-04-16 09:00:13 -08:00
|
|
|
for(t=d->parent; t!=NULL; t=t->parent) {
|
2009-04-10 08:16:33 -08:00
|
|
|
t->size += d->size;
|
|
|
|
|
t->asize += d->asize;
|
2007-07-25 10:38:49 -08:00
|
|
|
}
|
|
|
|
|
}
|
2009-04-10 08:16:33 -08:00
|
|
|
return 0;
|
2007-07-25 10:38:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* recursively walk through the directory tree */
|
|
|
|
|
int calc_dir(struct dir *dest, char *path) {
|
|
|
|
|
struct dir *t;
|
2007-07-20 03:15:46 -08:00
|
|
|
DIR *dir;
|
|
|
|
|
struct dirent *dr;
|
2009-04-10 08:16:33 -08:00
|
|
|
char tmp[PATH_MAX];
|
|
|
|
|
int len;
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
if(input_handle(1))
|
|
|
|
|
return 1;
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* open directory */
|
2007-07-25 10:38:49 -08:00
|
|
|
if((dir = opendir(path)) == NULL) {
|
2009-04-10 23:58:33 -08:00
|
|
|
strcpy(stcalc.lasterr, path);
|
2007-07-25 10:38:49 -08:00
|
|
|
dest->flags |= FF_ERR;
|
|
|
|
|
t = dest;
|
|
|
|
|
while((t = t->parent) != NULL)
|
|
|
|
|
t->flags |= FF_SERR;
|
2009-04-10 08:16:33 -08:00
|
|
|
return 0;
|
2007-07-20 03:15:46 -08:00
|
|
|
}
|
2007-07-20 03:29:50 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* add leading slash */
|
|
|
|
|
len = strlen(path);
|
2007-07-25 10:38:49 -08:00
|
|
|
if(path[len-1] != '/') {
|
|
|
|
|
path[len] = '/';
|
|
|
|
|
path[++len] = '\0';
|
|
|
|
|
}
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* read directory */
|
|
|
|
|
while((dr = readdir(dir)) != NULL) {
|
|
|
|
|
if(calc_item(dest, path, dr->d_name))
|
|
|
|
|
dest->flags |= FF_ERR;
|
|
|
|
|
if(input_handle(1))
|
|
|
|
|
return 1;
|
|
|
|
|
errno = 0;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
if(errno) {
|
|
|
|
|
if(dest->flags & FF_SERR)
|
|
|
|
|
dest->flags -= FF_SERR;
|
|
|
|
|
dest->flags |= FF_ERR;
|
|
|
|
|
}
|
|
|
|
|
closedir(dir);
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* error occured while reading this dir, update parent dirs */
|
|
|
|
|
for(t=dest->sub; t!=NULL; t=t->next)
|
|
|
|
|
if(t->flags & FF_ERR || t->flags & FF_SERR)
|
|
|
|
|
dest->flags |= FF_SERR;
|
|
|
|
|
if(dest->flags & FF_ERR || dest->flags & FF_SERR) {
|
|
|
|
|
for(t = dest; (t = t->parent) != NULL; )
|
|
|
|
|
t->flags |= FF_SERR;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* calculate subdirectories */
|
|
|
|
|
for(t=dest->sub; t!=NULL; t=t->next)
|
|
|
|
|
if(t->flags & FF_DIR && !(t->flags & FF_EXL || t->flags & FF_OTHFS)) {
|
|
|
|
|
strcpy(tmp, path);
|
|
|
|
|
strcat(tmp, t->name);
|
|
|
|
|
if(calc_dir(t, tmp))
|
|
|
|
|
return 1;
|
2008-08-02 03:14:48 -08:00
|
|
|
}
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
return 0;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
void calc_draw_progress() {
|
|
|
|
|
static char antext[15] = "Calculating...";
|
|
|
|
|
char ani[15];
|
|
|
|
|
int i;
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-16 08:26:39 -08:00
|
|
|
nccreate(10, 60, stcalc.orig ? "Calculating..." : "Recalculating...");
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
ncprint(2, 2, "Total items: %-8d size: %s",
|
2009-04-11 01:37:45 -08:00
|
|
|
stcalc.parent->items, formatsize(stcalc.parent->size, sflags & SF_SI));
|
|
|
|
|
ncprint(3, 2, "Current dir: %s", cropstr(stcalc.cur, 43));
|
2009-04-10 08:16:33 -08:00
|
|
|
ncaddstr(8, 43, "Press q to quit");
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* show warning if we couldn't open a dir */
|
2009-04-10 23:58:33 -08:00
|
|
|
if(stcalc.lasterr[0] != '\0') {
|
2009-04-10 08:16:33 -08:00
|
|
|
attron(A_BOLD);
|
|
|
|
|
ncaddstr(5, 2, "Warning:");
|
|
|
|
|
attroff(A_BOLD);
|
2009-04-11 01:37:45 -08:00
|
|
|
ncprint(5, 11, "could not open %-32s", cropstr(stcalc.lasterr, 32));
|
2009-04-10 08:16:33 -08:00
|
|
|
ncaddstr(6, 3, "some directory sizes may not be correct");
|
2007-07-20 03:15:46 -08:00
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* animation - but only if the screen refreshes more than or once every second */
|
2009-04-18 03:51:45 -08:00
|
|
|
if(calc_delay <= 1000) {
|
2009-04-10 23:58:33 -08:00
|
|
|
if(++stcalc.anpos == 28)
|
|
|
|
|
stcalc.anpos = 0;
|
2009-04-10 08:16:33 -08:00
|
|
|
strcpy(ani, " ");
|
2009-04-10 23:58:33 -08:00
|
|
|
if(stcalc.anpos < 14)
|
|
|
|
|
for(i=0; i<=stcalc.anpos; i++)
|
2009-04-10 08:16:33 -08:00
|
|
|
ani[i] = antext[i];
|
|
|
|
|
else
|
2009-04-10 23:58:33 -08:00
|
|
|
for(i=13; i>stcalc.anpos-14; i--)
|
2009-04-10 08:16:33 -08:00
|
|
|
ani[i] = antext[i];
|
|
|
|
|
} else
|
|
|
|
|
strcpy(ani, antext);
|
|
|
|
|
ncaddstr(8, 3, ani);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void calc_draw_error(char *cur, char *msg) {
|
|
|
|
|
nccreate(7, 60, "Error!");
|
|
|
|
|
|
|
|
|
|
attron(A_BOLD);
|
|
|
|
|
ncaddstr(2, 2, "Error:");
|
|
|
|
|
attroff(A_BOLD);
|
|
|
|
|
|
2009-04-11 01:37:45 -08:00
|
|
|
ncprint(2, 9, "could not open %s", cropstr(cur, 34));
|
|
|
|
|
ncprint(3, 4, "%s", cropstr(msg, 52));
|
2009-04-10 08:16:33 -08:00
|
|
|
ncaddstr(5, 30, "press any key to continue...");
|
2007-07-20 03:15:46 -08:00
|
|
|
}
|
|
|
|
|
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
int calc_draw() {
|
|
|
|
|
struct timeval tv;
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 23:58:33 -08:00
|
|
|
if(stcalc.err) {
|
|
|
|
|
calc_draw_error(stcalc.cur, stcalc.errmsg);
|
2009-04-10 08:16:33 -08:00
|
|
|
return 0;
|
2007-07-25 10:38:49 -08:00
|
|
|
}
|
2007-07-26 04:56:24 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* should we really draw the screen again? */
|
|
|
|
|
gettimeofday(&tv, (void *)NULL);
|
2009-04-18 03:51:45 -08:00
|
|
|
tv.tv_usec = (1000*(tv.tv_sec % 1000) + (tv.tv_usec / 1000)) / calc_delay;
|
2009-04-10 23:58:33 -08:00
|
|
|
if(stcalc.lastupdate != tv.tv_usec) {
|
2009-04-10 08:16:33 -08:00
|
|
|
calc_draw_progress();
|
2009-04-10 23:58:33 -08:00
|
|
|
stcalc.lastupdate = tv.tv_usec;
|
2009-04-10 08:16:33 -08:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
2007-07-25 10:38:49 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
int calc_key(int ch) {
|
2009-04-10 23:58:33 -08:00
|
|
|
if(stcalc.err)
|
2009-04-10 08:16:33 -08:00
|
|
|
return 1;
|
|
|
|
|
if(ch == 'q')
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
void calc_process() {
|
|
|
|
|
char tmp[PATH_MAX];
|
|
|
|
|
struct stat fs;
|
|
|
|
|
struct dir *t;
|
|
|
|
|
|
|
|
|
|
/* check root directory */
|
2009-04-10 23:58:33 -08:00
|
|
|
if(rpath(stcalc.cur, tmp) == NULL || lstat(tmp, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
|
|
|
|
stcalc.err = 1;
|
|
|
|
|
strcpy(stcalc.errmsg, "Directory not found");
|
2009-04-10 08:16:33 -08:00
|
|
|
goto fail;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* initialize parent dir */
|
|
|
|
|
t = (struct dir *) calloc(1, sizeof(struct dir));
|
|
|
|
|
t->size = fs.st_blocks * S_BLKSIZE;
|
|
|
|
|
t->asize = fs.st_size;
|
|
|
|
|
t->flags |= FF_DIR;
|
2009-04-13 09:32:40 -08:00
|
|
|
if(stcalc.orig) {
|
|
|
|
|
t->parent = stcalc.orig->parent;
|
|
|
|
|
t->next = stcalc.orig->next;
|
|
|
|
|
}
|
2009-04-10 08:16:33 -08:00
|
|
|
t->name = (char *) malloc(strlen(tmp)+1);
|
2009-04-13 09:32:40 -08:00
|
|
|
strcpy(t->name, stcalc.orig ? stcalc.orig->name : tmp);
|
2009-04-10 23:58:33 -08:00
|
|
|
stcalc.parent = t;
|
|
|
|
|
stcalc.curdev = fs.st_dev;
|
2009-04-10 08:16:33 -08:00
|
|
|
|
2009-04-16 09:05:11 -08:00
|
|
|
/* update parents, if any */
|
|
|
|
|
if(stcalc.orig) {
|
|
|
|
|
for(t=t->parent; t!=NULL; t=t->parent) {
|
|
|
|
|
t->size += stcalc.parent->size;
|
|
|
|
|
t->asize += stcalc.parent->asize;
|
|
|
|
|
t->items++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* start calculating */
|
2009-04-10 23:58:33 -08:00
|
|
|
if(!calc_dir(stcalc.parent, tmp) && !stcalc.err) {
|
|
|
|
|
pstate = ST_BROWSE;
|
2009-04-13 09:32:40 -08:00
|
|
|
stbrowse.cur = stcalc.parent->sub;
|
|
|
|
|
|
|
|
|
|
/* update references and free original item */
|
|
|
|
|
if(stcalc.orig) {
|
|
|
|
|
if(stcalc.orig->parent) {
|
|
|
|
|
t = stcalc.orig->parent->sub;
|
|
|
|
|
if(t == stcalc.orig)
|
|
|
|
|
stcalc.orig->parent->sub = stcalc.parent;
|
|
|
|
|
else if(t != NULL)
|
|
|
|
|
for(; t->next!=NULL; t=t->next)
|
|
|
|
|
if(t->next == stcalc.orig)
|
|
|
|
|
t->next = stcalc.parent;
|
|
|
|
|
}
|
|
|
|
|
freedir(stcalc.orig);
|
|
|
|
|
}
|
2009-04-10 08:16:33 -08:00
|
|
|
return;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-10 08:16:33 -08:00
|
|
|
/* something went wrong... */
|
2009-04-10 23:58:33 -08:00
|
|
|
freedir(stcalc.parent);
|
2009-04-10 08:16:33 -08:00
|
|
|
fail:
|
2009-04-10 23:58:33 -08:00
|
|
|
while(stcalc.err && !input_handle(0))
|
2009-04-10 08:16:33 -08:00
|
|
|
;
|
2009-04-16 08:26:39 -08:00
|
|
|
pstate = stcalc.orig ? ST_BROWSE : ST_QUIT;
|
2009-04-10 08:16:33 -08:00
|
|
|
return;
|
|
|
|
|
}
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-16 08:26:39 -08:00
|
|
|
|
|
|
|
|
void calc_init(char *dir, struct dir *orig) {
|
|
|
|
|
stcalc.err = 0;
|
|
|
|
|
stcalc.lastupdate = 999;
|
|
|
|
|
stcalc.lasterr[0] = 0;
|
|
|
|
|
stcalc.anpos = 0;
|
|
|
|
|
stcalc.orig = orig;
|
|
|
|
|
strcpy(stcalc.cur, dir);
|
|
|
|
|
pstate = ST_CALC;
|
|
|
|
|
}
|
|
|
|
|
|