#include <sys/mman.h>
#include <fnmatch.h>
#include <sys/shm.h>
+#include <dirent.h>
#include <osl.h>
#include <lopsub.h>
{
const struct lls_command *cmd = SERVER_CMD_CMD_PTR(LS);
struct ls_options *opts = aca->query.data;
- int i = 0, ret;
+ int ret;
time_t current_time;
const struct lls_opt_result *r_r, *r_a;
+ uint32_t limit, k, n;
ret = lls_deserialize_parse_result(
(char *)aca->query.data + sizeof(*opts), cmd, &opts->lpr);
prepare_ls_row));
if (ret < 0)
goto out;
- if (opts->num_matching_paths == 0) {
+ n = opts->num_matching_paths;
+ if (n == 0) {
ret = lls_num_inputs(opts->lpr) > 0? -E_NO_MATCH : 0;
goto out;
}
if (ret < 0)
goto out;
time(¤t_time);
- if (lls_opt_given(r_r))
- for (i = opts->num_matching_paths - 1; i >= 0; i--) {
- ret = print_list_item(opts->data_ptr[i], opts,
- &aca->pbout, current_time);
- if (ret < 0)
- goto out;
- }
- else
- for (i = 0; i < opts->num_matching_paths; i++) {
- ret = print_list_item(opts->data_ptr[i], opts,
- &aca->pbout, current_time);
- if (ret < 0)
- goto out;
- }
+ limit = SERVER_CMD_UINT32_VAL(LS, LIMIT, opts->lpr);
+ for (k = 0; k < n && (limit == 0 || k < limit); k++) {
+ uint32_t idx = lls_opt_given(r_r)? n - 1 - k : k;
+ ret = print_list_item(opts->data_ptr[idx], opts, &aca->pbout,
+ current_time);
+ if (ret < 0)
+ goto out;
+ }
out:
lls_free_parse_result(opts->lpr, cmd);
free(opts->data);
return send_ret;
}
+/*
+ * Call back once for each regular file below a directory.
+ *
+ * Traverse the given directory recursively and call the supplied callback for
+ * each regular file encountered. The first argument to the callback will be
+ * the path to the regular file and the second argument will be the data
+ * pointer. All file types except regular files and directories are ignored. In
+ * particular, symlinks are not followed. Subdirectories are ignored silently
+ * if the calling process has insufficient access permissions.
+ */
+static int for_each_file_in_dir(const char *dirname,
+ int (*func)(const char *, void *), void *data)
+{
+ int ret;
+ DIR *dir;
+ struct dirent *entry;
+
+ dir = opendir(dirname);
+ if (!dir)
+ return errno == EACCES? 1 : -ERRNO_TO_PARA_ERROR(errno);
+ /* scan cwd recursively */
+ while ((entry = readdir(dir))) {
+ char *tmp;
+ struct stat s;
+
+ if (!strcmp(entry->d_name, "."))
+ continue;
+ if (!strcmp(entry->d_name, ".."))
+ continue;
+ tmp = make_message("%s/%s", dirname, entry->d_name);
+ ret = 0;
+ if (lstat(tmp, &s) != -1) {
+ if (S_ISREG(s.st_mode))
+ ret = func(tmp, data);
+ else if (S_ISDIR(s.st_mode))
+ ret = for_each_file_in_dir(tmp, func, data);
+ }
+ free(tmp);
+ if (ret < 0)
+ goto out;
+ }
+ ret = 1;
+out:
+ closedir(dir);
+ return ret;
+}
+
static int com_add(struct command_context *cc, struct lls_parse_result *lpr)
{
int i, ret;