#include "adu.h"
#include <dirent.h> /* readdir() */
#include <pwd.h>
+#include "format.h"
+#include "select.h"
#include "gcc-compat.h"
#include "cmdline.h"
void *data);
void sort_hash_table(int (*comp)(const void *, const void *));
-/* select.c */
-struct select_format_info {
- struct format_info *global_list_fi;
- struct format_info *global_summary_fi;
- struct format_info *user_summary_fi;
- struct format_info *user_list_fi;
-};
-int parse_select_options(char *string, struct select_cmdline_parser_params *params,
- struct uid_range **admissible_uids, struct select_format_info *sfi);
-int run_select_query(struct uid_range *admissible_uids, struct select_format_info *sfi);
-int com_select(void);
-
/* create.h */
int com_create(void);
int com_interactive(void);
-#include "format.h"
#include "adu.h"
+#include "format.h"
+#include "select.h"
#include "string.h"
#include "error.h"
#include "cmdline.h"
};
static struct uid_range *admissible_uids;
-static struct select_format_info sfi;
+static struct format_info *fi;
#define INTERACTIVE_COMMANDS \
INTERACTIVE_COMMAND(dump, "dump the current configuration") \
static int icom_run(__a_unused char *line)
{
- return run_select_query(admissible_uids, &sfi);
+ return run_select_query(admissible_uids, fi);
}
static int icom_help(__a_unused char *line)
.check_ambiguity = 0,
.print_errors = 1
};
- return parse_select_options(line, ¶ms, &admissible_uids, &sfi);
+ return parse_select_options(line, ¶ms, &admissible_uids, &fi);
}
static int icom_dump(__a_unused char *line)
global_list_loop_function, &gli.ret, &gli.osl_errno);
}
-static int print_statistics(struct select_format_info *sli)
+static int print_statistics(struct format_info *fi)
{
- int ret;
-
switch (select_conf.select_mode_arg) {
case select_mode_arg_global_list:
- ret = print_global_list(sli->global_list_fi);
- free_format_info(sli->global_list_fi);
- return ret;
+ return print_global_list(fi);
case select_mode_arg_global_summary:
- ret = print_global_summary(sli->global_summary_fi);
- free_format_info(sli->global_summary_fi);
- return ret;
+ return print_global_summary(fi);
case select_mode_arg_user_list:
- ret = for_each_admissible_user(print_user_list,
- sli->user_list_fi);
- free_format_info(sli->user_list_fi);
- return ret;
+ return for_each_admissible_user(print_user_list, fi);
case select_mode_arg_user_summary:
- ret = print_user_summary(sli->user_summary_fi);
- free_format_info(sli->user_summary_fi);
- return ret;
+ return print_user_summary(fi);
};
ERROR_LOG("bad select mode\n");
return ERRNO_TO_ERROR(-EINVAL);
return ret;
}
-int run_select_query(struct uid_range *admissible_uids,
- struct select_format_info *sfi)
+int run_select_query(struct uid_range *admissible_uids, struct format_info *fi)
{
int ret;
if (ret < 0)
goto out;
check_signals();
- ret = print_statistics(sfi);
+ ret = print_statistics(fi);
out:
close_all_tables();
if (output_file != stdout)
return ret;
}
+#define GLOBAL_LIST_DFLT_FMT "%(size:r:8) %(files:r:8) %(dirname)\n"
+#define GLOBAL_SUMMARY_DFLT_FMT "#directories: %(dirs), #files: %(files), size: %(size)\n\n"
+#define USER_LIST_DFLT_FMT "%(size:r:5) %(files:r:5) %(dirname)\n"
+#define USER_SUMMARY_DFLT_FMT "%(pw_name:l:16) %(uid:r:5) %(dirs:r:5) %(files:r:5) %(size:r:5)\n"
+
/* return: < 0: error, >0: OK, == 0: help given */
int parse_select_options(char *string, struct select_cmdline_parser_params *params,
- struct uid_range **admissible_uids, struct select_format_info *sfi)
+ struct uid_range **admissible_uids, struct format_info **fi)
{
int ret;
const char **line;
+ char *fmt = NULL;
+ struct atom *atoms;
if (conf.select_options_given) {
int argc;
return -E_SYNTAX;
if (select_conf.help_given || select_conf.detailed_help_given)
goto help;
+ fmt = select_conf.format_arg;
}
ret = parse_uid_arg(select_conf.uid_arg, admissible_uids);
if (ret < 0)
return ret;
- ret = parse_format_string(select_conf.user_summary_format_arg,
- user_summary_atoms, &sfi->user_summary_fi);
- if (ret < 0)
- return ret;
- ret = parse_format_string(select_conf.global_summary_format_arg,
- global_summary_atoms, &sfi->global_summary_fi);
- if (ret < 0)
- goto global_summary_err;
- ret = parse_format_string(select_conf.global_list_format_arg,
- global_list_atoms, &sfi->global_list_fi);
- if (ret < 0)
- goto global_list_err;
- ret = parse_format_string(select_conf.user_list_format_arg,
- user_list_atoms, &sfi->user_list_fi);
- if (ret < 0)
- goto user_list_err;
- return 1;
-user_list_err:
- free_format_info(sfi->global_list_fi);
-global_list_err:
- free_format_info(sfi->global_summary_fi);
-global_summary_err:
- free_format_info(sfi->user_summary_fi);
- return ret;
+
+ switch (select_conf.select_mode_arg) {
+ case select_mode_arg_global_list:
+ if (!fmt)
+ fmt = GLOBAL_LIST_DFLT_FMT;
+ atoms = global_list_atoms;
+ case select_mode_arg_global_summary:
+ if (!fmt)
+ fmt = GLOBAL_SUMMARY_DFLT_FMT;
+ atoms = global_summary_atoms;
+ case select_mode_arg_user_list:
+ if (!fmt)
+ fmt = USER_LIST_DFLT_FMT;
+ atoms = user_list_atoms;
+ case select_mode_arg_user_summary:
+ if (!fmt)
+ fmt = USER_SUMMARY_DFLT_FMT;
+ atoms = user_summary_atoms;
+ };
+ return parse_format_string(fmt, atoms, fi);
help:
line = select_conf.detailed_help_given?
select_args_info_detailed_help : select_args_info_help;
int com_select(void)
{
struct uid_range *admissible_uids = NULL;
- struct select_format_info sfi;
int ret;
+ struct format_info *fi;
struct select_cmdline_parser_params params = {
.override = 1,
.initialize = 1,
select_cmdline_parser_init(&select_conf);
ret = parse_select_options(conf.select_options_arg, ¶ms,
- &admissible_uids, &sfi);
+ &admissible_uids, &fi);
if (ret <= 0) /* do not run query if help was given */
return ret;
- return run_select_query(admissible_uids, &sfi);
+ ret = run_select_query(admissible_uids, fi);
+ free_format_info(fi);
+ return ret;
}
to the base dir.
"
-########################
-section "Format strings"
-########################
-
-option "global-list-format" -
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-"How to format the global list"
-string typestr="<format>"
-default="%(size:r:8) %(files:r:8) %(dirname)\n"
-details="
- size: Total size of all files
- files: The number of files
- dirname: The name of the directory
-"
-
+option "format" f
+#~~~~~~~~~~~~~~~~
+"How to format the output"
+string typestr="<format_string>"
optional
-option "global-summary-format" -
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-"How to format the global summary"
-string typestr="<format>"
-default="#directories: %(dirs), #files: %(files), size: %(size)\n\n"
details="
- dirs: The number of directories
- files: The number of files
- size: Total size of all files
-"
-optional
+ A string that specifies how the output of the select query is
+ goint to be formated. Depending on the chosen select-mode,
+ several conversion specifiers are available and a different
+ default value for this option applies.
-option "user-list-format" -
-#~~~~~~~~~~~~~~~~~~~~~~~~~~
-"How to format the user list"
-string typestr="<format>"
-default="%(size:r:5) %(files:r:5) %(dirname)\n"
-details="
- pw_name: The user name
- uid: The user id
- files: The number of files
- size: size of all files in that directory
- dirname: The name of the directory
-"
-optional
-option "user-summary-format" -
-#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-"How to format the user summary"
-string typestr="<format>"
-default="%(pw_name:l:16) %(uid:r:5) %(dirs:r:5) %(files:r:5) %(size:r:5)\n"
-details="
- pw_name: The user name
- uid: The user id
- dirs: The number of directories
- files: The number of files
- size: Total size of all files
+ adu knows four different types of directives: string, id,
+ count and size. These are explained in more detail below.
+
+ The general syntax for string and id directives is %(name:a:w)
+ where \"name\" is the name of the directive, \"a\" specifies
+ the alignment and \"w\" is the width specifier which allows
+ to give a field width.
+
+ The alignment specifier is a single character: Either \"l\",
+ \"r\", or \"c\" may be given to specify left, right and
+ centered alignment respectively. The with specifier is a
+ positive integer. Both \"a\" and \"w\" are optional.
+
+ A string directive supported by adu is \"dirname\" which is
+ subsitituted by the name of the directory. It is available
+ if either user_list or global_list mode was selected via
+ --select-mode.
+
+ Examples:
+
+ \"%(diname)\" # print dirname without any padding
+ \"%(dirname:c:20)\" # center dirname in a 20 chars wide field
+
+ The other two types of directives, count and size, are used
+ for numbers. The syntax for these is %(name:a:w:u). The \"a\"
+ and the \"w\" specifier have the same meaning as for the string
+ and id directives. The additional \"u\" specifier selects a unit
+ in which the number that corresponds to the directive should
+ be formated. All three specifiers are optional.
+
+ Possible units are the characters of the set \" bkmgtBKMGT\"
+ specifying bytes, kilobytes, megabytes, gigabytes and
+ terabytes respectively. The difference between the lower and
+ the upper case variants is that the lower case specifiers
+ select 1024-based units while the upper case specifiers use
+ 1000 as the basis.
+
+ The whitespace character is like \"b\", but a space character
+ is printed instead of a unit.
+
+ Two more characters \"h\" and \"H\" (human-readable) are also
+ available that choose an appropriate unit depending on the
+ size of the number being printed.
+
+ An asterisk prepended to the unit specifier prevents the
+ unit from being printed. This is useful mainly for feeding
+ the output of adu to scripts that do not expect units.
+
+ In order to print a percent sign, use \"%%\". Moreover, adu
+ understands \"\n\" and \"\t\" and outputs a newline and a
+ tab character for these combinations respectively.
+
+ Examples:
+
+ \"%(size:r::G)\" # print size in gigabytes right-aligned
+ \"%(size:r5::G)\" # as before, but use 5 char wide field
+ \"%(size:r5::*G)\" # as before, but supress trailing \"G\"
+
+ List of directives and types known to adu, together with their types:
+
+ name type meaning
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ pw_name string user name
+ uid id user id
+ files count number of files
+ dirname string name of the directory
+ size size total size/ directory size
+ dirs count number of directories
+
+ Not all directives are available for each mode:
+
+ name available in directives
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ pw_name user_list, user_summary
+ uid user_list, user_summary
+ files everywhere
+ dirname user_list, global_list
+ size everywhere
+ dirs suer_summary, global_summary
"
-optional
--- /dev/null
+int parse_select_options(char *string, struct select_cmdline_parser_params *params,
+ struct uid_range **admissible_uids, struct format_info **fi);
+int run_select_query(struct uid_range *admissible_uids, struct format_info *fi);
+int com_select(void);