#undef ATOM
/* user list header */
-#define USER_LIST_HEADER_ATOMS \
+#define USER_LIST_HEADER_TRAILER_ATOMS \
ATOM(pw_name, STRING) \
ATOM(uid, ID)
#define ATOM(x, y) { .name = #x, .type = AT_ ## y},
-struct atom user_list_header_atoms[] = {
- USER_LIST_HEADER_ATOMS
+struct atom user_list_header_trailer_atoms[] = {
+ USER_LIST_HEADER_TRAILER_ATOMS
{.name = NULL}
};
#undef ATOM
#define ATOM(x, y) ulha_ ## x,
-enum user_list_header_atoms {USER_LIST_HEADER_ATOMS};
+enum user_list_header_trailer_atoms {USER_LIST_HEADER_TRAILER_ATOMS};
#undef ATOM
/* user summary */
struct user_list_format_info {
struct format_info *fi;
struct format_info *header_fi;
+ struct format_info *trailer_fi;
};
struct user_summary_info {
buf = format_items(fi, values);
ret = output("%s", buf);
free(buf);
- return ret;
+ if (ret < 0)
+ return ret;
+ return output("%s", select_conf.trailer_arg);
}
+/* row: a pointer to a row of the *user* table */
static int user_summary_loop_function(struct osl_row *row, void *data)
{
struct user_summary_info *usi = data;
if (usi->preg) {
char *dirname;
- ret = get_dir_name_of_row(row, &dirname);
+ ret = get_dir_name_of_user_row(row, usi->ui, &dirname);
if (ret < 0)
goto err;
ret = dir_is_admissible(dirname, usi->preg, usi->inverse_matching);
for (i = 0; i < usld.num_admissible_users; i++) {
if (select_conf.limit_arg >= 0 && i > select_conf.limit_arg)
break;
- print_user_summary_line(usld.usis + i, usld.fi);
+ ret = print_user_summary_line(usld.usis + i, usld.fi);
+ if (ret < 0)
+ goto out;
}
+ ret = output("%s", select_conf.trailer_arg);
out:
free(usld.usis);
return ret;
.fi = ulfi->fi,
.count = select_conf.limit_arg
};
- union atom_value header_values[] = {
+ union atom_value header_trailer_values[] = {
[ulha_uid] = {.num_value = (long long unsigned)ui->uid},
[ulha_pw_name] = {.string_value = ui->pw_name?
ui->pw_name : "?"}
};
- char *buf = format_items(ulfi->header_fi, header_values);
+ char *buf = format_items(ulfi->header_fi, header_trailer_values);
ret = output("%s", buf);
free(buf);
ret = adu_loop_reverse(ui->table, sort_column, &uli,
user_list_loop_function, &uli.ret, &uli.osl_errno);
free_regex(uli.preg);
+ if (ret < 0)
+ return ret;
+ buf = format_items(ulfi->trailer_fi, header_trailer_values);
+ ret = output("%s", buf);
+ free(buf);
return ret;
}
struct user_list_format_info ulfi = {.fi = fi};
char *header_fmt = select_conf.header_given?
select_conf.header_arg : "uid %(uid)(%(pw_name)):\n";
+ char *trailer_fmt = select_conf.trailer_arg;
int ret = parse_format_string(header_fmt,
- user_list_header_atoms, &ulfi.header_fi);
+ user_list_header_trailer_atoms, &ulfi.header_fi);
+ if (ret < 0)
+ return ret;
+ ret = parse_format_string(trailer_fmt,
+ user_list_header_trailer_atoms, &ulfi.trailer_fi);
if (ret < 0)
return ret;
ret = for_each_admissible_user(print_user_list, &ulfi);
free_format_info(ulfi.header_fi);
+ free_format_info(ulfi.trailer_fi);
return ret;
}
ret = adu_loop_reverse(dir_table, sort_column, &gli,
global_list_loop_function, &gli.ret, &gli.osl_errno);
free_regex(gli.preg);
- return ret;
+ if (ret < 0)
+ return ret;
+ return output("%s", select_conf.trailer_arg);
}
static int print_statistics(struct format_info *fi)
return print_user_lists(fi);
case select_mode_arg_user_summary:
return print_user_summary(fi);
+ default:
+ ERROR_LOG("bad select mode\n");
+ return -ERRNO_TO_ERROR(EINVAL);
};
- ERROR_LOG("bad select mode\n");
- return -ERRNO_TO_ERROR(EINVAL);
}
static int open_pipe(char *path)
{
- int p[2], ret, argc;
+ int p[2], ret;
char **argv;
ret = pipe(p);
if (p[0] != STDIN_FILENO)
dup2(p[0], STDIN_FILENO);
DEBUG_LOG("executing %s\n", path);
- argc = split_args(path, &argv, " \t");
+ split_args(path, &argv, " \t");
execvp(argv[0], argv);
ERROR_LOG("error executing %s: %s\n", path,
adu_strerror(ERRNO_TO_ERROR(errno)));
/** Default format string for global_list mode. */
#define GLOBAL_LIST_DFLT_FMT "%(size:r:8) %(files:r:8) %(dirname)\n"
/** Default format string for global_summary mode. */
-#define GLOBAL_SUMMARY_DFLT_FMT "#directories: %(dirs), #files: %(files), size: %(size)\n\n"
+#define GLOBAL_SUMMARY_DFLT_FMT "#directories: %(dirs), #files: %(files), size: %(size)\n"
/** Default format string for user_list mode. */
#define USER_LIST_DFLT_FMT "%(size:r:5) %(files:r:5) %(dirname)\n"
/** Default format string for user_summary mode. */
-#define USER_SUMMARY_DFLT_FMT "%(pw_name:l:16) %(uid:r:5) %(dirs:r:5) %(files:r:5) %(size:r:5)\n"
+#define USER_SUMMARY_DFLT_FMT "%(pw_name:l:16) %(uid:r:6) %(dirs:r:5) %(files:r:5) %(size:r:5)\n"
static int setup_format_string(char *fmt, struct format_info **fi)
{