1/* See LICENSE file for copyright and license details. */
2
3
4#include <sys/stat.h>
5
6#include <errno.h>
7#include <fcntl.h>
8#include <stdio.h>
9
10#include "fs.h"
11#include "util.h"
12
13static int mv_status = 0;
14
15static int
16mv(const char *s1, const char *s2, int depth)
17{
18 struct recursor r = { .fn = rm, .follow = 'P', .flags = SILENT };
19
20 if (!rename(s1, s2))
21 return 0;
22 if (errno == EXDEV) {
23 cp_aflag = cp_rflag = cp_pflag = 1;
24 cp_follow = 'P';
25 cp_status = 0;
26 rm_status = 0;
27 cp(s1, s2, depth);
28 if (cp_status == 0)
29 recurse(AT_FDCWD, s1, NULL, &r);
30 if (cp_status || rm_status)
31 mv_status = 1;
32 } else {
33 weprintf("%s -> %s:", s1, s2);
34 mv_status = 1;
35 }
36
37 return 0;
38}
39
40static void
41usage(void)
42{
43 eprintf("usage: %s [-f] source ... dest\n", argv0);
44}
45
46// ?man mv: move or rename files
47// ?man arguments: source ... dest
48// ?man move or rename files and directories
49int
50main(int argc, char *argv[])
51{
52 struct stat st;
53
54 ARGBEGIN {
55 // ?man -f: do not prompt before overwriting
56 case 'f':
57 break;
58 default:
59 usage();
60 } ARGEND
61
62 if (argc < 2)
63 usage();
64
65 if (argc > 2) {
66 if (stat(argv[argc - 1], &st) < 0)
67 eprintf("stat %s:", argv[argc - 1]);
68 if (!S_ISDIR(st.st_mode))
69 eprintf("%s: not a directory\n", argv[argc - 1]);
70 }
71 enmasse(argc, argv, mv);
72
73 return mv_status;
74}