Converted all code to call the compll functions

This commit is contained in:
Yorhel 2010-05-10 11:08:44 +02:00
parent 686084d6e0
commit ab435e664f
12 changed files with 348 additions and 314 deletions

View file

@ -38,13 +38,14 @@ int graph = 0,
void browse_draw_info(struct dir *dr) {
struct dir *t;
void browse_draw_info(compll_t dr) {
const struct dir *tmp = DR(dr);
compll_t t;
int i;
nccreate(11, 60, "Item info");
if(dr->hlnk) {
if(tmp->hlnk) {
if(info_page == 0)
attron(A_REVERSE);
ncaddstr(0, 41, "1:Info");
@ -65,16 +66,16 @@ void browse_draw_info(struct dir *dr) {
ncaddstr(7, 3, "Apparent size:");
attroff(A_BOLD);
ncaddstr(2, 9, cropstr(dr->name, 49));
ncaddstr(3, 9, cropstr(getpath(dr->parent), 49));
ncaddstr(4, 9, dr->flags & FF_DIR ? "Directory"
: dr->flags & FF_FILE ? "File" : "Other (link, device, socket, ..)");
ncprint(6, 18, "%s (%s B)", formatsize(dr->size), fullsize(dr->size));
ncprint(7, 18, "%s (%s B)", formatsize(dr->asize), fullsize(dr->asize));
ncaddstr(2, 9, cropstr(tmp->name, 49));
ncaddstr(3, 9, cropstr(getpath(tmp->parent), 49));
ncaddstr(4, 9, tmp->flags & FF_DIR ? "Directory"
: DR(dr)->flags & FF_FILE ? "File" : "Other (link, device, socket, ..)");
ncprint(6, 18, "%s (%s B)", formatsize(tmp->size), fullsize(tmp->size));
ncprint(7, 18, "%s (%s B)", formatsize(tmp->asize), fullsize(tmp->asize));
break;
case 1:
for(i=0,t=dr->hlnk; t!=dr; t=t->hlnk,i++) {
for(i=0,t=tmp->hlnk; t!=dr; t=DR(t)->hlnk,i++) {
if(info_start > i)
continue;
if(i-info_start > 5)
@ -90,12 +91,13 @@ void browse_draw_info(struct dir *dr) {
}
void browse_draw_item(struct dir *n, int row, char *line) {
void browse_draw_item(compll_t n, int row, char *line) {
char ct, dt, *size, gr[11];
const struct dir *t = DR(n);
int i, o;
float pc;
if(n->flags & FF_BSEL)
if(t->flags & FF_BSEL)
attron(A_REVERSE);
/* reference to parent dir has a different format */
@ -106,34 +108,35 @@ void browse_draw_item(struct dir *n, int row, char *line) {
graph == 2 ? 20 :
31 ;
mvaddstr(row, o, "/..");
if(n->flags & FF_BSEL)
if(t->flags & FF_BSEL)
attroff(A_REVERSE);
return;
}
/* determine indication character */
ct = n->flags & FF_EXL ? '<' :
n->flags & FF_ERR ? '!' :
n->flags & FF_SERR ? '.' :
n->flags & FF_OTHFS ? '>' :
n->flags & FF_HLNKC ? 'H' :
!(n->flags & FF_FILE
|| n->flags & FF_DIR) ? '@' :
n->flags & FF_DIR
&& n->sub == NULL ? 'e' :
ct = t->flags & FF_EXL ? '<' :
t->flags & FF_ERR ? '!' :
t->flags & FF_SERR ? '.' :
t->flags & FF_OTHFS ? '>' :
t->flags & FF_HLNKC ? 'H' :
!(t->flags & FF_FILE
|| t->flags & FF_DIR) ? '@' :
t->flags & FF_DIR
&& !t->sub ? 'e' :
' ' ;
dt = n->flags & FF_DIR ? '/' : ' ';
size = formatsize(show_as ? n->asize : n->size);
dt = t->flags & FF_DIR ? '/' : ' ';
size = formatsize(show_as ? t->asize : t->size);
/* create graph (if necessary) */
if(graph) {
/* percentage */
if((pc = (float)(show_as ? n->parent->asize : n->parent->size)) < 1)
if((pc = (float)(show_as ? DR(t->parent)->asize : DR(t->parent)->size)) < 1)
pc = 1.0f;
pc = ((float)(show_as ? n->asize : n->size) / pc) * 100.0f;
t = DR(n);
pc = ((float)(show_as ? t->asize : t->size) / pc) * 100.0f;
/* graph */
if(graph == 1 || graph == 3) {
o = (int)(10.0f*(float)(show_as ? n->asize : n->size) / (float)(show_as ? dirlist_maxa : dirlist_maxs));
o = (int)(10.0f*(float)(show_as ? t->asize : t->size) / (float)(show_as ? dirlist_maxa : dirlist_maxs));
for(i=0; i<10; i++)
gr[i] = i < o ? '#' : ' ';
gr[10] = '\0';
@ -142,19 +145,19 @@ void browse_draw_item(struct dir *n, int row, char *line) {
/* format and add item to the list */
switch(graph) {
case 0: mvprintw(row, 0, line, ct, size, dt, cropstr(n->name, wincols-13)); break;
case 1: mvprintw(row, 0, line, ct, size, gr, dt, cropstr(n->name, wincols-25)); break;
case 2: mvprintw(row, 0, line, ct, size, pc, dt, cropstr(n->name, wincols-21)); break;
case 3: mvprintw(row, 0, line, ct, size, pc, gr, dt, cropstr(n->name, wincols-32));
case 0: mvprintw(row, 0, line, ct, size, dt, cropstr(t->name, wincols-13)); break;
case 1: mvprintw(row, 0, line, ct, size, gr, dt, cropstr(t->name, wincols-25)); break;
case 2: mvprintw(row, 0, line, ct, size, pc, dt, cropstr(t->name, wincols-21)); break;
case 3: mvprintw(row, 0, line, ct, size, pc, gr, dt, cropstr(t->name, wincols-32));
}
if(n->flags & FF_BSEL)
if(t->flags & FF_BSEL)
attroff(A_REVERSE);
}
void browse_draw() {
struct dir *t;
compll_t t;
char fmtsize[9], *tmp, line[35];
int selected, i;
@ -172,7 +175,7 @@ void browse_draw() {
mvhline(1, 0, '-', wincols);
if(t) {
mvaddch(1, 3, ' ');
tmp = getpath(t->parent);
tmp = getpath(DR(t)->parent);
mvaddstr(1, 4, cropstr(tmp, wincols-8));
mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' ');
}
@ -180,9 +183,9 @@ void browse_draw() {
/* bottom line - stats */
attron(A_REVERSE);
if(t) {
strcpy(fmtsize, formatsize(t->parent->size));
strcpy(fmtsize, formatsize(DR(DR(t)->parent)->size));
mvprintw(winrows-1, 0, " Total disk usage: %s Apparent size: %s Items: %d",
fmtsize, formatsize(t->parent->asize), t->parent->items);
fmtsize, formatsize(DR(DR(t)->parent)->asize), DR(DR(t)->parent)->items);
} else
mvaddstr(winrows-1, 0, " No items to display.");
attroff(A_REVERSE);
@ -206,7 +209,7 @@ void browse_draw() {
for(i=0; t && i<winrows-3; t=dirlist_next(t),i++) {
browse_draw_item(t, 2+i, line);
/* save the selected row number for later */
if(t->flags & FF_BSEL)
if(DR(t)->flags & FF_BSEL)
selected = i;
}
@ -221,7 +224,7 @@ void browse_draw() {
int browse_key(int ch) {
struct dir *t, *sel;
compll_t t, sel;
int i, catch = 0;
sel = dirlist_get(0);
@ -233,26 +236,26 @@ int browse_key(int ch) {
info_page = 0;
break;
case '2':
if(sel->hlnk)
if(DR(sel)->hlnk)
info_page = 1;
break;
case KEY_RIGHT:
case 'l':
if(sel->hlnk) {
if(DR(sel)->hlnk) {
info_page = 1;
catch++;
}
break;
case KEY_LEFT:
case 'h':
if(sel->hlnk) {
if(DR(sel)->hlnk) {
info_page = 0;
catch++;
}
break;
case KEY_UP:
case 'k':
if(sel->hlnk && info_page == 1) {
if(DR(sel)->hlnk && info_page == 1) {
if(info_start > 0)
info_start--;
catch++;
@ -261,8 +264,8 @@ int browse_key(int ch) {
case KEY_DOWN:
case 'j':
case ' ':
if(sel->hlnk && info_page == 1) {
for(i=0,t=sel->hlnk; t!=sel; t=t->hlnk)
if(DR(sel)->hlnk && info_page == 1) {
for(i=0,t=DR(sel)->hlnk; t!=sel; t=DR(t)->hlnk)
i++;
if(i > info_start+6)
info_start++;
@ -287,7 +290,7 @@ int browse_key(int ch) {
info_start = 0;
break;
case KEY_HOME:
dirlist_select(dirlist_next(NULL));
dirlist_select(dirlist_next((compll_t)0));
dirlist_top(2);
info_start = 0;
break;
@ -337,8 +340,8 @@ int browse_key(int ch) {
case 10:
case KEY_RIGHT:
case 'l':
if(sel != NULL && sel->sub != NULL) {
dirlist_open(sel->sub);
if(sel && DR(sel)->sub) {
dirlist_open(DR(sel)->sub);
dirlist_top(-3);
}
info_show = 0;
@ -346,8 +349,8 @@ int browse_key(int ch) {
case KEY_LEFT:
case 'h':
case '<':
if(sel != NULL && sel->parent->parent != NULL) {
dirlist_open(sel->parent);
if(sel && DR(DR(sel)->parent)->parent) {
dirlist_open(DR(sel)->parent);
dirlist_top(-3);
}
info_show = 0;
@ -355,8 +358,8 @@ int browse_key(int ch) {
/* and other stuff */
case 'r':
if(sel != NULL)
calc_init(getpath(sel->parent), sel->parent);
if(sel)
calc_init(getpath(DR(sel)->parent), DR(sel)->parent);
info_show = 0;
break;
case 'q':
@ -378,12 +381,12 @@ int browse_key(int ch) {
info_show = 0;
break;
case 'd':
if(sel == NULL || sel == dirlist_parent)
if(!sel || sel == dirlist_parent)
break;
info_show = 0;
if((t = dirlist_get(1)) == sel)
if((t = dirlist_get(-1)) == sel || t == dirlist_parent)
t = sel->parent;
t = DR(sel)->parent;
delete_init(sel, t);
break;
}
@ -392,14 +395,14 @@ int browse_key(int ch) {
sel = dirlist_get(0);
if(!info_show || sel == dirlist_parent)
info_show = info_page = info_start = 0;
else if(sel && !sel->hlnk)
else if(sel && !DR(sel)->hlnk)
info_page = info_start = 0;
return 0;
}
void browse_init(struct dir *cur) {
void browse_init(compll_t cur) {
pstate = ST_BROWSE;
dirlist_open(cur);
}

View file

@ -30,7 +30,7 @@
int browse_key(int);
void browse_draw(void);
void browse_init(struct dir *);
void browse_init(compll_t);
#endif

View file

@ -49,19 +49,19 @@ char failed; /* 1 on fatal error */
char *curpath; /* last lstat()'ed item, used for excludes matching and display */
char *lasterr; /* last unreadable dir/item */
char errmsg[128]; /* error message, when failed=1 */
struct dir *root; /* root directory struct we're calculating */
struct dir *orig; /* original directory, when recalculating */
compll_t root; /* root directory struct we're calculating */
compll_t 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 dir **links = NULL;
compll_t *links = NULL;
int linksl, linkst;
/* adds name to curpath */
void calc_enterpath(char *name) {
void calc_enterpath(const char *name) {
int n;
n = strlen(curpath)+strlen(name)+2;
@ -88,11 +88,11 @@ void calc_leavepath() {
/* looks in the links list and adds the file when not found */
int calc_hlink_add(struct dir *d) {
int calc_hlink_add(compll_t d) {
int i;
/* check the list */
for(i=0; i<linkst; i++)
if(links[i]->dev == d->dev && links[i]->ino == d->ino)
if(DR(links[i])->dev == DR(d)->dev && DR(links[i])->ino == DR(d)->ino)
break;
/* found, do nothing and return the index */
if(i != linkst)
@ -102,9 +102,9 @@ int calc_hlink_add(struct dir *d) {
linksl *= 2;
if(!linksl) {
linksl = 64;
links = malloc(linksl*sizeof(struct dir *));
links = malloc(linksl*sizeof(compll_t));
} else
links = realloc(links, linksl*sizeof(struct dir *));
links = realloc(links, linksl*sizeof(compll_t));
}
links[linkst-1] = d;
return -1;
@ -112,13 +112,13 @@ int calc_hlink_add(struct dir *d) {
/* recursively checks a dir structure for hard links and fills the lookup array */
void calc_hlink_init(struct dir *d) {
struct dir *t;
void calc_hlink_init(compll_t d) {
compll_t t;
for(t=d->sub; t!=NULL; t=t->next)
for(t=DR(d)->sub; t; t=DR(t)->next)
calc_hlink_init(t);
if(!(d->flags & FF_HLNKC))
if(!(DR(d)->flags & FF_HLNKC))
return;
calc_hlink_add(d);
}
@ -126,103 +126,103 @@ void calc_hlink_init(struct dir *d) {
/* checks an individual file and updates the flags and cicrular linked list,
* also updates the sizes of the parent dirs */
void calc_hlink_check(struct dir *d) {
struct dir *t, *pt, *par;
void calc_hlink_check(compll_t d) {
compll_t t, pt, par;
int i;
d->flags |= FF_HLNKC;
DW(d)->flags |= FF_HLNKC;
i = calc_hlink_add(d);
/* found in the list? update hlnk */
if(i >= 0) {
t = d->hlnk = links[i];
if(t->hlnk != NULL)
for(t=t->hlnk; t->hlnk!=d->hlnk; t=t->hlnk)
t = DW(d)->hlnk = links[i];
if(DR(t)->hlnk)
for(t=DR(t)->hlnk; DR(t)->hlnk!=DR(d)->hlnk; t=DR(t)->hlnk)
;
t->hlnk = d;
DW(t)->hlnk = d;
}
/* now update the sizes of the parent directories,
* This works by only counting this file in the parent directories where this
* file hasn't been counted yet, which can be determined from the hlnk list.
* XXX: This may not be the most efficient algorithm to do this */
for(i=1,par=d->parent; i&&par; par=par->parent) {
if(d->hlnk)
for(t=d->hlnk; i&&t!=d; t=t->hlnk)
for(pt=t->parent; i&&pt; pt=pt->parent)
for(i=1,par=DR(d)->parent; i&&par; par=DR(par)->parent) {
if(DR(d)->hlnk)
for(t=DR(d)->hlnk; i&&t!=d; t=DR(t)->hlnk)
for(pt=DR(t)->parent; i&&pt; pt=DR(pt)->parent)
if(pt==par)
i=0;
if(i) {
par->size += d->size;
par->asize += d->asize;
DW(par)->size += DR(d)->size;
DW(par)->asize += DR(d)->asize;
}
}
}
int calc_item(struct dir *par, char *name) {
struct dir *t, *d;
int calc_item(compll_t par, char *name) {
compll_t t, d;
struct stat fs;
if(name[0] == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0')))
return 0;
/* allocate dir and fix references */
d = calloc(SDIRSIZE+strlen(name), 1);
d->parent = par;
d->next = par->sub;
par->sub = d;
if(d->next)
d->next->prev = d;
strcpy(d->name, name);
d = compll_alloc(SDIRSIZE+strlen(name));
DW(d)->parent = par;
DW(d)->next = DR(par)->sub;
DW(par)->sub = d;
if(DR(d)->next)
DW(DR(d)->next)->prev = d;
strcpy(DW(d)->name, name);
#ifdef __CYGWIN__
/* /proc/registry names may contain slashes */
if(strchr(d->name, '/') || strchr(d->name, '\\')) {
d->flags |= FF_ERR;
if(strchr(name, '/') || strchr(name, '\\')) {
DW(d)->flags |= FF_ERR;
return 0;
}
#endif
/* lstat */
if(lstat(name, &fs)) {
d->flags |= FF_ERR;
DW(d)->flags |= FF_ERR;
return 0;
}
/* check for excludes and same filesystem */
if(exclude_match(curpath))
d->flags |= FF_EXL;
DW(d)->flags |= FF_EXL;
if(calc_smfs && curdev != fs.st_dev)
d->flags |= FF_OTHFS;
DW(d)->flags |= FF_OTHFS;
/* determine type of this item */
if(S_ISREG(fs.st_mode))
d->flags |= FF_FILE;
DW(d)->flags |= FF_FILE;
else if(S_ISDIR(fs.st_mode))
d->flags |= FF_DIR;
DW(d)->flags |= FF_DIR;
/* update the items count of the parent dirs */
if(!(d->flags & FF_EXL))
for(t=d->parent; t!=NULL; t=t->parent)
t->items++;
if(!(DR(d)->flags & FF_EXL))
for(t=DR(d)->parent; t; t=DR(t)->parent)
DW(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;
if(!(DR(d)->flags & FF_EXL || DR(d)->flags & FF_OTHFS)) {
DW(d)->size = fs.st_blocks * S_BLKSIZE;
DW(d)->asize = fs.st_size;
/* only update the sizes of the parents if it's not a hard link */
if(S_ISDIR(fs.st_mode) || fs.st_nlink <= 1)
for(t=d->parent; t!=NULL; t=t->parent) {
t->size += d->size;
t->asize += d->asize;
for(t=DR(d)->parent; t; t=DR(t)->parent) {
DW(t)->size += DR(d)->size;
DW(t)->asize += DR(d)->asize;
}
}
/* Hard link checking (also takes care of updating the sizes of the parents) */
d->ino = fs.st_ino;
d->dev = fs.st_dev;
DW(d)->ino = fs.st_ino;
DW(d)->dev = fs.st_dev;
if(!S_ISDIR(fs.st_mode) && fs.st_nlink > 1)
calc_hlink_check(d);
@ -232,8 +232,8 @@ int calc_item(struct dir *par, char *name) {
/* recursively walk through the directory tree,
assumes path resides in the cwd */
int calc_dir(struct dir *dest, char *name) {
struct dir *t;
int calc_dir(compll_t dest, const char *name) {
compll_t t;
DIR *dir;
struct dirent *dr;
int ch;
@ -251,10 +251,10 @@ int calc_dir(struct dir *dest, char *name) {
lasterr = realloc(lasterr, lasterrl);
}
strcpy(lasterr, curpath);
dest->flags |= FF_ERR;
DW(dest)->flags |= FF_ERR;
t = dest;
while((t = t->parent) != NULL)
t->flags |= FF_SERR;
while((t = DR(t)->parent))
DW(t)->flags |= FF_SERR;
calc_leavepath();
if(dir != NULL)
closedir(dir);
@ -265,7 +265,7 @@ int calc_dir(struct dir *dest, char *name) {
while((dr = readdir(dir)) != NULL) {
calc_enterpath(dr->d_name);
if(calc_item(dest, dr->d_name))
dest->flags |= FF_ERR;
DW(dest)->flags |= FF_ERR;
if(input_handle(1)) {
calc_leavepath();
closedir(dir);
@ -276,26 +276,25 @@ int calc_dir(struct dir *dest, char *name) {
}
if(errno) {
if(dest->flags & FF_SERR)
dest->flags -= FF_SERR;
dest->flags |= FF_ERR;
DW(dest)->flags &= ~FF_SERR;
DW(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;
for(t=DR(dest)->sub; t; t=DR(t)->next)
if(DR(t)->flags & FF_ERR || DR(t)->flags & FF_SERR)
DW(dest)->flags |= FF_SERR;
if(DR(dest)->flags & FF_ERR || DR(dest)->flags & FF_SERR) {
for(t = dest; (t = DR(t)->parent); )
DW(t)->flags |= FF_SERR;
}
/* calculate subdirectories */
ch = 0;
for(t=dest->sub; t!=NULL; t=t->next)
if(t->flags & FF_DIR && !(t->flags & FF_EXL || t->flags & FF_OTHFS))
if(calc_dir(t, t->name)) {
for(t=DR(dest)->sub; t; t=DR(t)->next)
if(DR(t)->flags & FF_DIR && !(DR(t)->flags & FF_EXL || DR(t)->flags & FF_OTHFS))
if(calc_dir(t, DR(t)->name)) {
calc_leavepath();
return 1;
}
@ -321,7 +320,7 @@ void calc_draw_progress() {
nccreate(10, 60, !orig ? "Calculating..." : "Recalculating...");
ncprint(2, 2, "Total items: %-8d size: %s",
root->items, formatsize(root->size));
DR(root)->items, formatsize(DR(root)->size));
ncprint(3, 2, "Current dir: %s", cropstr(curpath, 43));
ncaddstr(8, 43, "Press q to quit");
@ -385,13 +384,13 @@ int calc_key(int ch) {
int calc_process() {
char *path, *name;
struct stat fs;
struct dir *t;
compll_t t;
int n;
/* create initial links array */
linksl = linkst = 0;
if(orig) {
for(t=orig; t->parent!=NULL; t=t->parent)
for(t=orig; DR(t)->parent; t=DR(t)->parent)
;
calc_hlink_init(t);
}
@ -433,21 +432,21 @@ int calc_process() {
}
/* initialize parent dir */
n = orig ? strlen(orig->name) : strlen(path)+strlen(name)+1;
t = (struct dir *) calloc(1, SDIRSIZE+n);
t->size = fs.st_blocks * S_BLKSIZE;
t->asize = fs.st_size;
t->flags |= FF_DIR;
n = orig ? strlen(DR(orig)->name) : strlen(path)+strlen(name)+1;
t = compll_alloc(SDIRSIZE+n);
DW(t)->size = fs.st_blocks * S_BLKSIZE;
DW(t)->asize = fs.st_size;
DW(t)->flags |= FF_DIR;
if(orig) {
strcpy(t->name, orig->name);
t->parent = orig->parent;
strcpy(DW(t)->name, DR(orig)->name);
DW(t)->parent = DR(orig)->parent;
} else {
t->name[0] = 0;
DW(t)->name[0] = 0;
if(strcmp(path, "/"))
strcpy(t->name, path);
strcpy(DW(t)->name, path);
if(strcmp(name, ".")) {
strcat(t->name, "/");
strcat(t->name, name);
strcat(DW(t)->name, "/");
strcat(DW(t)->name, name);
}
}
root = t;
@ -455,10 +454,10 @@ int calc_process() {
/* make sure to count this directory entry in its parents at this point */
if(orig)
for(t=root->parent; t!=NULL; t=t->parent) {
t->size += root->size;
t->asize += root->asize;
t->items += 1;
for(t=DR(root)->parent; t; t=DR(t)->parent) {
DW(t)->size += DR(root)->size;
DW(t)->asize += DR(root)->asize;
DW(t)->items += 1;
}
/* update curpath */
@ -486,7 +485,7 @@ int calc_process() {
/* success */
if(!n && !failed) {
if(root->sub == NULL) {
if(!DR(root)->sub) {
freedir(root);
failed = 1;
strcpy(errmsg, "Directory empty.");
@ -495,18 +494,18 @@ int calc_process() {
/* update references and free original item */
if(orig) {
root->next = orig->next;
root->prev = orig->prev;
if(root->parent && root->parent->sub == orig)
root->parent->sub = root;
if(root->prev)
root->prev->next = root;
if(root->next)
root->next->prev = root;
orig->next = orig->prev = NULL;
DW(root)->next = DR(orig)->next;
DW(root)->prev = DR(orig)->prev;
if(DR(root)->parent && DR(DR(root)->parent)->sub == orig)
DW(DR(root)->parent)->sub = root;
if(DR(root)->prev)
DW(DR(root)->prev)->next = root;
if(DR(root)->next)
DW(DR(root)->next)->prev = root;
DW(orig)->next = DW(orig)->prev = (compll_t)0;
freedir(orig);
}
browse_init(root->sub);
browse_init(DR(root)->sub);
dirlist_top(-3);
return 0;
}
@ -516,7 +515,7 @@ int calc_process() {
calc_fail:
while(failed && !input_handle(0))
;
if(orig == NULL)
if(!orig)
return 1;
else {
browse_init(orig);
@ -525,7 +524,7 @@ calc_fail:
}
void calc_init(char *dir, struct dir *org) {
void calc_init(char *dir, compll_t org) {
failed = anpos = 0;
orig = org;
if(curpathl == 0) {

View file

@ -33,7 +33,7 @@ extern char calc_smfs; /* stay on the same filesystem */
int calc_process(void);
int calc_key(int);
void calc_draw(void);
void calc_init(char *, struct dir *);
void calc_init(char *, compll_t);
#endif

View file

@ -36,7 +36,7 @@
#define DS_FAILED 2
struct dir *root, *nextsel, *curdir;
compll_t root, nextsel, curdir;
char noconfirm = 0,
ignoreerr = 0,
state, seloption;
@ -47,8 +47,8 @@ void delete_draw_confirm() {
nccreate(6, 60, "Confirm delete");
ncprint(1, 2, "Are you sure you want to delete \"%s\"%c",
cropstr(root->name, 21), root->flags & FF_DIR ? ' ' : '?');
if(root->flags & FF_DIR)
cropstr(DR(root)->name, 21), DR(root)->flags & FF_DIR ? ' ' : '?');
if(DR(root)->flags & FF_DIR)
ncprint(2, 18, "and all of its contents?");
if(seloption == 0)
@ -165,8 +165,8 @@ int delete_key(int ch) {
}
int delete_dir(struct dir *dr) {
struct dir *nxt, *cur;
int delete_dir(compll_t dr) {
compll_t nxt, cur;
int r;
/* check for input or screen resizes */
@ -175,23 +175,23 @@ int delete_dir(struct dir *dr) {
return 1;
/* do the actual deleting */
if(dr->flags & FF_DIR) {
if((r = chdir(dr->name)) < 0)
if(DR(dr)->flags & FF_DIR) {
if((r = chdir(DR(dr)->name)) < 0)
goto delete_nxt;
if(dr->sub != NULL) {
nxt = dr->sub;
while(nxt != NULL) {
if(DR(dr)->sub) {
nxt = DR(dr)->sub;
while(nxt) {
cur = nxt;
nxt = cur->next;
nxt = DR(cur)->next;
if(delete_dir(cur))
return 1;
}
}
if((r = chdir("..")) < 0)
goto delete_nxt;
r = dr->sub == NULL ? rmdir(dr->name) : 0;
r = DR(dr)->sub ? 0 : rmdir(DR(dr)->name);
} else
r = unlink(dr->name);
r = unlink(DR(dr)->name);
delete_nxt:
/* error occured, ask user what to do */
@ -202,7 +202,7 @@ delete_nxt:
while(state == DS_FAILED)
if(input_handle(0))
return 1;
} else if(!(dr->flags & FF_DIR && dr->sub != NULL)) {
} else if(!(DR(dr)->flags & FF_DIR && DR(dr)->sub)) {
freedir(dr);
return 0;
}
@ -220,7 +220,7 @@ void delete_process() {
}
/* chdir */
if(path_chdir(getpath(root->parent)) < 0) {
if(path_chdir(getpath(DR(root)->parent)) < 0) {
state = DS_FAILED;
lasterrno = errno;
while(state == DS_FAILED)
@ -234,14 +234,14 @@ void delete_process() {
if(delete_dir(root))
browse_init(root);
else {
nextsel->flags |= FF_BSEL;
DW(nextsel)->flags |= FF_BSEL;
browse_init(nextsel);
dirlist_top(-4);
}
}
void delete_init(struct dir *dr, struct dir *s) {
void delete_init(compll_t dr, compll_t s) {
state = DS_CONFIRM;
root = curdir = dr;
pstate = ST_DEL;

View file

@ -31,7 +31,7 @@
void delete_process(void);
int delete_key(int);
void delete_draw(void);
void delete_init(struct dir *, struct dir *);
void delete_init(compll_t, compll_t);
#endif

View file

@ -25,39 +25,40 @@
#include "global.h"
#include <stdlib.h>
#include <string.h>
/* public variables */
struct dir *dirlist_parent = NULL;
off_t dirlist_maxs = 0,
dirlist_maxa = 0;
compll_t dirlist_parent = (compll_t)0;
off_t dirlist_maxs = 0,
dirlist_maxa = 0;
int dirlist_sort_desc = 1,
dirlist_sort_col = DL_COL_SIZE,
dirlist_sort_df = 0,
dirlist_hidden = 0;
int dirlist_sort_desc = 1,
dirlist_sort_col = DL_COL_SIZE,
dirlist_sort_df = 0,
dirlist_hidden = 0;
/* private state vars */
struct dir dirlist_parent_alloc;
struct dir *head, *head_real, *selected, *top = NULL;
compll_t dirlist_parent_alloc = (compll_t)0;
compll_t head, head_real, selected, top = (compll_t)0;
#define ISHIDDEN(d) (dirlist_hidden && (d) != dirlist_parent && (\
(d)->flags & FF_EXL || (d)->name[0] == '.' || (d)->name[strlen((d)->name)-1] == '~'\
#define ISHIDDEN(d) (dirlist_hidden && d != dirlist_parent && (\
DR(d)->flags & FF_EXL || DR(d)->name[0] == '.' || DR(d)->name[strlen(DR(d)->name)-1] == '~'\
))
int dirlist_cmp(struct dir *x, struct dir *y) {
int dirlist_cmp(compll_t x, compll_t y) {
int r;
/* dirs are always before files when that option is set */
if(dirlist_sort_df) {
if(y->flags & FF_DIR && !(x->flags & FF_DIR))
if(DR(y)->flags & FF_DIR && !(DR(x)->flags & FF_DIR))
return 1;
else if(!(y->flags & FF_DIR) && x->flags & FF_DIR)
else if(!(DR(y)->flags & FF_DIR) && DR(x)->flags & FF_DIR)
return -1;
}
@ -69,9 +70,9 @@ int dirlist_cmp(struct dir *x, struct dir *y) {
*
* Note that the method used below is supposed to be fast, not readable :-)
*/
#define CMP_NAME strcmp(x->name, y->name)
#define CMP_SIZE (x->size > y->size ? 1 : (x->size == y->size ? 0 : -1))
#define CMP_ASIZE (x->asize > y->asize ? 1 : (x->asize == y->asize ? 0 : -1))
#define CMP_NAME strcmp(DR(x)->name, DR(y)->name)
#define CMP_SIZE (DR(x)->size > DR(y)->size ? 1 : (DR(x)->size == DR(y)->size ? 0 : -1))
#define CMP_ASIZE (DR(x)->asize > DR(y)->asize ? 1 : (DR(x)->asize == DR(y)->asize ? 0 : -1))
/* try 1 */
r = dirlist_sort_col == DL_COL_NAME ? CMP_NAME : dirlist_sort_col == DL_COL_SIZE ? CMP_SIZE : CMP_ASIZE;
@ -90,15 +91,15 @@ int dirlist_cmp(struct dir *x, struct dir *y) {
}
struct dir *dirlist_sort(struct dir *list) {
struct dir *p, *q, *e, *tail;
compll_t dirlist_sort(compll_t list) {
compll_t p, q, e, tail;
int insize, nmerges, psize, qsize, i;
insize = 1;
while(1) {
p = list;
list = NULL;
tail = NULL;
list = (compll_t)0;
tail = (compll_t)0;
nmerges = 0;
while(p) {
nmerges++;
@ -106,31 +107,31 @@ struct dir *dirlist_sort(struct dir *list) {
psize = 0;
for(i=0; i<insize; i++) {
psize++;
q = q->next;
q = DR(q)->next;
if(!q) break;
}
qsize = insize;
while(psize > 0 || (qsize > 0 && q)) {
if(psize == 0) {
e = q; q = q->next; qsize--;
e = q; q = DR(q)->next; qsize--;
} else if(qsize == 0 || !q) {
e = p; p = p->next; psize--;
e = p; p = DR(p)->next; psize--;
} else if(dirlist_cmp(p,q) <= 0) {
e = p; p = p->next; psize--;
e = p; p = DR(p)->next; psize--;
} else {
e = q; q = q->next; qsize--;
e = q; q = DR(q)->next; qsize--;
}
if(tail) tail->next = e;
if(tail) DW(tail)->next = e;
else list = e;
e->prev = tail;
DW(e)->prev = tail;
tail = e;
}
p = q;
}
tail->next = NULL;
DW(tail)->next = (compll_t)0;
if(nmerges <= 1) {
if(list->parent)
list->parent->sub = list;
if(DR(list)->parent)
DW(DR(list)->parent)->sub = list;
return list;
}
insize *= 2;
@ -143,109 +144,115 @@ struct dir *dirlist_sort(struct dir *list) {
* - updates the dirlist_(maxs|maxa) values
* - makes sure that the FF_BSEL bits are correct */
void dirlist_fixup() {
struct dir *t;
compll_t t;
/* we're going to determine the selected items from the list itself, so reset this one */
selected = NULL;
selected = (compll_t)0;
for(t=head; t; t=t->next) {
for(t=head; t; t=DR(t)->next) {
/* not visible? not selected! */
if(ISHIDDEN(t))
t->flags &= ~FF_BSEL;
else {
if(ISHIDDEN(t)) {
if(DR(t)->flags & FF_BSEL)
DW(t)->flags &= ~FF_BSEL;
} else {
/* visible and selected? make sure only one item is selected */
if(t->flags & FF_BSEL) {
if(DR(t)->flags & FF_BSEL) {
if(!selected)
selected = t;
else
t->flags &= ~FF_BSEL;
DW(t)->flags &= ~FF_BSEL;
}
}
/* update dirlist_(maxs|maxa) */
if(t->size > dirlist_maxs)
dirlist_maxs = t->size;
if(t->asize > dirlist_maxa)
dirlist_maxa = t->asize;
if(DR(t)->size > dirlist_maxs)
dirlist_maxs = DR(t)->size;
if(DR(t)->asize > dirlist_maxa)
dirlist_maxa = DR(t)->asize;
}
/* no selected items found after one pass? select the first visible item */
if(!selected)
if((selected = dirlist_next(NULL)))
selected->flags |= FF_BSEL;
if((selected = dirlist_next((compll_t)0)))
DW(selected)->flags |= FF_BSEL;
}
void dirlist_open(struct dir *d) {
void dirlist_open(compll_t d) {
/* set the head of the list */
head_real = head = d == NULL ? NULL : d->parent == NULL ? d->sub : d->parent->sub;
head_real = head = !d ? d : !DR(d)->parent ? DR(d)->sub : DR(DR(d)->parent)->sub;
/* reset internal status */
dirlist_maxs = dirlist_maxa = 0;
/* stop if this is not a directory list we can work with */
if(head == NULL) {
dirlist_parent = NULL;
if(!head) {
dirlist_parent = (compll_t)0;
return;
}
/* sort the dir listing */
head_real = head = dirlist_sort(head);
/* allocate reference to parent dir if we don't have one yet */
if(!dirlist_parent_alloc) {
dirlist_parent_alloc = compll_alloc(SDIRSIZE+2);
strcpy(DW(dirlist_parent_alloc)->name, "..");
}
/* set the reference to the parent dir */
dirlist_parent_alloc.flags &= ~FF_BSEL;
if(head->parent->parent) {
dirlist_parent = &dirlist_parent_alloc;
strcpy(dirlist_parent->name, "..");
dirlist_parent->next = head;
dirlist_parent->parent = head->parent;
dirlist_parent->sub = head->parent;
DW(dirlist_parent_alloc)->flags &= ~FF_BSEL;
if(DR(DR(head)->parent)->parent) {
dirlist_parent = dirlist_parent_alloc;
DW(dirlist_parent)->next = head;
DW(dirlist_parent)->parent = DR(head)->parent;
DW(dirlist_parent)->sub = DR(head)->parent;
head = dirlist_parent;
} else
dirlist_parent = NULL;
dirlist_parent = (compll_t)0;
dirlist_fixup();
}
struct dir *dirlist_next(struct dir *d) {
compll_t dirlist_next(compll_t d) {
if(!head)
return NULL;
return (compll_t)0;
if(!d) {
if(!ISHIDDEN(head))
return head;
else
d = head;
}
while((d = d->next)) {
while((d = DR(d)->next)) {
if(!ISHIDDEN(d))
return d;
}
return NULL;
return (compll_t)0;
}
struct dir *dirlist_prev(struct dir *d) {
compll_t dirlist_prev(compll_t d) {
if(!head || !d)
return NULL;
while((d = d->prev)) {
return (compll_t)0;
while((d = DR(d)->prev)) {
if(!ISHIDDEN(d))
return d;
}
if(dirlist_parent)
return dirlist_parent;
return NULL;
return (compll_t)0;
}
struct dir *dirlist_get(int i) {
struct dir *t = selected, *d;
compll_t dirlist_get(int i) {
compll_t t = selected, d;
if(!head)
return NULL;
return (compll_t)0;
if(ISHIDDEN(selected)) {
selected = dirlist_next(NULL);
selected = dirlist_next((compll_t)0);
return selected;
}
@ -275,13 +282,13 @@ struct dir *dirlist_get(int i) {
}
void dirlist_select(struct dir *d) {
if(!d || !head || ISHIDDEN(d) || d->parent != head->parent)
void dirlist_select(compll_t d) {
if(!d || !head || ISHIDDEN(d) || DR(d)->parent != DR(head)->parent)
return;
selected->flags &= ~FF_BSEL;
DW(selected)->flags &= ~FF_BSEL;
selected = d;
selected->flags |= FF_BSEL;
DW(selected)->flags |= FF_BSEL;
}
@ -304,12 +311,12 @@ void dirlist_select(struct dir *d) {
* Regardless of the hint, the returned top will always be chosen such that the
* selected item is visible.
*/
struct dir *dirlist_top(int hint) {
struct dir *t;
compll_t dirlist_top(int hint) {
compll_t t;
int i = winrows-3, visible = 0;
if(hint == -2 || hint == -3)
top = NULL;
top = (compll_t)0;
/* check whether the current selected item is within the visible window */
if(top) {
@ -358,7 +365,7 @@ void dirlist_set_sort(int col, int desc, int df) {
/* sort the list (excluding the parent, which is always on top) */
head_real = dirlist_sort(head_real);
if(dirlist_parent)
dirlist_parent->next = head_real;
DW(dirlist_parent)->next = head_real;
else
head = head_real;
dirlist_top(-3);

View file

@ -38,22 +38,22 @@
#define DL_COL_ASIZE 2
void dirlist_open(struct dir *);
void dirlist_open(compll_t);
/* Get the next non-hidden item,
* NULL = get first non-hidden item */
struct dir *dirlist_next(struct dir *);
compll_t dirlist_next(compll_t);
/* Get the struct dir item relative to the selected item, or the item nearest to the requested item
* i = 0 get selected item
* hidden items aren't considered */
struct dir *dirlist_get(int i);
compll_t dirlist_get(int i);
/* Get/set the first visible item in the list on the screen */
struct dir *dirlist_top(int hint);
compll_t dirlist_top(int hint);
/* Set selected dir (must be in the currently opened directory, obviously) */
void dirlist_select(struct dir *);
void dirlist_select(compll_t);
/* Change sort column (arguments should have a NO_CHANGE option) */
void dirlist_set_sort(int column, int desc, int df);
@ -65,7 +65,7 @@ void dirlist_set_hidden(int hidden);
/* DO NOT WRITE TO ANY OF THE BELOW VARIABLES FROM OUTSIDE OF dirlist.c! */
/* The 'reference to parent dir' */
extern struct dir *dirlist_parent;
extern compll_t dirlist_parent;
/* current sorting configuration (set with dirlist_set_sort()) */
extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df;

View file

@ -30,6 +30,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "compll.h"
/* File Flags (struct dir -> flags) */
#define FF_DIR 0x01
@ -48,17 +49,15 @@
#define ST_HELP 3
/* structure representing a file or directory
* XXX: probably a good idea to get rid of the custom _t types and use
* fixed-size integers instead, which are much more predictable */
/* structure representing a file or directory */
struct dir {
struct dir *parent, *next, *prev, *sub, *hlnk;
compll_t parent, next, prev, sub, hlnk;
off_t size, asize;
ino_t ino;
unsigned long items;
dev_t dev;
unsigned char flags;
char name[3]; /* must be large enough to hold ".." */
char name[3];
};
/* sizeof(total dir) = SDIRSIZE + strlen(name) = sizeof(struct dir) - 3 + strlen(name) + 1 */
#define SDIRSIZE (sizeof(struct dir)-2)

View file

@ -33,6 +33,11 @@
#include <sys/time.h>
#include <locale.h>
#ifndef COMPLL_NOLIB
#include <zlib.h>
#endif
int pstate;
int min_rows = 17,
@ -143,6 +148,23 @@ char *argv_parse(int argc, char **argv) {
}
/* compression and decompression functions for compll */
#ifndef COMPLL_NOLIB
unsigned int block_compress(const unsigned char *src, unsigned int srclen, unsigned char *dst, unsigned int dstlen) {
uLongf len = dstlen;
compress2(dst, &len, src, srclen, 6);
return len;
}
void block_decompress(const unsigned char *src, unsigned int srclen, unsigned char *dst, unsigned int dstlen) {
uLongf len = dstlen;
uncompress(dst, &len, src, srclen);
}
#endif
/* main program */
int main(int argc, char **argv) {
char *dir;
@ -152,7 +174,12 @@ int main(int argc, char **argv) {
if((dir = argv_parse(argc, argv)) == NULL)
dir = ".";
calc_init(dir, NULL);
#ifndef COMPLL_NOLIB
/* we probably want to make these options configurable */
compll_init(32*1024, sizeof(off_t), 50, block_compress, block_decompress);
#endif
calc_init(dir, (compll_t)0);
initscr();
cbreak();

View file

@ -38,9 +38,6 @@ char fullsizedat[20]; /* max: 999.999.999.999.999 */
char *getpathdat;
int getpathdatl = 0;
struct dir **links;
int linksl = 0, linkst = 0;
char *cropstr(const char *from, int s) {
int i, j, o = strlen(from);
@ -170,11 +167,11 @@ void ncprint(int r, int c, char *fmt, ...) {
/* removes item from the hlnk circular linked list and size counts of the parents */
void freedir_hlnk(struct dir *d) {
struct dir *t, *par, *pt;
void freedir_hlnk(compll_t d) {
compll_t t, par, pt;
int i;
if(!(d->flags & FF_HLNKC))
if(!(DR(d)->flags & FF_HLNKC))
return;
/* remove size from parents.
@ -183,81 +180,80 @@ void freedir_hlnk(struct dir *d) {
* exists within the parent it shouldn't get removed from the count.
* XXX: Same note as for calc.c / calc_hlnk_check():
* this is probably not the most efficient algorithm */
for(i=1,par=d->parent; i&&par; par=par->parent) {
if(d->hlnk)
for(t=d->hlnk; i&&t!=d; t=t->hlnk)
for(pt=t->parent; i&&pt; pt=pt->parent)
for(i=1,par=DR(d)->parent; i&&par; par=DR(par)->parent) {
if(DR(d)->hlnk)
for(t=DR(d)->hlnk; i&&t!=d; t=DR(t)->hlnk)
for(pt=DR(t)->parent; i&&pt; pt=DR(pt)->parent)
if(pt==par)
i=0;
if(i) {
par->size -= d->size;
par->asize -= d->asize;
DW(par)->size -= DR(d)->size;
DW(par)->asize -= DR(d)->asize;
}
}
/* remove from hlnk */
if(d->hlnk) {
for(t=d->hlnk; t->hlnk!=d; t=t->hlnk)
if(DR(d)->hlnk) {
for(t=DR(d)->hlnk; DR(t)->hlnk!=d; t=DR(t)->hlnk)
;
t->hlnk = d->hlnk;
DW(t)->hlnk = DR(d)->hlnk;
}
}
void freedir_rec(struct dir *dr) {
struct dir *tmp, *tmp2;
void freedir_rec(compll_t dr) {
compll_t tmp, tmp2;
tmp2 = dr;
while((tmp = tmp2) != NULL) {
while((tmp = tmp2)) {
freedir_hlnk(tmp);
/* remove item */
if(tmp->sub) freedir_rec(tmp->sub);
tmp2 = tmp->next;
free(tmp);
if(DR(tmp)->sub) freedir_rec(DR(tmp)->sub);
tmp2 = DR(tmp)->next;
compll_free(tmp);
}
}
void freedir(struct dir *dr) {
struct dir *tmp;
void freedir(compll_t dr) {
compll_t tmp;
/* free dr->sub recursively */
if(dr->sub)
freedir_rec(dr->sub);
if(DR(dr)->sub)
freedir_rec(DR(dr)->sub);
/* update references */
if(dr->parent && dr->parent->sub == dr)
dr->parent->sub = dr->next;
if(dr->prev)
dr->prev->next = dr->next;
if(dr->next)
dr->next->prev = dr->prev;
if(DR(dr)->parent && DR(DR(dr)->parent)->sub == dr)
DW(DR(dr)->parent)->sub = DR(dr)->next;
if(DR(dr)->prev)
DW(DR(dr)->prev)->next = DR(dr)->next;
if(DR(dr)->next)
DW(DR(dr)->next)->prev = DR(dr)->prev;
freedir_hlnk(dr);
/* update sizes of parent directories if this isn't a hard link.
* If this is a hard link, freedir_hlnk() would have done so already */
for(tmp=dr->parent; tmp; tmp=tmp->parent) {
if(!(dr->flags & FF_HLNKC)) {
tmp->size -= dr->size;
tmp->asize -= dr->asize;
for(tmp=DR(dr)->parent; tmp; tmp=DR(tmp)->parent) {
if(!(DR(dr)->flags & FF_HLNKC)) {
DW(tmp)->size -= DR(dr)->size;
DW(tmp)->asize -= DR(dr)->asize;
}
tmp->items -= dr->items+1;
DW(tmp)->items -= DR(dr)->items+1;
}
free(dr);
compll_free(dr);
}
char *getpath(struct dir *cur) {
struct dir *d, **list;
char *getpath(compll_t cur) {
compll_t d, *list;
int c, i;
if(!cur->name[0])
if(!DR(cur)->name[0])
return "/";
c = i = 1;
for(d=cur; d!=NULL; d=d->parent) {
i += strlen(d->name)+1;
for(d=cur; d; d=DR(d)->parent) {
i += strlen(DR(d)->name)+1;
c++;
}
@ -268,17 +264,17 @@ char *getpath(struct dir *cur) {
getpathdatl = i;
getpathdat = realloc(getpathdat, i);
}
list = malloc(c*sizeof(struct dir *));
list = malloc(c*sizeof(compll_t));
c = 0;
for(d=cur; d!=NULL; d=d->parent)
for(d=cur; d; d=DR(d)->parent)
list[c++] = d;
getpathdat[0] = '\0';
while(c--) {
if(list[c]->parent)
if(DR(list[c])->parent)
strcat(getpathdat, "/");
strcat(getpathdat, list[c]->name);
strcat(getpathdat, DR(list[c])->name);
}
free(list);
return getpathdat;

View file

@ -35,6 +35,9 @@ extern int winrows, wincols;
/* used by the nc* functions and macros */
extern int subwinr, subwinc;
/* handy macros for accessing nodes */
#define DR(n) ((const struct dir *) compll_read(n))
#define DW(n) ((struct dir *) compll_write(n))
/* Instead of using several ncurses windows, we only draw to stdscr.
* the functions nccreate, ncprint and the macros ncaddstr and ncaddch
@ -72,11 +75,11 @@ char *formatsize(const off_t);
char *fullsize(const off_t);
/* recursively free()s a directory tree */
void freedir(struct dir *);
void freedir(compll_t);
/* generates full path from a dir item,
returned pointer will be overwritten with a subsequent call */
char *getpath(struct dir *);
char *getpath(compll_t);
#endif