void core(t_opt arg, t_list *path, int multidir) { DIR *dir; t_list *file; t_list *directory; t_list *cur; file = NULL; directory = NULL; cur = path; while (cur) { if ((dir = opendir(cur->content)) == NULL) errno != ENOTDIR ? basicerror("ft_ls: ", cur->content, 0) : \ ft_lstpushback(&file, cur->content, cur->content_size); else { ft_lstpushback(&directory, cur->content, cur->content_size); if (closedir(dir) == -1) basicerror("ft_ls: ", cur->content, 0); } cur = cur->next; } file ? do_ls_file(arg, file) : NULL; file && directory ? ft_putchar('\n') : NULL; directory ? do_ls_dir(arg, directory, multidir) : NULL; }
/* sftp ls.1 replacement which handles path globs */ static int do_globbed_ls(struct sftp_conn *conn, char *path, char *strip_path, int lflag) { glob_t g; u_int i, c = 1, colspace = 0, columns = 1; Attrib *a = NULL; memset(&g, 0, sizeof(g)); if (remote_glob(conn, path, GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE, NULL, &g) || (g.gl_pathc && !g.gl_matchc)) { if (g.gl_pathc) globfree(&g); error("Can't ls: \"%s\" not found", path); return (-1); } if (interrupted) goto out; /* * If the glob returns a single match and it is a directory, * then just list its contents. */ if (g.gl_matchc == 1) { if ((a = do_lstat(conn, g.gl_pathv[0], 1)) == NULL) { globfree(&g); return (-1); } if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) && S_ISDIR(a->perm)) { int err; err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag); globfree(&g); return (err); } } if (!(lflag & LS_SHORT_VIEW)) { u_int m = 0, width = 80; struct winsize ws; /* Count entries for sort and find longest filename */ for (i = 0; g.gl_pathv[i]; i++) m = MAX(m, strlen(g.gl_pathv[i])); if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1) width = ws.ws_col; columns = width / (m + 2); columns = MAX(columns, 1); colspace = width / columns; } for (i = 0; g.gl_pathv[i] && !interrupted; i++, a = NULL) { char *fname; fname = path_strip(g.gl_pathv[i], strip_path); if (lflag & LS_LONG_VIEW) { char *lname; struct stat sb; /* * XXX: this is slow - 1 roundtrip per path * A solution to this is to fork glob() and * build a sftp specific version which keeps the * attribs (which currently get thrown away) * that the server returns as well as the filenames. */ memset(&sb, 0, sizeof(sb)); if (a == NULL) a = do_lstat(conn, g.gl_pathv[i], 1); if (a != NULL) attrib_to_stat(a, &sb); lname = ls_file(fname, &sb, 1); printf("%s\n", lname); xfree(lname); } else { printf("%-*s", colspace, fname); if (c >= columns) { printf("\n"); c = 1; } else c++; } xfree(fname); } if (!(lflag & LS_LONG_VIEW) && (c != 1)) printf("\n"); out: if (g.gl_pathc) globfree(&g); return (0); }