/* * mv: do what you'd expect it to do */ #include #include #include #include #include /* for copytimes(), copymodes() */ #include "glob.h" /* and DosQFileMode() */ #define CBFRSIZ 10240 static char bfr[CBFRSIZ]; char inquire=0; /* ask if we want to move the file */ char verbose=0; /* show filenames as we move them */ char forced=0; /* force the move */ extern char *basename(); extern int getopt(); extern int optind, opterr; extern char *optarg; /* * copymodes() copies the attributes from the src to the dst file */ copymodes(src, dst) char *src, *dst; { short attrib; if (DosQFileMode(src, &attrib, 0L) == 0) { DosSetFileMode(dst, attrib, 0L); return 0; } return 1; } /* copymodes */ /* * copytimes() makes the dates of the dst file the same as the src file. */ copytimes(src, dst) { FILESTATUS dates; if (DosQFileInfo(src, 1, &dates, sizeof dates) == 0) { DosSetFileInfo(dst, 1, (PBYTE)&dates, sizeof dates); return 0; } return 1; } /* copytimes */ /* * masscopy() does the work of copying a file from one place to * another. */ masscopy(in, out) register in, out; { register size; while ((size=read(in, bfr, CBFRSIZ)) > 0) if (write(out, bfr, size) != size) return 2; return size; } /* masscopy */ /* * domv() moves a single file */ void domv(src, dest) char *src, *dest; { register srcfd, dstfd; char ans[80]; register st; if (access(src) < 0) { if (!forced) perror(src); return; } if (inquire) { fprintf(stderr, "%s? ", src); fflush(stderr); gets(ans); if (ans[0] != 'Y' && ans[0] != 'y') return; } remove(dest); st = rename(src, dest); if (st == 0) return; else if (errno != ENOENT && errno != EXDEV) { perror(src); return; } if ((srcfd = open(src, O_RDONLY|O_BINARY)) >= 0) { dstfd = open(dest, O_WRONLY|O_TRUNC|O_CREAT|O_BINARY, 0666); if (dstfd < 0) { perror(dest); close(srcfd); return; } if (st = masscopy(srcfd, dstfd)) perror((st==1)?src:dest); else copytimes(srcfd, dstfd); close(srcfd); close(dstfd); if (st == 0) { copymodes(src, dest); if (verbose && !inquire) puts(src); if (remove(src) != 0) perror(src); } else /* remove destination file if copy was bad */ remove(dest); } else if (!forced) perror(src); } /* domv */ /* * badboy() complains about bad use of arguments, then retires */ badboy() { fprintf(stderr, "usage: mv [-fiv] src dst\n"); fprintf(stderr, " mv [-fiv] src1 .. srcn dir\n"); exit(1); } /* badboy */ /* * mv, in the flesh */ main(argc, argv) char **argv; { register i; register destisdir = 0; static char destfile[512]; short attrib; char *fn, *fbn; char c; opterr=1; while ((i=getopt(argc, argv, "fvi")) != EOF) { switch (i) { case 'f': forced = 1; inquire=0; break; case 'v': verbose = 1; break; case 'i': inquire = 1; break; default: badboy(); } } optind--; expand_arglist(argc-optind, argv+optind, (struct args_t*)0); if (myargc < 2) badboy(); fn = myargv[myargc-1]; fbn = basename(fn); c = fn[strlen(fn)-1]; if (c == '/' || c == '\\' || c == ':') destisdir = 1; else if (DosQFileMode(fn, &attrib, 0L) == 0 && (attrib & F_DIRECT)) { c = fn[strlen(fn)-1]; destisdir = 1; } else if (strcmp(fbn, ".") == 0 || strcmp(fbn, "..") == 0) { c = '.'; destisdir = 1; } if (myargc > 2 && !destisdir) { fprintf(stderr, "mv: destination is not a directory\n"); exit(0); } if (destisdir) { strcpy(destfile, fn); if (c != '/' && c != '\\') strcat(destfile, "/"); fn = destfile+strlen(destfile); for (i=0; i < myargc-1; i++) { strcpy(fn, basename(myargv[i])); domv(myargv[i], destfile); } } else domv(myargv[0], myargv[1]); exit(0); } /* main */