/* cmd-mv.c
*
****************************************************************
* Copyright (C) 2001, 2002, 2003 Tom Lord, Rob Weir
*
* 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/cmd/main.h"
#include "hackerlab/fs/file-names.h"
#include "libarch/inv-ids.h"
#include "commands/mv.h"
#include "commands/version.h"
static t_uchar * usage = N_("[options] from to OR from1 from2 ... dir");
#define OPTS(OP) \
OP (opt_help_msg, "h", "help", 0, \
N_("Display a help message and exit.")) \
OP (opt_long_help, "H", 0, 0, \
N_("Display a verbose help message and exit.")) \
OP (opt_version, "V", "version", 0, \
N_("Display a release identifier string\n" \
"and exit."))
t_uchar arch_cmd_mv_help[] = N_("move a file (or dir, or symlink) and its explicit inventory tag (if any)\n"
"This command is suitable as a replacement for mv(1) within any baz\n"
"tree for any move operation, regardless of id tagging method.\n");
enum options
{
OPTS (OPT_ENUM)
};
static struct opt_desc opts[] =
{
OPTS (OPT_DESC)
{-1, 0, 0, 0, 0}
};
int
arch_cmd_mv (t_uchar * program_name, int argc, char * argv[])
{
int o;
int i;
struct opt_parsed * option;
t_uchar * dest_name = 0;
int dest_is_dir = 0;
struct stat stat_buf;
safe_buffer_fd (1, 0, O_WRONLY, 0);
option = 0;
while (1)
{
o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, libarch_version_string, arch_cmd_mv_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;
}
}
if (argc < 3)
goto usage_error;
dest_name = argv[argc-1];
if (safe_access (dest_name, F_OK) != -1)
{
safe_stat (dest_name, &stat_buf);
if (stat_buf.st_mode & S_IFDIR)
dest_is_dir = 1;
}
/* if the destination is not a directory, then there
should be only 2 args for a simple rename */
if (!dest_is_dir && (argc != 3))
goto usage_error;
for (i=1; i < argc-1; ++i)
{
int move_id = 0;
t_uchar * new_name;
/* if argv[i] is NOT a directory AND it has an explicit tag,
we need to move this tag */
safe_stat (argv[i], &stat_buf);
if (!(stat_buf.st_mode & S_IFDIR) && (safe_access (arch_explicit_id_file_for (argv[i]), F_OK) != -1))
move_id = 1;
if (dest_is_dir)
{
/* if dest_name is a directory, move arg into it */
new_name = file_name_in_vicinity (0, dest_name, file_name_tail (0, argv[i]));
}
else
{
/* otherwise, simply rename the file */
new_name = dest_name;
}
safe_rename (argv[i], new_name);
if (move_id)
arch_move_explicit_id (argv[i], new_name);
}
return 0;
}
/* tag: Rob Weir Sun Sep 21 15:22:53 EST 2003 (cmd-mv.c)
*/
syntax highlighted by Code2HTML, v. 0.9.1