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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -38,22 +38,22 @@
#define DL_COL_ASIZE 2 #define DL_COL_ASIZE 2
void dirlist_open(struct dir *); void dirlist_open(compll_t);
/* Get the next non-hidden item, /* Get the next non-hidden item,
* NULL = get first 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 /* Get the struct dir item relative to the selected item, or the item nearest to the requested item
* i = 0 get selected item * i = 0 get selected item
* hidden items aren't considered */ * 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 */ /* 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) */ /* 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) */ /* Change sort column (arguments should have a NO_CHANGE option) */
void dirlist_set_sort(int column, int desc, int df); 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! */ /* DO NOT WRITE TO ANY OF THE BELOW VARIABLES FROM OUTSIDE OF dirlist.c! */
/* The 'reference to parent dir' */ /* The 'reference to parent dir' */
extern struct dir *dirlist_parent; extern compll_t dirlist_parent;
/* current sorting configuration (set with dirlist_set_sort()) */ /* current sorting configuration (set with dirlist_set_sort()) */
extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df; extern int dirlist_sort_desc, dirlist_sort_col, dirlist_sort_df;

View file

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "compll.h"
/* File Flags (struct dir -> flags) */ /* File Flags (struct dir -> flags) */
#define FF_DIR 0x01 #define FF_DIR 0x01
@ -48,17 +49,15 @@
#define ST_HELP 3 #define ST_HELP 3
/* structure representing a file or directory /* 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 */
struct dir { struct dir {
struct dir *parent, *next, *prev, *sub, *hlnk; compll_t parent, next, prev, sub, hlnk;
off_t size, asize; off_t size, asize;
ino_t ino; ino_t ino;
unsigned long items; unsigned long items;
dev_t dev; dev_t dev;
unsigned char flags; 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 */ /* sizeof(total dir) = SDIRSIZE + strlen(name) = sizeof(struct dir) - 3 + strlen(name) + 1 */
#define SDIRSIZE (sizeof(struct dir)-2) #define SDIRSIZE (sizeof(struct dir)-2)

View file

@ -33,6 +33,11 @@
#include <sys/time.h> #include <sys/time.h>
#include <locale.h> #include <locale.h>
#ifndef COMPLL_NOLIB
#include <zlib.h>
#endif
int pstate; int pstate;
int min_rows = 17, 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 */ /* main program */
int main(int argc, char **argv) { int main(int argc, char **argv) {
char *dir; char *dir;
@ -152,7 +174,12 @@ int main(int argc, char **argv) {
if((dir = argv_parse(argc, argv)) == NULL) if((dir = argv_parse(argc, argv)) == NULL)
dir = "."; 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(); initscr();
cbreak(); cbreak();

View file

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

View file

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