1
1

Removed reliance on PATH_MAX on most places

ncdu already does seem to handle longer paths now, though there are
still a few places where the code still relies on PATH_MAX. Will fix
those later.
Этот коммит содержится в:
Yorhel 2009-04-23 21:15:11 +02:00
родитель bb7119c642
Коммит 4bb7d6b7c2
5 изменённых файлов: 113 добавлений и 68 удалений

Просмотреть файл

@ -134,8 +134,6 @@ struct dir *browse_sort(struct dir *list) {
void browse_draw_info(struct dir *dr) { void browse_draw_info(struct dir *dr) {
char path[PATH_MAX];
nccreate(11, 60, "Item info"); nccreate(11, 60, "Item info");
attron(A_BOLD); attron(A_BOLD);
@ -147,7 +145,7 @@ void browse_draw_info(struct dir *dr) {
attroff(A_BOLD); attroff(A_BOLD);
ncaddstr(2, 9, cropstr(dr->name, 49)); ncaddstr(2, 9, cropstr(dr->name, 49));
ncaddstr(3, 9, cropstr(getpath(dr, path), 49)); ncaddstr(3, 9, cropstr(getpath(dr), 49));
ncaddstr(4, 9, dr->flags & FF_DIR ? "Directory" ncaddstr(4, 9, dr->flags & FF_DIR ? "Directory"
: dr->flags & FF_FILE ? "File" : "Other (link, device, socket, ..)"); : 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(dr->size), fullsize(dr->size));
@ -226,7 +224,7 @@ void browse_draw_item(struct dir *n, int row, off_t max, int ispar) {
int browse_draw() { int browse_draw() {
struct dir *n, ref, *cur, *sel = NULL; struct dir *n, ref, *cur, *sel = NULL;
char tmp[PATH_MAX]; char tmp[PATH_MAX], *tmp2;
int selected, i; int selected, i;
off_t max = 1; off_t max = 1;
@ -250,9 +248,9 @@ int browse_draw() {
mvhline(1, 0, '-', wincols); mvhline(1, 0, '-', wincols);
if(cur) { if(cur) {
mvaddch(1, 3, ' '); mvaddch(1, 3, ' ');
getpath(cur, tmp); tmp2 = getpath(cur);
mvaddstr(1, 4, cropstr(tmp, wincols-8)); mvaddstr(1, 4, cropstr(tmp2, wincols-8));
mvaddch(1, 4+((int)strlen(tmp) > wincols-8 ? wincols-8 : (int)strlen(tmp)), ' '); mvaddch(1, 4+((int)strlen(tmp2) > wincols-8 ? wincols-8 : (int)strlen(tmp2)), ' ');
} }
if(!cur) if(!cur)
@ -339,7 +337,6 @@ void browse_key_sel(int change) {
#define toggle(x,y) if(x & y) x -=y; else x |= y #define toggle(x,y) if(x & y) x -=y; else x |= y
int browse_key(int ch) { int browse_key(int ch) {
char tmp[PATH_MAX];
char sort = 0, nonfo = 0; char sort = 0, nonfo = 0;
struct dir *n, *r; struct dir *n, *r;
@ -419,7 +416,7 @@ int browse_key(int ch) {
/* refresh */ /* refresh */
case 'r': case 'r':
calc_init(getpath(browse_dir, tmp), browse_dir->parent); calc_init(getpath(browse_dir), browse_dir->parent);
nonfo++; nonfo++;
sort++; sort++;
break; break;

Просмотреть файл

@ -53,28 +53,25 @@ char calc_smfs = 0;
/* global vars for internal use */ /* global vars for internal use */
char failed; /* 1 on fatal error */ char failed; /* 1 on fatal error */
char curpath[PATH_MAX]; /* last lstat()'ed item */ char *curpath; /* last lstat()'ed item */
char lasterr[PATH_MAX]; /* last unreadable dir/item */ char *lasterr; /* last unreadable dir/item */
char errmsg[128]; /* error message, when err=1 */ char errmsg[128]; /* error message, when failed=1 */
struct dir *root; /* root directory struct we're calculating */ struct dir *root; /* root directory struct we're calculating */
struct dir *orig; /* original directory, when recalculating */ struct dir *orig; /* original directory, when recalculating */
dev_t curdev; /* current device we're calculating on */ dev_t curdev; /* current device we're calculating on */
long lastupdate; /* time of the last screen update */ long lastupdate; /* time of the last screen update */
int anpos; /* position of the animation string */ int anpos; /* position of the animation string */
int curpathl = 0, lasterrl = 0;
int calc_item(struct dir *par, char *path, char *name) { int calc_item(struct dir *par, char *name) {
char tmp[PATH_MAX];
struct dir *t, *d; struct dir *t, *d;
struct stat fs; struct stat fs;
char *tmp;
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;
/* path too long - ignore file */
if(strlen(path)+strlen(name)+1 > PATH_MAX)
return 1;
/* allocate dir and fix references */ /* allocate dir and fix references */
d = calloc(sizeof(struct dir), 1); d = calloc(sizeof(struct dir), 1);
d->parent = par; d->parent = par;
@ -96,17 +93,22 @@ int calc_item(struct dir *par, char *path, char *name) {
} }
#endif #endif
/* lstat */ /* update curpath */
strcpy(tmp, path); tmp = getpath(d);
strcat(tmp, name); if((int)strlen(tmp)+1 > curpathl) {
curpathl = strlen(tmp)+1;
curpath = realloc(curpath, curpathl);
}
strcpy(curpath, tmp); strcpy(curpath, tmp);
if(lstat(tmp, &fs)) {
/* lstat */
if(lstat(d->name, &fs)) {
d->flags |= FF_ERR; d->flags |= FF_ERR;
return 0; return 0;
} }
/* check for excludes and same filesystem */ /* check for excludes and same filesystem */
if(exclude_match(tmp)) if(exclude_match(curpath))
d->flags |= FF_EXL; d->flags |= FF_EXL;
if(calc_smfs && curdev != fs.st_dev) if(calc_smfs && curdev != fs.st_dev)
@ -136,20 +138,26 @@ int calc_item(struct dir *par, char *path, char *name) {
} }
/* recursively walk through the directory tree */ /* recursively walk through the directory tree,
int calc_dir(struct dir *dest, char *path) { assumes path resides in the cwd */
int calc_dir(struct dir *dest) {
struct dir *t; struct dir *t;
DIR *dir; DIR *dir;
char *tmp;
struct dirent *dr; struct dirent *dr;
char tmp[PATH_MAX]; int ch;
int len;
if(input_handle(1)) if(input_handle(1))
return 1; return 1;
/* open directory */ /* open directory */
if((dir = opendir(path)) == NULL) { if((dir = opendir(dest->name)) == NULL) {
strcpy(lasterr, path); tmp = getpath(dest);
if(lasterrl < (int)strlen(tmp)+1) {
lasterrl = strlen(tmp)+1;
lasterr = realloc(lasterr, lasterrl);
}
strcpy(lasterr, tmp);
dest->flags |= FF_ERR; dest->flags |= FF_ERR;
t = dest; t = dest;
while((t = t->parent) != NULL) while((t = t->parent) != NULL)
@ -157,16 +165,15 @@ int calc_dir(struct dir *dest, char *path) {
return 0; return 0;
} }
/* add leading slash */ /* chdir */
len = strlen(path); if(chdir(dest->name) < 0) {
if(path[len-1] != '/') { dest->flags |= FF_ERR;
path[len] = '/'; return 0;
path[++len] = '\0';
} }
/* read directory */ /* read directory */
while((dr = readdir(dir)) != NULL) { while((dr = readdir(dir)) != NULL) {
if(calc_item(dest, path, dr->d_name)) if(calc_item(dest, dr->d_name))
dest->flags |= FF_ERR; dest->flags |= FF_ERR;
if(input_handle(1)) if(input_handle(1))
return 1; return 1;
@ -190,13 +197,18 @@ int calc_dir(struct dir *dest, char *path) {
} }
/* calculate subdirectories */ /* calculate subdirectories */
ch = 0;
for(t=dest->sub; t!=NULL; t=t->next) for(t=dest->sub; t!=NULL; t=t->next)
if(t->flags & FF_DIR && !(t->flags & FF_EXL || t->flags & FF_OTHFS)) { if(t->flags & FF_DIR && !(t->flags & FF_EXL || t->flags & FF_OTHFS))
strcpy(tmp, path); if(calc_dir(t))
strcat(tmp, t->name);
if(calc_dir(t, tmp))
return 1; return 1;
}
/* chdir back */
if(chdir("..") < 0) {
failed = 1;
strcpy(errmsg, "Couldn't chdir to previous directory");
return 1;
}
return 0; return 0;
} }
@ -295,6 +307,11 @@ void calc_process() {
strcpy(errmsg, "Directory not found"); strcpy(errmsg, "Directory not found");
goto fail; goto fail;
} }
if(path_chdir(tmp) < 0 || chdir("..") < 0) {
failed = 1;
strcpy(errmsg, "Couldn't chdir into directory");
goto fail;
}
/* initialize parent dir */ /* initialize parent dir */
t = (struct dir *) calloc(1, sizeof(struct dir)); t = (struct dir *) calloc(1, sizeof(struct dir));
@ -306,7 +323,7 @@ void calc_process() {
curdev = fs.st_dev; curdev = fs.st_dev;
/* start calculating */ /* start calculating */
if(!calc_dir(root, tmp) && !failed) { if(!calc_dir(root) && !failed) {
browse_init(root->sub); browse_init(root->sub);
/* update references and free original item */ /* update references and free original item */
@ -344,10 +361,22 @@ fail:
void calc_init(char *dir, struct dir *org) { void calc_init(char *dir, struct dir *org) {
failed = anpos = lasterr[0] = 0; failed = anpos = 0;
lastupdate = 999; lastupdate = 999;
orig = org; orig = org;
if(curpathl == 0) {
curpathl = strlen(dir);
curpath = malloc(curpathl);
} else if(curpathl < (int)strlen(dir)+1) {
curpathl = strlen(dir)+1;
curpath = realloc(curpath, curpathl);
}
strcpy(curpath, dir); strcpy(curpath, dir);
if(lasterrl == 0) {
lasterrl = 1;
lasterr = malloc(lasterrl);
}
lasterr[0] = 0;
pstate = ST_CALC; pstate = ST_CALC;
} }

Просмотреть файл

@ -27,6 +27,7 @@
#include "ncdu.h" #include "ncdu.h"
#include "util.h" #include "util.h"
#include "browser.h" #include "browser.h"
#include "path.h"
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
@ -42,10 +43,10 @@
int delete_delay = 100; int delete_delay = 100;
long lastupdate; long lastupdate;
struct dir *root, *nextsel; struct dir *root, *nextsel, *curdir;
char noconfirm = 0, char noconfirm = 0,
ignoreerr = 0, ignoreerr = 0,
state, seloption, curfile[PATH_MAX]; state, seloption;
int lasterrno; int lasterrno;
@ -77,7 +78,7 @@ void delete_draw_confirm() {
void delete_draw_progress() { void delete_draw_progress() {
nccreate(6, 60, "Deleting..."); nccreate(6, 60, "Deleting...");
ncaddstr(1, 2, cropstr(curfile, 47)); ncaddstr(1, 2, cropstr(getpath(curdir), 47));
ncaddstr(4, 41, "Press q to abort"); ncaddstr(4, 41, "Press q to abort");
} }
@ -85,7 +86,7 @@ void delete_draw_progress() {
void delete_draw_error() { void delete_draw_error() {
nccreate(6, 60, "Error!"); nccreate(6, 60, "Error!");
ncprint(1, 2, "Can't delete %s:", cropstr(curfile, 42)); ncprint(1, 2, "Can't delete %s:", cropstr(getpath(curdir), 42));
ncaddstr(2, 4, strerror(lasterrno)); ncaddstr(2, 4, strerror(lasterrno));
if(seloption == 0) if(seloption == 0)
@ -187,15 +188,14 @@ int delete_key(int ch) {
int delete_dir(struct dir *dr) { int delete_dir(struct dir *dr) {
struct dir *nxt, *cur; struct dir *nxt, *cur;
int r; int r;
char file[PATH_MAX]; char *path;
getpath(dr, file); /* calling path_chdir() this often isn't exactly efficient... */
if(file[strlen(file)-1] != '/') path = getpath(dr->sub);
strcat(file, "/"); path_chdir(path);
strcat(file, dr->name);
/* check for input or screen resizes */ /* check for input or screen resizes */
strcpy(curfile, file); curdir = dr;
if(input_handle(1)) if(input_handle(1))
return 1; return 1;
@ -210,9 +210,9 @@ int delete_dir(struct dir *dr) {
return 1; return 1;
} }
} }
r = rmdir(file); r = rmdir(dr->name);
} else } else
r = unlink(file); r = unlink(dr->name);
/* error occured, ask user what to do */ /* error occured, ask user what to do */
if(r == -1 && !ignoreerr) { if(r == -1 && !ignoreerr) {

Просмотреть файл

@ -35,6 +35,8 @@ int subwinr, subwinc;
char cropstrdat[4096]; char cropstrdat[4096];
char formatsizedat[8]; char formatsizedat[8];
char fullsizedat[20]; /* max: 999.999.999.999.999 */ char fullsizedat[20]; /* max: 999.999.999.999.999 */
char *getpathdat;
int getpathdatl = 0;
char *cropstr(const char *from, int s) { char *cropstr(const char *from, int s) {
@ -208,20 +210,36 @@ void freedir(struct dir *dr) {
} }
char *getpath(struct dir *cur, char *to) { char *getpath(struct dir *cur) {
struct dir *d, *list[100]; struct dir *d, **list;
int c = 0; int c, i;
for(d = cur; (d = d->parent) != NULL; ) c = i = 1;
list[c++] = d; for(d=cur; d!=NULL; d=d->parent) {
i += strlen(d->name)+1;
to[0] = '\0'; c++;
while(c--) {
if(list[c]->parent && list[c]->parent->name[strlen(list[c]->parent->name)-1] != '/')
strcat(to, "/");
strcat(to, list[c]->name);
} }
return to; if(getpathdatl == 0) {
getpathdatl = i;
getpathdat = malloc(i);
} else if(getpathdatl < i) {
getpathdatl = i;
getpathdat = realloc(getpathdat, i);
}
list = malloc(c*sizeof(struct dir *));
c = 0;
for(d=cur; d!=NULL; d=d->parent)
list[c++] = d;
getpathdat[0] = '\0';
while(c--) {
if(list[c]->parent)
strcat(getpathdat, "/");
strcat(getpathdat, list[c]->name);
}
free(list);
return getpathdat;
} }

Просмотреть файл

@ -74,8 +74,9 @@ char *fullsize(const off_t);
/* recursively free()s a directory tree */ /* recursively free()s a directory tree */
void freedir(struct dir *); void freedir(struct dir *);
/* generates full path from a dir item */ /* generates full path from a dir item,
char *getpath(struct dir *, char *); returned pointer will be overwritten with a subsequent call */
char *getpath(struct dir *);
#endif #endif