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-23 09:44:37 -08:00
|
|
|
#include "path.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
|
|
|
|
|
|
|
|
|
|
|
2009-04-18 04:36:24 -08:00
|
|
|
/* external vars */
|
2009-04-18 04:16:48 -08:00
|
|
|
int calc_delay = 100;
|
|
|
|
|
char calc_smfs = 0;
|
2009-04-18 03:51:45 -08:00
|
|
|
|
2009-04-18 04:36:24 -08:00
|
|
|
/* global vars for internal use */
|
|
|
|
|
char failed; /* 1 on fatal error */
|
2009-04-23 11:15:11 -08:00
|
|
|
char *curpath; /* last lstat()'ed item */
|
|
|
|
|
char *lasterr; /* last unreadable dir/item */
|
|
|
|
|
char errmsg[128]; /* error message, when failed=1 */
|
2009-04-18 04:36:24 -08:00
|
|
|
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 */
|
2009-04-19 04:29:49 -08:00
|
|
|
long lastupdate; /* time of the last screen update */
|
2009-04-18 04:36:24 -08:00
|
|
|
int anpos; /* position of the animation string */
|
2009-04-23 11:15:11 -08:00
|
|
|
int curpathl = 0, lasterrl = 0;
|
2007-07-20 03:15:46 -08:00
|
|
|
|
2007-07-25 10:38:49 -08:00
|
|
|
|
2009-04-23 11:15:11 -08:00
|
|
|
int calc_item(struct dir *par, char *name) {
|
2009-04-10 08:16:33 -08:00
|
|
|
struct dir *t, *d;
|
|
|
|
|
struct stat fs;
|
2009-04-23 11:15:11 -08:00
|
|
|
char *tmp;
|
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;
|
|
|
|
|
|
|
|
|
|
/* 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-23 11:15:11 -08:00
|
|
|
/* update curpath */
|
|
|
|
|
tmp = getpath(d);
|
|
|
|
|
if((int)strlen(tmp)+1 > curpathl) {
|
|
|
|
|
curpathl = strlen(tmp)+1;
|
|
|
|
|
curpath = realloc(curpath, curpathl);
|
|
|
|
|
}
|
2009-04-18 04:36:24 -08:00
|
|
|
strcpy(curpath, tmp);
|
2009-04-23 11:15:11 -08:00
|
|
|
|
|
|
|
|
/* lstat */
|
|
|
|
|
if(lstat(d->name, &fs)) {
|
2009-04-10 08:16:33 -08:00
|
|
|
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-23 11:15:11 -08:00
|
|
|
if(exclude_match(curpath))
|
2009-04-10 08:16:33 -08:00
|
|
|
d->flags |= FF_EXL;
|
|
|
|
|
|
2009-04-18 04:36:24 -08:00
|
|
|
if(calc_smfs && 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-23 11:15:11 -08:00
|
|
|
/* recursively walk through the directory tree,
|
|
|
|
|
assumes path resides in the cwd */
|
2009-04-25 04:31:54 -08:00
|
|
|
int calc_dir(struct dir *dest, char *name) {
|
2009-04-10 08:16:33 -08:00
|
|
|
struct dir *t;
|
2007-07-20 03:15:46 -08:00
|
|
|
DIR *dir;
|
2009-04-23 11:15:11 -08:00
|
|
|
char *tmp;
|
2007-07-20 03:15:46 -08:00
|
|
|
struct dirent *dr;
|
2009-04-23 11:15:11 -08:00
|
|
|
int ch;
|
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 */
|
2009-04-25 04:31:54 -08:00
|
|
|
if((dir = opendir(name)) == NULL) {
|
2009-04-23 11:15:11 -08:00
|
|
|
tmp = getpath(dest);
|
|
|
|
|
if(lasterrl < (int)strlen(tmp)+1) {
|
|
|
|
|
lasterrl = strlen(tmp)+1;
|
|
|
|
|
lasterr = realloc(lasterr, lasterrl);
|
|
|
|
|
}
|
|
|
|
|
strcpy(lasterr, tmp);
|
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-23 11:15:11 -08:00
|
|
|
/* chdir */
|
2009-04-25 04:31:54 -08:00
|
|
|
if(chdir(name) < 0) {
|
2009-04-23 11:15:11 -08:00
|
|
|
dest->flags |= FF_ERR;
|
|
|
|
|
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
|
|
|
/* read directory */
|
|
|
|
|
while((dr = readdir(dir)) != NULL) {
|
2009-04-23 11:15:11 -08:00
|
|
|
if(calc_item(dest, dr->d_name))
|
2009-04-10 08:16:33 -08:00
|
|
|
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 */
|
2009-04-23 11:15:11 -08:00
|
|
|
ch = 0;
|
2009-04-10 08:16:33 -08:00
|
|
|
for(t=dest->sub; t!=NULL; t=t->next)
|
2009-04-23 11:15:11 -08:00
|
|
|
if(t->flags & FF_DIR && !(t->flags & FF_EXL || t->flags & FF_OTHFS))
|
2009-04-25 04:31:54 -08:00
|
|
|
if(calc_dir(t, t->name))
|
2009-04-10 08:16:33 -08:00
|
|
|
return 1;
|
2009-04-23 11:15:11 -08:00
|
|
|
|
|
|
|
|
/* chdir back */
|
|
|
|
|
if(chdir("..") < 0) {
|
|
|
|
|
failed = 1;
|
|
|
|
|
strcpy(errmsg, "Couldn't chdir to previous directory");
|
|
|
|
|
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-18 23:45:27 -08:00
|
|
|
nccreate(10, 60, !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-18 04:36:24 -08:00
|
|
|
root->items, formatsize(root->size));
|
|
|
|
|
ncprint(3, 2, "Current dir: %s", cropstr(curpath, 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-18 04:36:24 -08:00
|
|
|
if(lasterr[0] != '\0') {
|
2009-04-10 08:16:33 -08:00
|
|
|
attron(A_BOLD);
|
|
|
|
|
ncaddstr(5, 2, "Warning:");
|
|
|
|
|
attroff(A_BOLD);
|
2009-04-18 04:36:24 -08:00
|
|
|
ncprint(5, 11, "could not open %-32s", cropstr(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-18 04:36:24 -08:00
|
|
|
if(++anpos == 28)
|
|
|
|
|
anpos = 0;
|
2009-04-10 08:16:33 -08:00
|
|
|
strcpy(ani, " ");
|
2009-04-18 04:36:24 -08:00
|
|
|
if(anpos < 14)
|
|
|
|
|
for(i=0; i<=anpos; i++)
|
2009-04-10 08:16:33 -08:00
|
|
|
ani[i] = antext[i];
|
|
|
|
|
else
|
2009-04-18 04:36:24 -08:00
|
|
|
for(i=13; i>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-18 04:36:24 -08:00
|
|
|
if(failed) {
|
2009-04-18 05:35:37 -08:00
|
|
|
browse_draw();
|
2009-04-18 04:36:24 -08:00
|
|
|
calc_draw_error(curpath, 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-18 04:36:24 -08:00
|
|
|
if(lastupdate != tv.tv_usec) {
|
2009-04-18 05:35:37 -08:00
|
|
|
browse_draw();
|
2009-04-10 08:16:33 -08:00
|
|
|
calc_draw_progress();
|
2009-04-18 04:36:24 -08:00
|
|
|
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-18 04:36:24 -08:00
|
|
|
if(failed)
|
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() {
|
2009-04-25 04:29:20 -08:00
|
|
|
char *path, *name;
|
2009-04-10 08:16:33 -08:00
|
|
|
struct stat fs;
|
|
|
|
|
struct dir *t;
|
|
|
|
|
|
|
|
|
|
/* check root directory */
|
2009-04-25 04:29:20 -08:00
|
|
|
if((path = path_real(curpath)) == NULL) {
|
2009-04-18 04:36:24 -08:00
|
|
|
failed = 1;
|
|
|
|
|
strcpy(errmsg, "Directory not found");
|
2009-04-25 01:49:20 -08:00
|
|
|
goto calc_fail;
|
2009-04-10 08:16:33 -08:00
|
|
|
}
|
2009-04-25 04:29:20 -08:00
|
|
|
/* split into path and last component */
|
|
|
|
|
name = strrchr(path, '/');
|
|
|
|
|
*(name++) = 0;
|
2009-04-25 01:49:20 -08:00
|
|
|
/* we need to chdir so we can provide relative paths for lstat() and opendir(),
|
|
|
|
|
* this to prevent creating path names longer than PATH_MAX */
|
2009-04-25 04:29:20 -08:00
|
|
|
if(path_chdir(path) < 0) {
|
2009-04-23 11:15:11 -08:00
|
|
|
failed = 1;
|
|
|
|
|
strcpy(errmsg, "Couldn't chdir into directory");
|
2009-04-25 04:29:20 -08:00
|
|
|
free(path);
|
2009-04-25 01:49:20 -08:00
|
|
|
goto calc_fail;
|
|
|
|
|
}
|
|
|
|
|
/* would be strange for this to fail, but oh well... */
|
2009-04-25 04:29:20 -08:00
|
|
|
if(lstat(name, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
2009-04-25 01:49:20 -08:00
|
|
|
failed = 1;
|
|
|
|
|
strcpy(errmsg, "Couldn't stat directory");
|
2009-04-25 04:29:20 -08:00
|
|
|
free(path);
|
2009-04-25 01:49:20 -08:00
|
|
|
goto calc_fail;
|
2009-04-23 11:15:11 -08:00
|
|
|
}
|
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-25 04:29:20 -08:00
|
|
|
if(orig) {
|
|
|
|
|
t->name = malloc(strlen(orig->name)+1);
|
|
|
|
|
strcpy(t->name, orig->name);
|
|
|
|
|
} else {
|
|
|
|
|
t->name = malloc(strlen(path)+strlen(name)+1);
|
|
|
|
|
strcpy(t->name, path);
|
|
|
|
|
strcat(t->name, "/");
|
|
|
|
|
strcat(t->name, name);
|
|
|
|
|
}
|
2009-04-18 04:36:24 -08:00
|
|
|
root = t;
|
|
|
|
|
curdev = fs.st_dev;
|
2009-04-25 04:29:20 -08:00
|
|
|
free(path);
|
2009-04-10 08:16:33 -08:00
|
|
|
|
|
|
|
|
/* start calculating */
|
2009-04-25 04:31:54 -08:00
|
|
|
if(!calc_dir(root, name) && !failed) {
|
2009-04-18 05:23:33 -08:00
|
|
|
browse_init(root->sub);
|
2009-04-13 09:32:40 -08:00
|
|
|
|
|
|
|
|
/* update references and free original item */
|
2009-04-18 04:36:24 -08:00
|
|
|
if(orig) {
|
2009-04-18 05:07:23 -08:00
|
|
|
root->parent = orig->parent;
|
|
|
|
|
root->next = orig->next;
|
|
|
|
|
for(t=root->parent; t!=NULL; t=t->parent) {
|
|
|
|
|
t->size += root->size;
|
|
|
|
|
t->asize += root->asize;
|
|
|
|
|
t->items += root->items+1;
|
|
|
|
|
}
|
|
|
|
|
|
2009-04-18 04:36:24 -08:00
|
|
|
if(orig->parent) {
|
|
|
|
|
t = orig->parent->sub;
|
|
|
|
|
if(t == orig)
|
|
|
|
|
orig->parent->sub = root;
|
2009-04-13 09:32:40 -08:00
|
|
|
else if(t != NULL)
|
|
|
|
|
for(; t->next!=NULL; t=t->next)
|
2009-04-18 04:36:24 -08:00
|
|
|
if(t->next == orig)
|
|
|
|
|
t->next = root;
|
2009-04-13 09:32:40 -08:00
|
|
|
}
|
2009-04-18 04:36:24 -08:00
|
|
|
freedir(orig);
|
2009-04-13 09:32:40 -08:00
|
|
|
}
|
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-18 04:36:24 -08:00
|
|
|
freedir(root);
|
2009-04-25 01:49:20 -08:00
|
|
|
calc_fail:
|
2009-04-18 04:36:24 -08:00
|
|
|
while(failed && !input_handle(0))
|
2009-04-10 08:16:33 -08:00
|
|
|
;
|
2009-04-18 04:36:24 -08:00
|
|
|
pstate = 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
|
|
|
|
2009-04-18 04:36:24 -08:00
|
|
|
void calc_init(char *dir, struct dir *org) {
|
2009-04-23 11:15:11 -08:00
|
|
|
failed = anpos = 0;
|
2009-04-18 04:36:24 -08:00
|
|
|
lastupdate = 999;
|
|
|
|
|
orig = org;
|
2009-04-23 11:15:11 -08:00
|
|
|
if(curpathl == 0) {
|
|
|
|
|
curpathl = strlen(dir);
|
|
|
|
|
curpath = malloc(curpathl);
|
|
|
|
|
} else if(curpathl < (int)strlen(dir)+1) {
|
|
|
|
|
curpathl = strlen(dir)+1;
|
|
|
|
|
curpath = realloc(curpath, curpathl);
|
|
|
|
|
}
|
2009-04-18 04:36:24 -08:00
|
|
|
strcpy(curpath, dir);
|
2009-04-23 11:15:11 -08:00
|
|
|
if(lasterrl == 0) {
|
|
|
|
|
lasterrl = 1;
|
|
|
|
|
lasterr = malloc(lasterrl);
|
|
|
|
|
}
|
|
|
|
|
lasterr[0] = 0;
|
2009-04-16 08:26:39 -08:00
|
|
|
pstate = ST_CALC;
|
|
|
|
|
}
|
|
|
|
|
|