/* cmd-inventory.c: file inventories
*
* vim:smartindent ts=8:sts=2:sta:et:ai:shiftwidth=2
****************************************************************
* Copyright (C) 2002, 2003 Tom Lord
*
* See the file "COPYING" for further information about
* the copyright and warranty status of this work.
*/
#include "config-options.h"
#include "po/gettext.h"
#include "hackerlab/bugs/exception.h"
#include "hackerlab/cmd/main.h"
#include "hackerlab/vu/safe.h"
#include "hackerlab/char/pika-escaping-utils.h"
#include "hackerlab/os/errno-to-string.h"
#include "libarch/project-tree.h"
#include "libarch/invent.h"
#include "commands/cmd.h"
#include "commands/inventory.h"
#include "commands/version.h"
static t_uchar * usage = N_("[options] [dir]*");
#define OPTS(OP) \
OP (opt_help_msg, "h", "help", 0, \
N_("display help")) \
OP (opt_long_help, "H", 0, 0, \
N_("Display a verbose help message and exit.")) \
OP (opt_version, "V", "version", 0, \
N_("display version info\n")) \
OP (opt_source, "s", "source", 0, \
N_("list source files")) \
OP (opt_precious, "p", "precious", 0, \
N_("list precious files")) \
OP (opt_backups, "b", "backups", 0, \
N_("list backup files")) \
OP (opt_junk, "j", "junk", 0, \
N_("list junk files")) \
OP (opt_unrecognized, "u", "unrecognized", 0, \
N_("list unrecognized files")) \
OP (opt_trees, "t", "trees", 0, \
N_("list roots of nested trees\n")) \
OP (opt_directories, "d", "directories", 0, \
N_("list only directories")) \
OP (opt_files, "f", "files", 0, \
N_("list only non-directories")) \
OP (opt_both, "B", "both", 0, \
N_("list both dirs and files")) \
OP (opt_kind, 0, "kind", 0, \
N_("indicate file kinds\n")) \
OP (opt_all, 0, "all", 0, \
N_("include arch control files")) \
OP (opt_nested, 0, "nested", 0, \
N_("include nested trees")) \
OP (opt_no_recursion, 0, "no-recursion", 0, \
N_("do not list content of directory\n")) \
OP (opt_ids, 0, "ids", 0, \
N_("list with ids (source files only)")) \
OP (opt_untagged, 0, "untagged", 0, \
N_("include files that are missing ids\n")) \
OP (opt_explicit, 0, "explicit", 0, \
N_("use explicit file ids")) \
OP (opt_implicit, 0, "implicit", 0, \
N_("permit implicit file ids")) \
OP (opt_tagline, 0, "tagline", 0, \
N_("permit tagline file ids")) \
OP (opt_names, 0, "names", 0, \
N_("use name-based file ids")) \
OP (opt_unescaped, 0, "unescaped", 0, \
N_("show filenames in unescaped form"))
t_uchar arch_cmd_inventory_help[] = N_("inventory a source tree\n"
"With no arguments, print a human-readable inventory report.\n"
"\n"
"With category options (--source etc) limit the report to just\n"
"those files. With no other options, the report includes all\n"
"sections and files.\n"
"\n"
"The options -d, -f, and -b cancel each other.\n"
"\n"
"The options --nested and --no-recursion cancel each other.\n"
"\n"
"If a directory is precious, junk, or unrecognized, only the\n"
"directory name itself is printed -- its contents are not\n"
"searched.\n");
enum options
{
OPTS (OPT_ENUM)
};
static struct opt_desc opts[] =
{
OPTS (OPT_DESC)
{-1, 0, 0, 0, 0}
};
/* __STDC__ prototypes for static functions */
static void inventory_printer (void * closure, invent_callback_data_t const * const data);
static int show_dirs = 0;
static int show_files = 1;
static int show_kind = 0;
static int show_ids;
static int n_categories = 0;
int
arch_cmd_inventory (t_uchar * program_name, int argc, char * argv[])
{
int o;
struct opt_parsed * option;
struct arch_inventory_options inv_options;
int escape_classes = arch_escape_classes;
option = 0;
mem_set0 ((t_uchar *)&inv_options, sizeof (inv_options));
while (1)
{
o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv,
program_name, usage, libarch_version_string, arch_cmd_inventory_help,
opt_help_msg, opt_long_help, opt_version);
if (o == opt_none)
break;
switch (o)
{
default:
safe_printfmt (2, "unhandled option `%s'\n", option->opt_string);
panic ("internal error parsing arguments");
usage_error:
opt_usage (2, argv[0], program_name, usage, 1);
exit (1);
/* bogus_arg: */
safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string);
goto usage_error;
case opt_source:
inv_options.categories |= arch_inventory_source;
break;
case opt_precious:
inv_options.categories |= arch_inventory_precious;
break;
case opt_backups:
inv_options.categories |= arch_inventory_backup;
break;
case opt_junk:
inv_options.categories |= arch_inventory_junk;
break;
case opt_unrecognized:
inv_options.categories |= arch_inventory_unrecognized;
break;
case opt_trees:
inv_options.categories |= arch_inventory_tree;
break;
case opt_no_recursion:
inv_options.no_recursion = 1;
inv_options.nested = 0;
break;
case opt_directories:
show_dirs = 1;
show_files = 0;
break;
case opt_files:
show_dirs = 0;
show_files = 1;
break;
case opt_both:
show_dirs = 1;
show_files = 1;
break;
case opt_kind:
show_kind = 1;
break;
case opt_all:
inv_options.include_excluded = 1;
break;
case opt_nested:
inv_options.nested = 1;
inv_options.no_recursion = 0;
break;
case opt_ids:
inv_options.want_ids = 1;
show_ids = 1;
break;
case opt_untagged:
inv_options.treat_unrecognized_source_as_source = 1;
break;
case opt_explicit:
inv_options.override_method = 1;
inv_options.method = arch_explicit_id_tagging;
break;
case opt_implicit:
inv_options.override_method = 1;
inv_options.method = arch_implicit_id_tagging;
break;
case opt_tagline:
inv_options.override_method = 1;
inv_options.method = arch_tagline_id_tagging;
break;
case opt_names:
inv_options.override_method = 1;
inv_options.method = arch_names_id_tagging;
break;
case opt_unescaped:
escape_classes = 0;
break;
}
}
lim_free (lim_use_must_malloc, option);
n_categories = 0;
if (inv_options.categories & arch_inventory_source)
++n_categories;
if (inv_options.categories & arch_inventory_precious)
++n_categories;
if (inv_options.categories & arch_inventory_backup)
++n_categories;
if (inv_options.categories & arch_inventory_junk)
++n_categories;
if (inv_options.categories & arch_inventory_tree)
++n_categories;
if (inv_options.categories & arch_inventory_unrecognized)
++n_categories;
if (!n_categories)
{
n_categories = 6;
inv_options.categories = arch_inventory_source | arch_inventory_precious | arch_inventory_backup | arch_inventory_tree | arch_inventory_unrecognized;
}
if (argc == 1)
{
argv[1] = ".";
++argc;
}
{
int x;
int errn;
int re_error;
for (x = 1; x < argc; ++x)
{
arch_project_tree_t * tree;
char * bad_file;
errn = 0;
re_error = 0;
if ( vu_access(&errn, argv[x], X_OK | F_OK ) == -1)
{
safe_printfmt (2, "inventory: Cannot access directory %s\n%s\n", argv[x], errno_to_string(errn));
exit (2);
}
tree = arch_project_tree_new_ext (talloc_context, argv[x], 1, 0);
arch_get_inventory_naming_conventions (&inv_options, tree);
bad_file = 0;
arch_inventory_traversal_path (&inv_options, tree, argv[x], inventory_printer, &escape_classes);
arch_free_inventory_naming_conventions (&inv_options);
arch_project_tree_delete (tree);
}
}
return 0;
}
static void
inventory_printer (void * closure, invent_callback_data_t const * const data)
{
t_uchar * path = data->path;
if ((data->category != arch_inventory_tree) && !show_dirs && S_ISDIR (data->stat_buf.st_mode))
return;
if (!show_files && !S_ISDIR (data->stat_buf.st_mode))
return;
if (n_categories > 1)
{
t_uchar * quest = (data->has_source_name ? "?" : " ");
switch (data->category)
{
case arch_inventory_source:
safe_printfmt (1, "S ");
break;
case arch_inventory_precious:
safe_printfmt (1, "P%s ", quest);
break;
case arch_inventory_backup:
safe_printfmt (1, "B%s ", quest);
break;
case arch_inventory_junk:
safe_printfmt (1, "J%s ", quest);
break;
case arch_inventory_tree:
safe_printfmt (1, "T%s ", quest);
break;
case arch_inventory_unrecognized:
safe_printfmt (1, "U%s ", quest);
break;
case arch_inventory_excludes:
break;
}
}
if (show_kind)
{
if (S_ISDIR (data->stat_buf.st_mode))
safe_printfmt (1, "d ");
else if (S_ISLNK (data->stat_buf.st_mode))
safe_printfmt (1, "> ");
else
safe_printfmt (1, "r ");
}
if (path[0] == '.' && path[1] == '/')
path += 2;
{
t_uchar * item;
item = pika_save_escape_iso8859_1 (0, 0, *(int *)closure, path);
safe_printfmt (1, "%s%s%s\n", item, (show_ids ? "\t" : ""), (show_ids ? (data->id ? (char *)data->id : "???") : ""));
lim_free (0, item);
}
}
/* tag: Tom Lord Wed May 14 10:52:12 2003 (srcfind.c)
*/
syntax highlighted by Code2HTML, v. 0.9.1