fix(meowpanel): 文件列表排序——目录优先+名称不区分大小写(原 readdir 原始顺序混杂);条目上限 1024 防巨目录爆内存;设备实测生效
This commit is contained in:
1 parent
f7e45f472e
commit
c8ffdfbad9
2 files changed
+26
-8
No files matched your search
@@ -973,6 +973,16 @@ static void fmt_json_item(sbuf_t *s, const char *name, int isdir, long long size
|
||||
isdir ? "dir" : "file", size, mtime);
|
||||
}
|
||||
|
||||
struct fent { char name[256]; int isdir; long long size, mtime; };
|
||||
/* 目录优先 + 名称不区分大小写(再按大小写敏感定序保证稳定) */
|
||||
static int fent_cmp(const void *a, const void *b)
|
||||
{
|
||||
const struct fent *fa = a, *fb = b;
|
||||
if (fa->isdir != fb->isdir) return fb->isdir - fa->isdir;
|
||||
int c = strcasecmp(fa->name, fb->name);
|
||||
return c ? c : strcmp(fa->name, fb->name);
|
||||
}
|
||||
|
||||
static int files_list(int sock, const char *relpath)
|
||||
{
|
||||
char abs[1024], rel[1024];
|
||||
@@ -999,7 +1009,10 @@ static int files_list(int sock, const char *relpath)
|
||||
sA(&s, ",\"allowed\":[");
|
||||
for (int i = 0; i < ALLOWED_COUNT; i++) { if (i) sA(&s, ","); sA_str(&s, g_allowed_dirs[i]); }
|
||||
sA(&s, "],\"items\":[");
|
||||
int first = 1;
|
||||
/* M2.78:排序后输出(原 readdir 原始顺序混杂难用)——目录优先,同组按名称
|
||||
* 不区分大小写排序;条目上限 1024(与 files App 一致,防巨目录爆内存)。 */
|
||||
int cap = 1024, n = 0;
|
||||
struct fent *ents = malloc((size_t)cap * sizeof *ents);
|
||||
struct dirent *e;
|
||||
while ((e = readdir(d))) {
|
||||
if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue;
|
||||
@@ -1007,15 +1020,20 @@ static int files_list(int sock, const char *relpath)
|
||||
snprintf(full, sizeof full, "%s/%s", abs, e->d_name);
|
||||
struct stat fs;
|
||||
if (stat(full, &fs) < 0) continue;
|
||||
int isdir = S_ISDIR(fs.st_mode);
|
||||
long long size = (long long)fs.st_size;
|
||||
long long mtime = (long long)fs.st_mtime;
|
||||
if (isdir) size = 0;
|
||||
if (!first) sA(&s, ",");
|
||||
first = 0;
|
||||
fmt_json_item(&s, e->d_name, isdir, size, mtime);
|
||||
if (n >= cap) break;
|
||||
struct fent *en = &ents[n++];
|
||||
snprintf(en->name, sizeof en->name, "%s", e->d_name);
|
||||
en->isdir = S_ISDIR(fs.st_mode);
|
||||
en->size = en->isdir ? 0 : (long long)fs.st_size;
|
||||
en->mtime = (long long)fs.st_mtime;
|
||||
}
|
||||
closedir(d);
|
||||
qsort(ents, (size_t)n, sizeof *ents, fent_cmp);
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (i) sA(&s, ",");
|
||||
fmt_json_item(&s, ents[i].name, ents[i].isdir, ents[i].size, ents[i].mtime);
|
||||
}
|
||||
free(ents);
|
||||
sA(&s, "]}");
|
||||
return send_json(sock, 200, s.b ? s.b : "");
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user