[Toybox] [PATCH] New toy - mv
Georgi Chorbadzhiyski
gf at unixsol.org
Thu Mar 15 02:33:41 PDT 2012
This new toy depends on CP && RM. -f is probably not working.
There is a possible generic functionality here in case of internal_exec(char *argv[])
--
Georgi Chorbadzhiyski
http://georgi.unixsol.org/
-------------- next part --------------
/* vi: set sw=4 ts=4:
*
* mv.c - Move files.
*
* Copyright 2012 Georgi Chorbadzhiyski <georgi at unixsol.org>
*
* See http://www.opengroup.org/onlinepubs/009695399/utilities/mv.html
*
USE_MV(NEWTOY(mv, "<2fiv", TOYFLAG_BIN))
config MV
bool "mv"
default y
depends on CP && RM
help
usage: mv -fiv SOURCE... DEST
Move files from SOURCE to DEST. If more than one SOURCE, DEST must
be a directory.
-f force overwrite
-i interactive, prompt before moving file
-v verbose
*/
#include "toys.h"
#define FLAG_f 4
#define FLAG_i 2
#define FLAG_v 1
// Remove trailing /
// Remove ./ infront
char *normalize(char *x, int xlen) {
if (!xlen)
return x;
while (x[--xlen] == '/')
x[xlen] = '\0';
if (xlen > 1) {
if (x[0] == '.' && x[1] == '/') {
x += 1;
while (x[0] == '/')
x++;
}
}
return x;
}
int internal_exec(char *argv[])
{
struct toy_list *which;
struct toy_context c;
int exitval;
c = toys;
toys.optargs = NULL; // Prevent freeing of original args
which = toy_find(argv[0]);
if (!which)
return -1;
toy_init(which, argv);
toys.which->toy_main();
free(toys.optargs);
exitval = toys.exitval;
toys = c;
return exitval;
}
void mv_main(void)
{
char *dest;
char *fulldest;
int fulldest_len = 0;
struct stat st;
int i;
int ret = 0;
dest = toys.optargs[--toys.optc];
// Many sources, destination must be a directory
if (toys.optc > 1) {
if (stat(dest, &st) != 0 || !S_ISDIR(st.st_mode)) {
error_exit("'%s' is not a directory", dest);
}
}
fulldest_len = 4096;
fulldest = xmalloc(fulldest_len);
dest = normalize(dest, strlen(dest));
for (i=0; i<toys.optc; i++) {
char *src = normalize(toys.optargs[i], strlen(toys.optargs[i]));
if (!strcmp(src, dest))
continue;
int flen = strlen(dest) + 1 + strlen(src) + 2;
if (flen > fulldest_len) {
fulldest = xrealloc(fulldest, flen);
fulldest_len = flen;
}
snprintf(fulldest, flen - 1, "%s/%s", dest, src);
fulldest[flen - 1] = '\0';
if ((toys.optflags & FLAG_i) && !yesno("Confirm mv", 1))
continue;
if (toys.optflags & FLAG_v)
xprintf("mv '%s' -> '%s'\n", src, fulldest);
if (rename(src, fulldest) != 0) {
if (errno == EXDEV) {
char *cp_argv[5] = { "cp", "-af", src, fulldest, NULL };
char *rm_argv[4] = { "rm", "-rf", src, NULL };
if (internal_exec(cp_argv) != 0 || internal_exec(rm_argv) != 0)
toys.exitval = 1;
} else {
perror_msg("%s", fulldest);
toys.exitval = 1;
}
}
}
if (CFG_TOYBOX_FREE) {
free(fulldest);
}
toys.exitval = ret;
}
More information about the Toybox
mailing list