mirror of
https://code.blicky.net/yorhel/ncdu.git
synced 2026-01-15 02:08:40 -09:00
Rewrote calc.c in the new style & framework
ncdu is currently pretty much in a non-working state, but things will get fixed eventually after porting the other source files to the new framework.
This commit is contained in:
parent
02705d2c7f
commit
f392bf3ee1
4 changed files with 289 additions and 252 deletions
|
|
@ -428,12 +428,12 @@ void showBrowser(void) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* refresh */
|
/* refresh *
|
||||||
case 'r':
|
case 'r':
|
||||||
hideinfo;
|
hideinfo;
|
||||||
drawBrowser(0);
|
drawBrowser(0);
|
||||||
if((n = showCalc(getpath(bcur, tmp))) != NULL) {
|
if((n = showCalc(getpath(bcur, tmp))) != NULL) {
|
||||||
/* free current items */
|
* free current items *
|
||||||
d = bcur;
|
d = bcur;
|
||||||
bcur = bcur->parent;
|
bcur = bcur->parent;
|
||||||
while(d != NULL) {
|
while(d != NULL) {
|
||||||
|
|
@ -442,7 +442,7 @@ void showBrowser(void) {
|
||||||
freedir(t);
|
freedir(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update parent dir */
|
* update parent dir *
|
||||||
bcur->sub = n->sub;
|
bcur->sub = n->sub;
|
||||||
bcur->items = n->items;
|
bcur->items = n->items;
|
||||||
bcur->size = n->size;
|
bcur->size = n->size;
|
||||||
|
|
@ -450,7 +450,7 @@ void showBrowser(void) {
|
||||||
for(t = bcur->sub; t != NULL; t = t->next)
|
for(t = bcur->sub; t != NULL; t = t->next)
|
||||||
t->parent = bcur;
|
t->parent = bcur;
|
||||||
|
|
||||||
/* update sizes of parent dirs */
|
* update sizes of parent dirs *
|
||||||
for(t = bcur; (t = t->parent) != NULL; ) {
|
for(t = bcur; (t = t->parent) != NULL; ) {
|
||||||
t->size += bcur->size;
|
t->size += bcur->size;
|
||||||
t->asize += bcur->asize;
|
t->asize += bcur->asize;
|
||||||
|
|
@ -462,6 +462,7 @@ void showBrowser(void) {
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
*/
|
||||||
|
|
||||||
/* and other stuff */
|
/* and other stuff */
|
||||||
case KEY_RESIZE:
|
case KEY_RESIZE:
|
||||||
|
|
|
||||||
464
src/calc.c
464
src/calc.c
|
|
@ -1,5 +1,5 @@
|
||||||
/* ncdu - NCurses Disk Usage
|
/* ncdu - NCurses Disk Usage
|
||||||
|
|
||||||
Copyright (c) 2007-2009 Yoran Heling
|
Copyright (c) 2007-2009 Yoran Heling
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
|
@ -9,10 +9,10 @@
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
the following conditions:
|
the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
The above copyright notice and this permission notice shall be included
|
||||||
in all copies or substantial portions of the Software.
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
|
@ -26,18 +26,6 @@
|
||||||
#include "ncdu.h"
|
#include "ncdu.h"
|
||||||
|
|
||||||
|
|
||||||
/* parent dir we are calculating */
|
|
||||||
struct dir *parent;
|
|
||||||
/* current device we are on */
|
|
||||||
dev_t curdev;
|
|
||||||
/* path of the last dir we couldn't read */
|
|
||||||
char lasterr[PATH_MAX];
|
|
||||||
/* and for the animation... */
|
|
||||||
int anpos;
|
|
||||||
char antext[15] = "Calculating...";
|
|
||||||
suseconds_t lastupdate;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* My own implementation of realpath()
|
/* My own implementation of realpath()
|
||||||
- assumes that *every* possible path fits in PATH_MAX bytes
|
- assumes that *every* possible path fits in PATH_MAX bytes
|
||||||
|
|
@ -54,7 +42,7 @@ char *rpath(const char *from, char *to) {
|
||||||
app[0] = 0;
|
app[0] = 0;
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
/* not an absolute path, add current directory */
|
/* not an absolute path, add current directory */
|
||||||
if(cur[0] != '/') {
|
if(cur[0] != '/') {
|
||||||
if(!(cwd[0] == '/' && cwd[1] == 0))
|
if(!(cwd[0] == '/' && cwd[1] == 0))
|
||||||
strcpy(tmp, cwd);
|
strcpy(tmp, cwd);
|
||||||
|
|
@ -67,7 +55,7 @@ char *rpath(const char *from, char *to) {
|
||||||
} else
|
} else
|
||||||
strcpy(tmp, cur);
|
strcpy(tmp, cur);
|
||||||
|
|
||||||
/* now fix things like '.' and '..' */
|
/* now fix things like '.' and '..' */
|
||||||
i = j = last = 0;
|
i = j = last = 0;
|
||||||
l = strlen(tmp);
|
l = strlen(tmp);
|
||||||
while(1) {
|
while(1) {
|
||||||
|
|
@ -95,23 +83,23 @@ char *rpath(const char *from, char *to) {
|
||||||
}
|
}
|
||||||
to[j++] = tmp[i++];
|
to[j++] = tmp[i++];
|
||||||
}
|
}
|
||||||
/* remove leading slashes */
|
/* remove leading slashes */
|
||||||
while(--j > 0) {
|
while(--j > 0) {
|
||||||
if(to[j] != '/')
|
if(to[j] != '/')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
to[j+1] = 0;
|
to[j+1] = 0;
|
||||||
/* make sure we do have something left in case our path is / */
|
/* make sure we do have something left in case our path is / */
|
||||||
if(to[0] == 0) {
|
if(to[0] == 0) {
|
||||||
to[0] = '/';
|
to[0] = '/';
|
||||||
to[1] = 0;
|
to[1] = 0;
|
||||||
}
|
}
|
||||||
/* append 'app' */
|
/* append 'app' */
|
||||||
if(app[0] != 0)
|
if(app[0] != 0)
|
||||||
strcat(to, app);
|
strcat(to, app);
|
||||||
|
|
||||||
j = strlen(to);
|
j = strlen(to);
|
||||||
/* check for symlinks */
|
/* check for symlinks */
|
||||||
for(i=1; i<=j; i++) {
|
for(i=1; i<=j; i++) {
|
||||||
if(to[i] == '/' || to[i] == 0) {
|
if(to[i] == '/' || to[i] == 0) {
|
||||||
strncpy(tmp, to, i);
|
strncpy(tmp, to, i);
|
||||||
|
|
@ -140,268 +128,264 @@ char *rpath(const char *from, char *to) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* the progress window */
|
int calc_item(struct dir *par, char *path, char *name) {
|
||||||
static void drawProgress(char *cdir) {
|
char tmp[PATH_MAX];
|
||||||
|
struct dir *t, *d;
|
||||||
|
struct stat fs;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
d->name = malloc(strlen(name)+1);
|
||||||
|
strcpy(d->name, name);
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
/* /proc/registry names may contain slashes */
|
||||||
|
if(strchr(d->name, '/') || strchr(d->name, '\\')) {
|
||||||
|
d->flags |= FF_ERR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* lstat */
|
||||||
|
strcpy(tmp, path);
|
||||||
|
strcat(tmp, name);
|
||||||
|
if(lstat(tmp, &fs)) {
|
||||||
|
d->flags |= FF_ERR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check for excludes and same filesystem */
|
||||||
|
if(matchExclude(tmp))
|
||||||
|
d->flags |= FF_EXL;
|
||||||
|
|
||||||
|
if(sflags & SF_SMFS && pstate.calc.curdev != fs.st_dev)
|
||||||
|
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))
|
||||||
|
for(t=d; t!=NULL; t=t->parent)
|
||||||
|
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;
|
||||||
|
for(t=d; t!=NULL; t=t->parent) {
|
||||||
|
t->size += d->size;
|
||||||
|
t->asize += d->asize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* recursively walk through the directory tree */
|
||||||
|
int calc_dir(struct dir *dest, char *path) {
|
||||||
|
struct dir *t;
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *dr;
|
||||||
|
char tmp[PATH_MAX];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
if(input_handle(1))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* open directory */
|
||||||
|
if((dir = opendir(path)) == NULL) {
|
||||||
|
strcpy(pstate.calc.lasterr, path);
|
||||||
|
dest->flags |= FF_ERR;
|
||||||
|
t = dest;
|
||||||
|
while((t = t->parent) != NULL)
|
||||||
|
t->flags |= FF_SERR;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add leading slash */
|
||||||
|
len = strlen(path);
|
||||||
|
if(path[len-1] != '/') {
|
||||||
|
path[len] = '/';
|
||||||
|
path[++len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errno) {
|
||||||
|
if(dest->flags & FF_SERR)
|
||||||
|
dest->flags -= FF_SERR;
|
||||||
|
dest->flags |= FF_ERR;
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void calc_draw_progress() {
|
||||||
|
static char antext[15] = "Calculating...";
|
||||||
char ani[15];
|
char ani[15];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
nccreate(10, 60, dat == NULL ? "Calculating..." : "Recalculating...");
|
nccreate(10, 60, dat == NULL ? "Calculating..." : "Recalculating...");
|
||||||
|
|
||||||
ncprint(2, 2, "Total items: %-8d size: %s",
|
ncprint(2, 2, "Total items: %-8d size: %s",
|
||||||
parent->items, cropsize(parent->size));
|
pstate.calc.parent->items, cropsize(pstate.calc.parent->size));
|
||||||
ncprint(3, 2, "Current dir: %s", cropdir(cdir, 43));
|
ncprint(3, 2, "Current dir: %s", cropdir(pstate.calc.cur, 43));
|
||||||
ncaddstr(8, 43, "Press q to quit");
|
ncaddstr(8, 43, "Press q to quit");
|
||||||
|
|
||||||
/* show warning if we couldn't open a dir */
|
/* show warning if we couldn't open a dir */
|
||||||
if(lasterr[0] != '\0') {
|
if(pstate.calc.lasterr[0] != '\0') {
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
ncaddstr(5, 2, "Warning:");
|
ncaddstr(5, 2, "Warning:");
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
ncprint(5, 11, "could not open %-32s", cropdir(lasterr, 32));
|
ncprint(5, 11, "could not open %-32s", cropdir(pstate.calc.lasterr, 32));
|
||||||
ncaddstr(6, 3, "some directory sizes may not be correct");
|
ncaddstr(6, 3, "some directory sizes may not be correct");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* animation - but only if the screen refreshes more than or once every second */
|
/* animation - but only if the screen refreshes more than or once every second */
|
||||||
if(sdelay <= 1000) {
|
if(sdelay <= 1000) {
|
||||||
if(++anpos == 28) anpos = 0;
|
if(++pstate.calc.anpos == 28)
|
||||||
strcpy(ani, " ");
|
pstate.calc.anpos = 0;
|
||||||
if(anpos < 14)
|
strcpy(ani, " ");
|
||||||
for(i=0; i<=anpos; i++)
|
if(pstate.calc.anpos < 14)
|
||||||
ani[i] = antext[i];
|
for(i=0; i<=pstate.calc.anpos; i++)
|
||||||
else
|
ani[i] = antext[i];
|
||||||
for(i=13; i>anpos-14; i--)
|
else
|
||||||
ani[i] = antext[i];
|
for(i=13; i>pstate.calc.anpos-14; i--)
|
||||||
|
ani[i] = antext[i];
|
||||||
} else
|
} else
|
||||||
strcpy(ani, antext);
|
strcpy(ani, antext);
|
||||||
ncaddstr(8, 3, ani);
|
ncaddstr(8, 3, ani);
|
||||||
|
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* show error if can't open parent dir */
|
void calc_draw_error(char *cur, char *msg) {
|
||||||
static void drawError(char *dir) {
|
nccreate(7, 60, "Error!");
|
||||||
nccreate(10, 60, "Error!");
|
|
||||||
|
|
||||||
attron(A_BOLD);
|
attron(A_BOLD);
|
||||||
ncaddstr(5, 2, "Error:");
|
ncaddstr(2, 2, "Error:");
|
||||||
attroff(A_BOLD);
|
attroff(A_BOLD);
|
||||||
|
|
||||||
ncprint(5, 9, "could not open %s", cropdir(dir, 34));
|
ncprint(2, 9, "could not open %s", cropdir(cur, 34));
|
||||||
ncaddstr(6, 3, "press any key to continue...");
|
ncprint(3, 4, "%s", cropdir(msg, 52));
|
||||||
|
ncaddstr(5, 30, "press any key to continue...");
|
||||||
refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* checks for input and calls drawProgress */
|
int calc_draw() {
|
||||||
int updateProgress(char *path) {
|
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int ch;
|
|
||||||
|
|
||||||
/* check for input or screen resizes */
|
if(pstate.calc.err) {
|
||||||
nodelay(stdscr, 1);
|
calc_draw_error(pstate.calc.cur, pstate.calc.errmsg);
|
||||||
while((ch = getch()) != ERR) {
|
return 0;
|
||||||
if(ch == 'q')
|
|
||||||
return(0);
|
|
||||||
if(ch == KEY_RESIZE) {
|
|
||||||
ncresize();
|
|
||||||
if(dat != NULL)
|
|
||||||
drawBrowser(0);
|
|
||||||
drawProgress(path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nodelay(stdscr, 0);
|
|
||||||
|
/* should we really draw the screen again? */
|
||||||
/* don't update the screen with shorter intervals than sdelay */
|
|
||||||
gettimeofday(&tv, (void *)NULL);
|
gettimeofday(&tv, (void *)NULL);
|
||||||
tv.tv_usec = (1000*(tv.tv_sec % 1000) + (tv.tv_usec / 1000)) / sdelay;
|
tv.tv_usec = (1000*(tv.tv_sec % 1000) + (tv.tv_usec / 1000)) / sdelay;
|
||||||
if(lastupdate != tv.tv_usec) {
|
if(pstate.calc.lastupdate != tv.tv_usec) {
|
||||||
drawProgress(path);
|
calc_draw_progress();
|
||||||
lastupdate = tv.tv_usec;
|
pstate.calc.lastupdate = tv.tv_usec;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return(1);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* recursive */
|
int calc_key(int ch) {
|
||||||
int calcDir(struct dir *dest, char *path) {
|
if(pstate.calc.err)
|
||||||
struct dir *d, *t, *last;
|
return 1;
|
||||||
struct stat fs;
|
if(ch == 'q')
|
||||||
DIR *dir;
|
return 1;
|
||||||
struct dirent *dr;
|
return 0;
|
||||||
char *f, tmp[PATH_MAX];
|
|
||||||
int len, derr = 0, serr = 0;
|
|
||||||
|
|
||||||
if(!updateProgress(path))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* open directory */
|
|
||||||
if((dir = opendir(path)) == NULL) {
|
|
||||||
strcpy(lasterr, path);
|
|
||||||
dest->flags |= FF_ERR;
|
|
||||||
t = dest;
|
|
||||||
while((t = t->parent) != NULL)
|
|
||||||
t->flags |= FF_SERR;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
len = strlen(path);
|
|
||||||
|
|
||||||
/* add leading slash */
|
|
||||||
if(path[len-1] != '/') {
|
|
||||||
path[len] = '/';
|
|
||||||
path[++len] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read directory */
|
|
||||||
last = NULL;
|
|
||||||
while((dr = readdir(dir)) != NULL) {
|
|
||||||
f = dr->d_name;
|
|
||||||
if(f[0] == '.' && (f[1] == '\0' || (f[1] == '.' && f[2] == '\0')))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* path too long - ignore file */
|
|
||||||
if(len+strlen(f)+1 > PATH_MAX) {
|
|
||||||
derr = 1;
|
|
||||||
errno = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* allocate dir and fix references */
|
|
||||||
d = calloc(sizeof(struct dir), 1);
|
|
||||||
d->parent = dest;
|
|
||||||
if(dest->sub == NULL)
|
|
||||||
dest->sub = d;
|
|
||||||
if(last != NULL)
|
|
||||||
last->next = d;
|
|
||||||
last = d;
|
|
||||||
|
|
||||||
/* set d->name */
|
|
||||||
d->name = malloc(strlen(f)+1);
|
|
||||||
strcpy(d->name, f);
|
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
/* /proc/registry names may contain slashes */
|
|
||||||
if(strchr(d->name, '/') || strchr(d->name, '\\')) {
|
|
||||||
serr = 1;
|
|
||||||
errno = 0;
|
|
||||||
d->flags |= FF_ERR;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* get full path */
|
|
||||||
strcpy(tmp, path);
|
|
||||||
strcat(tmp, f);
|
|
||||||
|
|
||||||
/* lstat */
|
|
||||||
if(lstat(tmp, &fs)) {
|
|
||||||
serr = 1;
|
|
||||||
errno = 0;
|
|
||||||
d->flags |= FF_ERR;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for excludes and same filesystem */
|
|
||||||
if(matchExclude(tmp))
|
|
||||||
d->flags |= FF_EXL;
|
|
||||||
|
|
||||||
if(sflags & SF_SMFS && curdev != fs.st_dev)
|
|
||||||
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))
|
|
||||||
for(t = dest; t != NULL; t = t->parent)
|
|
||||||
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;
|
|
||||||
for(t = dest; t != NULL; t = t->parent) {
|
|
||||||
t->size += d->size;
|
|
||||||
t->asize += d->asize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* show status */
|
|
||||||
if(!updateProgress(tmp))
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
derr = derr || errno;
|
|
||||||
closedir(dir);
|
|
||||||
|
|
||||||
/* error occured while reading this dir, update parent dirs */
|
|
||||||
if(derr || serr) {
|
|
||||||
dest->flags |= derr ? FF_ERR : FF_SERR;
|
|
||||||
for(t = dest; (t = t->parent) != NULL; )
|
|
||||||
t->flags |= FF_SERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(dest->sub) {
|
|
||||||
/* calculate subdirectories */
|
|
||||||
for(d = dest->sub; d != NULL; d = d->next)
|
|
||||||
if(d->flags & FF_DIR && !(d->flags & FF_EXL || d->flags & FF_OTHFS)) {
|
|
||||||
strcpy(tmp, path);
|
|
||||||
strcat(tmp, d->name);
|
|
||||||
if(!calcDir(d, tmp))
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct dir *showCalc(char *path) {
|
void calc_process() {
|
||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
struct stat fs;
|
struct stat fs;
|
||||||
struct dir *t;
|
struct dir *t;
|
||||||
|
|
||||||
/* init/reset global vars */
|
/* init/reset global vars */
|
||||||
*lasterr = '\0';
|
pstate.calc.err = 0;
|
||||||
anpos = 0;
|
pstate.calc.lastupdate = 999;
|
||||||
lastupdate = 999;
|
pstate.calc.lasterr[0] = 0;
|
||||||
memset(tmp, 0, PATH_MAX);
|
pstate.calc.anpos = 0;
|
||||||
|
|
||||||
/* init parent dir */
|
/* check root directory */
|
||||||
if(rpath(path, tmp) == NULL || lstat(tmp, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
if(rpath(pstate.calc.cur, tmp) == NULL || lstat(tmp, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
||||||
do {
|
pstate.calc.err = 1;
|
||||||
ncresize();
|
strcpy(pstate.calc.errmsg, "Directory not found");
|
||||||
if(dat != NULL)
|
goto fail;
|
||||||
drawBrowser(0);
|
|
||||||
drawError(path);
|
|
||||||
} while (getch() == KEY_RESIZE);
|
|
||||||
return(NULL);
|
|
||||||
}
|
|
||||||
parent = calloc(sizeof(struct dir), 1);
|
|
||||||
parent->size = fs.st_blocks * S_BLKSIZE;
|
|
||||||
parent->asize = fs.st_size;
|
|
||||||
parent->flags |= FF_DIR;
|
|
||||||
curdev = fs.st_dev;
|
|
||||||
parent->name = malloc(strlen(tmp)+1);
|
|
||||||
strcpy(parent->name, tmp);
|
|
||||||
|
|
||||||
/* start calculating */
|
|
||||||
if(!calcDir(parent, tmp)) {
|
|
||||||
freedir(parent);
|
|
||||||
return(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return(parent);
|
/* 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;
|
||||||
|
t->name = (char *) malloc(strlen(tmp)+1);
|
||||||
|
strcpy(t->name, tmp);
|
||||||
|
pstate.calc.parent = t;
|
||||||
|
pstate.calc.curdev = fs.st_dev;
|
||||||
|
|
||||||
|
/* start calculating */
|
||||||
|
if(!calc_dir(pstate.calc.parent, tmp) && !pstate.calc.err) {
|
||||||
|
pstate.st = ST_BROWSE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* something went wrong... */
|
||||||
|
freedir(pstate.calc.parent);
|
||||||
|
fail:
|
||||||
|
while(pstate.calc.err && !input_handle(0))
|
||||||
|
;
|
||||||
|
pstate.st = dat != NULL ? ST_BROWSE : ST_QUIT;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
50
src/main.c
50
src/main.c
|
|
@ -28,14 +28,44 @@
|
||||||
/* check ncdu.h what these are for */
|
/* check ncdu.h what these are for */
|
||||||
struct dir *dat;
|
struct dir *dat;
|
||||||
int winrows, wincols;
|
int winrows, wincols;
|
||||||
|
char sdir[PATH_MAX];
|
||||||
int sflags, bflags, sdelay, bgraph;
|
int sflags, bflags, sdelay, bgraph;
|
||||||
int subwinc, subwinr;
|
int subwinc, subwinr;
|
||||||
struct state pstate;
|
struct state pstate;
|
||||||
|
|
||||||
|
|
||||||
|
void screen_draw() {
|
||||||
|
int n = 1;
|
||||||
|
switch(pstate.st) {
|
||||||
|
case ST_CALC: n = calc_draw();
|
||||||
|
}
|
||||||
|
if(!n)
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int input_handle(int wait) {
|
||||||
|
int ch;
|
||||||
|
|
||||||
|
nodelay(stdscr, wait);
|
||||||
|
screen_draw();
|
||||||
|
while((ch = getch()) != ERR) {
|
||||||
|
if(ch == KEY_RESIZE) {
|
||||||
|
ncresize();
|
||||||
|
screen_draw();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(pstate.st) {
|
||||||
|
case ST_CALC: return calc_key(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* parse command line */
|
/* parse command line */
|
||||||
void argv_parse(int argc, char **argv, char *dir) {
|
void argv_parse(int argc, char **argv, char *dir) {
|
||||||
int i, j;
|
int i, j, len;
|
||||||
|
|
||||||
/* load defaults */
|
/* load defaults */
|
||||||
memset(dir, 0, PATH_MAX);
|
memset(dir, 0, PATH_MAX);
|
||||||
|
|
@ -63,7 +93,8 @@ void argv_parse(int argc, char **argv, char *dir) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* small flags */
|
/* small flags */
|
||||||
for(j=1; j < strlen(argv[i]); j++)
|
len = strlen(argv[i]);
|
||||||
|
for(j=1; j<len; j++)
|
||||||
switch(argv[i][j]) {
|
switch(argv[i][j]) {
|
||||||
case 'x': sflags |= SF_SMFS; break;
|
case 'x': sflags |= SF_SMFS; break;
|
||||||
case 'q': sdelay = 2000; break;
|
case 'q': sdelay = 2000; break;
|
||||||
|
|
@ -85,12 +116,12 @@ void argv_parse(int argc, char **argv, char *dir) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dir[PATH_MAX - 1] = 0;
|
|
||||||
strncpy(dir, argv[i], PATH_MAX);
|
strncpy(dir, argv[i], PATH_MAX);
|
||||||
if(dir[PATH_MAX - 1] != 0) {
|
if(dir[PATH_MAX - 1] != 0) {
|
||||||
printf("Error: path length exceeds PATH_MAX\n");
|
printf("Error: path length exceeds PATH_MAX\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
dir[PATH_MAX - 1] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +131,8 @@ void argv_parse(int argc, char **argv, char *dir) {
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
dat = NULL;
|
dat = NULL;
|
||||||
|
|
||||||
argv_parse(argc, argv, pstate.calc.root);
|
memset((void *)&pstate, 0, sizeof(struct state));
|
||||||
|
argv_parse(argc, argv, pstate.calc.cur);
|
||||||
pstate.st = ST_CALC;
|
pstate.st = ST_CALC;
|
||||||
|
|
||||||
initscr();
|
initscr();
|
||||||
|
|
@ -110,8 +142,16 @@ int main(int argc, char **argv) {
|
||||||
keypad(stdscr, TRUE);
|
keypad(stdscr, TRUE);
|
||||||
ncresize();
|
ncresize();
|
||||||
|
|
||||||
|
while(pstate.st != ST_QUIT) {
|
||||||
|
if(pstate.st == ST_CALC)
|
||||||
|
calc_process();
|
||||||
|
/*else
|
||||||
|
wait_for_input() */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if((dat = showCalc(pstate.calc.root)) != NULL)
|
if((dat = showCalc(pstate.calc.root)) != NULL)
|
||||||
showBrowser();
|
showBrowser();*/
|
||||||
|
|
||||||
erase();
|
erase();
|
||||||
refresh();
|
refresh();
|
||||||
|
|
|
||||||
18
src/ncdu.h
18
src/ncdu.h
|
|
@ -121,6 +121,7 @@
|
||||||
#define ST_BROWSE 1
|
#define ST_BROWSE 1
|
||||||
#define ST_DEL 2
|
#define ST_DEL 2
|
||||||
#define ST_HELP 3
|
#define ST_HELP 3
|
||||||
|
#define ST_QUIT 4
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -129,7 +130,7 @@
|
||||||
*/
|
*/
|
||||||
struct dir {
|
struct dir {
|
||||||
struct dir *parent, *next, *sub;
|
struct dir *parent, *next, *sub;
|
||||||
unsigned char *name;
|
char *name;
|
||||||
off_t size, asize;
|
off_t size, asize;
|
||||||
unsigned long items;
|
unsigned long items;
|
||||||
unsigned char flags;
|
unsigned char flags;
|
||||||
|
|
@ -138,7 +139,14 @@ struct dir {
|
||||||
struct state {
|
struct state {
|
||||||
int st; /* SC_x */
|
int st; /* SC_x */
|
||||||
struct {
|
struct {
|
||||||
char root[PATH_MAX];
|
char err;
|
||||||
|
char cur[PATH_MAX];
|
||||||
|
char lasterr[PATH_MAX];
|
||||||
|
char errmsg[128];
|
||||||
|
struct dir *parent;
|
||||||
|
dev_t curdev;
|
||||||
|
suseconds_t lastupdate;
|
||||||
|
int anpos;
|
||||||
} calc;
|
} calc;
|
||||||
/* TODO: information structs for the other states */
|
/* TODO: information structs for the other states */
|
||||||
};
|
};
|
||||||
|
|
@ -166,6 +174,8 @@ extern struct state pstate;
|
||||||
/*
|
/*
|
||||||
* G L O B A L F U N C T I O N S
|
* G L O B A L F U N C T I O N S
|
||||||
*/
|
*/
|
||||||
|
/* main.c */
|
||||||
|
int input_handle(int);
|
||||||
/* util.c */
|
/* util.c */
|
||||||
char *cropdir(const char *, int);
|
char *cropdir(const char *, int);
|
||||||
char *cropsize(const off_t);
|
char *cropsize(const off_t);
|
||||||
|
|
@ -176,7 +186,9 @@ void ncprint(int, int, char *, ...);
|
||||||
struct dir *freedir(struct dir *);
|
struct dir *freedir(struct dir *);
|
||||||
char *getpath(struct dir *, char *);
|
char *getpath(struct dir *, char *);
|
||||||
/* calc.c */
|
/* calc.c */
|
||||||
struct dir *showCalc(char *);
|
void calc_process(void);
|
||||||
|
int calc_key(int);
|
||||||
|
int calc_draw(void);
|
||||||
/* browser.c */
|
/* browser.c */
|
||||||
void drawBrowser(int);
|
void drawBrowser(int);
|
||||||
void showBrowser(void);
|
void showBrowser(void);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue