📄 ls.c
字号:
p = head; while (p) { q = p; p = p->down; while (q) { char pad[6]; char *tmp = (char *) q; if (q->right) { memset(pad, '\t', sizeof pad - 1U); pad[(sizeof pad) - 1] = 0; pad[(colwidth + 7U - strlen(q->line)) / 8] = 0; } else { pad[0] = '\r'; pad[1] = '\n'; pad[2] = 0; } wrstr(f, q->line); wrstr(f, pad); q = q->right; free(tmp); } } /* reset variables for next time */ head = tail = NULL; colwidth = 0U; filenames = 0U;}/* functions to to sort for qsort() */static int cmp(const void * const a, const void * const b){ return strcmp(FI_NAME((const FileInfo *) a), FI_NAME((const FileInfo *) b));}static int cmp_r(const void * const a, const void * const b){ return strcmp(FI_NAME((const FileInfo *) b), FI_NAME((const FileInfo *) a));}static int cmp_t(const void * const a, const void * const b){ if (((const FileInfo *) a)->mtime < ((const FileInfo *) b)->mtime) { return 1; } if (((const FileInfo *) a)->mtime > ((const FileInfo *) b)->mtime) { return -1; } return 0;}static int cmp_rt(const void * const a, const void * const b){ return cmp_t(b, a);}static int cmp_S(const void * const a, const void * const b){ if (((const FileInfo *) a)->size < ((const FileInfo *) b)->size) { return 1; } if (((const FileInfo *) a)->size > ((const FileInfo *) b)->size) { return -1; } return 0;}static int cmp_rS(const void * const a, const void * const b){ return cmp_S(b, a);}static FileInfo *sreaddir(char **names_pnt){ struct stat st; DIR *d; struct dirent *de; FileInfo *files_info; FileInfo *file_info; size_t files_info_size; size_t files_info_counter = (size_t) 0U; char *names; size_t names_size; size_t names_counter = (size_t) 0U; size_t name_len; int (*cmp_func)(const void * const, const void * const); if ((d = opendir(".")) == NULL) { return NULL; } names_size = CHUNK_SIZE; if ((names = malloc(names_size)) == NULL) { closedir(d); return NULL; } files_info_size = CHUNK_SIZE / sizeof *files_info; if ((files_info = malloc(files_info_size * sizeof *files_info)) == NULL) { closedir(d); free(names); return NULL; } while ((de = readdir(d)) != NULL) { if (checkprintable(de->d_name) != 0 || lstat(de->d_name, &st) < 0) { continue; } name_len = strlen(de->d_name) + (size_t) 1U; while (names_counter + name_len >= names_size) { char *new_names; if (name_len >= CHUNK_SIZE) { names_size += name_len + CHUNK_SIZE; } else { names_size += CHUNK_SIZE; } if ((new_names = realloc(names, names_size)) == NULL) { nomem: closedir(d); free(names); free(files_info); return NULL; } names = new_names; } while ((files_info_counter + (size_t) 1U) >= files_info_size) { FileInfo *new_files_info; files_info_size += (CHUNK_SIZE / sizeof *files_info); if ((new_files_info = realloc(files_info, files_info_size * sizeof *files_info)) == NULL) { goto nomem; } files_info = new_files_info; } memcpy(&names[names_counter], de->d_name, name_len); /* safe */ names[names_counter + name_len - 1] = 0; file_info = &files_info[files_info_counter]; file_info->names_pnt = names_pnt; file_info->name_offset = names_counter; file_info->size = st.st_size; file_info->mtime = st.st_mtime; file_info->mode = st.st_mode; file_info->nlink = st.st_nlink; file_info->uid = st.st_uid; file_info->gid = st.st_gid; names_counter += name_len; files_info_counter++; } closedir(d); files_info[files_info_counter].name_offset = (size_t) -1; *names_pnt = names; if (opt_t) { if (opt_r) { cmp_func = cmp_rt; } else { cmp_func = cmp_t; } } else if (opt_S) { if (opt_r) { cmp_func = cmp_rS; } else { cmp_func = cmp_S; } } else if (opt_r) { cmp_func = cmp_r; } else { cmp_func = cmp; } qsort(files_info, files_info_counter, sizeof files_info[0], cmp_func); return files_info;}/* have to change to the directory first (speed hack for -R) */static void listdir(unsigned int depth, int f, const char *name){ FileInfo *dir; char *names; FileInfo *s; FileInfo *r; int d; if (depth >= max_ls_depth || matches >= max_ls_files) { return; } if ((dir = sreaddir(&names)) == NULL) { addreply(226, MSG_CANT_READ_FILE, name); return; } s = dir; while (s->name_offset != (size_t) -1) { if (FI_NAME(s)[0] != '.') { d = listfile(s, NULL); } else if (opt_a) { d = listfile(s, NULL); if (FI_NAME(s)[1] == 0 || (FI_NAME(s)[1] == '.' && FI_NAME(s)[2] == 0)) { d = 0; } } else { d = 0; } if (!d) { s->name_offset = (size_t) -1; } s++; } outputfiles(f); r = dir; while (opt_R && r != s) { if (r->name_offset != (size_t) -1 && !chdir(FI_NAME(r))) { char *alloca_subdir; const size_t sizeof_subdir = MAXPATHLEN + 1U; if ((alloca_subdir = ALLOCA(sizeof_subdir)) == NULL) { goto toomany; } if (SNCHECK(snprintf(alloca_subdir, sizeof_subdir, "%s/%s", name, FI_NAME(r)), sizeof_subdir)) { goto nolist; }#ifndef MINIMAL if (modern_listings == 0) {#endif#ifdef FANCY_LS_DIRECTORY_HEADERS wrstr(f, "\r\n>----------------["); wrstr(f, alloca_subdir); wrstr(f, "]----------------<\r\n\r\n");#else wrstr(f, "\r\n\r\n"); wrstr(f, alloca_subdir); wrstr(f, ":\r\n\r\n"); #endif#ifndef MINIMAL }#endif listdir(depth + 1U, f, alloca_subdir); nolist: ALLOCA_FREE(alloca_subdir); if (matches >= max_ls_files) { goto toomany; } if (chdir("..")) { /* defensive in the extreme... */ chdir(wd); if (chdir(name)) { /* someone rmdir()'d it? */ die(421, LOG_ERR, "chdir: %s" , strerror(errno)); } } } r++; } toomany: free(names); free(dir); names = NULL;}void donlist(char *arg, const int on_ctrl_conn, const int opt_l_, const int split_args){ int c; matches = 0U; opt_C = opt_d = opt_F = opt_R = opt_r = opt_t = opt_S = 0; opt_l = opt_l_; if (force_ls_a != 0) { opt_a = 1; } else { opt_a = 0; } if (split_args != 0) { while (isspace((unsigned char) *arg)) { arg++; } while (arg && *arg == '-') { while (arg++ && isalnum((unsigned char) *arg)) { switch (*arg) { case 'a': opt_a = 1; break; case 'l': opt_l = 1; opt_C = 0; break; case '1': opt_l = opt_C = 0; break; case 'C': opt_l = 0; opt_C = 1; break; case 'F': opt_F = 1; break; case 'R': opt_R = 1; break; case 'd': opt_d = 1; break; case 'r': opt_r = 1; break; case 't': opt_t = 1; opt_S = 0; break; case 'S': opt_S = 1; opt_t = 0; break; } } while (isspace((unsigned char) *arg)) { arg++; } } } if (on_ctrl_conn == 0) { opendata(); if ((c = xferfd) == -1) { return; } doreply(); if (type == 2) { addreply_noformat(0, "ASCII"); } } else { /* STAT command */ c = 1; safe_write(c, "213-STAT" CRLF, sizeof "213-STAT" CRLF - 1U); } if (arg != NULL && *arg != 0) { int justone; justone = 1; /* just one argument, so don't print dir name */ do { glob_t g; int a; char *endarg; if (split_args == 0) { endarg = NULL; } else if ((endarg = strchr(arg, ' ')) != NULL) { *endarg++ = 0; justone = 0; }#ifdef DEBUG if (debug != 0) { addreply(226, "Glob: %s", arg); }#endif /* Expand ~ here if needed */ alarm(GLOB_TIMEOUT); a = sglob(arg, GLOB_BRACE | (opt_a ? GLOB_PERIOD : 0), NULL, &g, max_ls_files + 2, max_ls_depth * 2); alarm(0); if (a == 0) { char **path; path = g.gl_pathv; if (path && path[0] && path[1]) { justone = 0; } while (path && *path) { struct stat st; if (stat(*path, &st) == 0) { if (opt_d || !(S_ISDIR(st.st_mode))) { listfile(NULL, *path); **path = 0; } } else { **path = 0; } path++; } outputfiles(c); /* in case of opt_C */ path = g.gl_pathv; while (path && *path) { if (matches >= max_ls_files) { break; } if (**path) { if (!justone) {#ifdef FANCY_LS_DIRECTORY_HEADERS wrstr(c, "\r\n>-----------------["); wrstr(c, *path); wrstr(c, "]-----------------<\r\n\r\n");#else wrstr(c, "\r\n\r\n"); wrstr(c, *path); wrstr(c, ":\r\n\r\n");#endif } if (!chdir(*path)) { listdir(0U, c, *path); chdir(wd); } } path++; } } else { if (a == GLOB_NOSPACE) { addreply(226, MSG_GLOB_NO_MEMORY, arg); addreply_noformat(0, MSG_PROBABLY_DENIED); } else if (a == GLOB_ABEND) { addreply(226, MSG_GLOB_READ_ERROR, arg); } else if (a != GLOB_NOMATCH) { addreply(226, MSG_GLOB_READ_ERROR, arg); addreply_noformat(0, MSG_PROBABLY_DENIED); } } globfree(&g); arg = endarg; } while (arg != NULL); } else { if (opt_d) { listfile(NULL, "."); } else { listdir(0U, c, "."); } outputfiles(c); } wrstr(c, NULL); if (on_ctrl_conn == 0) { close(c); } else { addreply_noformat(213, "End."); goto end; } if (opt_a || opt_C || opt_d || opt_F || opt_l || opt_r || opt_R || opt_t || opt_S) addreply(0, "Options: %s%s%s%s%s%s%s%s%s", opt_a ? "-a " : "", opt_C ? "-C " : "", opt_d ? "-d " : "", opt_F ? "-F " : "", opt_l ? "-l " : "", opt_r ? "-r " : "", opt_R ? "-R " : "", opt_S ? "-S " : "", opt_t ? "-t" : ""); if (matches >= max_ls_files) { addreply(226, MSG_LS_TRUNCATED, matches); } else { addreply(226, MSG_LS_SUCCESS, matches); } end: chdir(wd);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -