static char *sccsid
= "@(#)mv.c 4.5 (Berkeley) 82/02/11";
int iflag
= 0; /* interactive flag. If this flag is set,
* the user is queried before files are
int fflag
= 0; /* force flag. supercedes all restrictions */
while (argc
>1 && *argv
[1] == '-') {
* all files following a null option are considered file names
if (*(arg
+1) == '\0') break;
/* don't live with bad options */
if (stat(argv
[1], &s1
) < 0) {
fprintf(stderr
, "mv: cannot access %s\n", argv
[1]);
if ((s1
.st_mode
& S_IFMT
) == S_IFDIR
) {
return mvdir(argv
[1], argv
[2]);
if (stat(argv
[argc
-1], &s2
) < 0 || (s2
.st_mode
& S_IFMT
) != S_IFDIR
)
r
|= move(argv
[i
], argv
[argc
-1]);
fprintf(stderr
, "usage: mv [-if] f1 f2; or mv [-if] d1 d2; or mv [-if] f1 ... fn d1\n");
if (stat(source
, &s1
) < 0) {
fprintf(stderr
, "mv: cannot access %s\n", source
);
if ((s1
.st_mode
& S_IFMT
) == S_IFDIR
) {
fprintf(stderr
, "mv: directory rename only\n");
if (stat(target
, &s2
) >= 0) {
if ((s2
.st_mode
& S_IFMT
) == S_IFDIR
) {
sprintf(buf
, "%s/%s", target
, dname(source
));
if (stat(target
, &s2
) >= 0) {
if ((s2
.st_mode
& S_IFMT
) == S_IFDIR
) {
fprintf(stderr
, "mv: %s is a directory\n", target
);
} else if (iflag
&& !fflag
) {
fprintf(stderr
, "remove %s? ", target
);
while (c
!= '\n' && c
!= EOF
)
if (s1
.st_dev
==s2
.st_dev
&& s1
.st_ino
==s2
.st_ino
) {
fprintf(stderr
, "mv: %s and %s are identical\n",
if (access(target
, 2) < 0 && !fflag
&& isatty(fileno(stdin
))) {
fprintf(stderr
, "override protection %o for %s? ",
s2
.st_mode
& MODEBITS
, target
);
while (c
!= '\n' && c
!= EOF
)
if (unlink(target
) < 0) {
fprintf(stderr
, "mv: cannot unlink %s\n", target
);
if (link(source
, target
) < 0) {
fprintf(stderr
, "mv: try again\n");
execl("/bin/cp", "cp", source
, target
, 0);
fprintf(stderr
, "mv: cannot exec cp\n");
while ((c
= wait(&status
)) != i
&& c
!= -1)
utime(target
, &s1
.st_atime
);
if (unlink(source
) < 0) {
fprintf(stderr
, "mv: cannot unlink %s\n", source
);
if (stat(target
, &s2
) >= 0) {
if ((s2
.st_mode
&S_IFMT
) != S_IFDIR
) {
fprintf(stderr
, "mv: %s exists\n", target
);
if (strlen(target
) > MAXN
-strlen(p
)-2) {
fprintf(stderr
, "mv :target name too long\n");
if (stat(target
, &s2
) >= 0) {
fprintf(stderr
, "mv: %s exists\n", buf
);
if (strcmp(source
, target
) == 0) {
fprintf(stderr
, "mv: ?? source == target, source exists and target doesnt\n");
if (!strcmp(p
, DOT
) || !strcmp(p
, DOTDOT
) || !strcmp(p
, "") || p
[strlen(p
)-1]=='/') {
fprintf(stderr
, "mv: cannot rename %s\n", p
);
if (stat(pname(source
), &s1
) < 0 || stat(pname(target
), &s2
) < 0) {
fprintf(stderr
, "mv: cannot locate parent\n");
if (access(pname(target
), 2) < 0) {
fprintf(stderr
, "mv: no write access to %s\n", pname(target
));
if (access(pname(source
), 2) < 0) {
fprintf(stderr
, "mv: no write access to %s\n", pname(source
));
if (s1
.st_dev
!= s2
.st_dev
) {
fprintf(stderr
, "mv: cannot move directories across devices\n");
if (s1
.st_ino
!= s2
.st_ino
) {
if (chkdot(source
) || chkdot(target
)) {
fprintf(stderr
, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT
);
if (check(pname(target
), s1
.st_ino
))
for (i
= 1; i
<= NSIG
; i
++)
if (link(source
, target
) < 0) {
fprintf(stderr
, "mv: cannot link %s to %s\n", target
, source
);
if (unlink(source
) < 0) {
fprintf(stderr
, "mv: %s: cannot unlink\n", source
);
fprintf(stderr
, "mv: %s: cannot unlink\n", dst
);
if (link(target
, source
) >= 0)
if (link(pname(target
), dst
) < 0) {
fprintf(stderr
, "mv: cannot link %s to %s\n",
if (link(pname(source
), dst
) >= 0)
if (link(target
, source
) >= 0)
if (link(source
, target
) < 0) {
fprintf(stderr
, "mv: cannot link %s and %s\n",
if (unlink(source
) < 0) {
fprintf(stderr
, "mv: ?? cannot unlink %s\n", source
);
while (c
= *p
++ = *name
++)
if (q
== buf
&& *q
== DELIM
)
return buf
[0]? buf
: DOT
;
while (sbuf
.st_ino
!= ROOTINO
) {
if (stat(nspth
, &sbuf
) < 0) {
fprintf(stderr
, "mv: cannot access %s\n", nspth
);
if (sbuf
.st_ino
== dinode
) {
fprintf(stderr
, "mv: cannot move a directory into itself\n");
if (strlen(nspth
) > MAXN
-2-sizeof(DOTDOT
)) {
fprintf(stderr
, "mv: name too long\n");
if (strcmp(dname(s
), DOTDOT
) == 0)
} while (strcmp(s
, DOT
) != 0 && strcmp(s
, SDELIM
) != 0);