/* * cp: do what you'd expect it to do */ #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 copy the file */ char verbose=0; /* show filenames as we copy them */ char preserve=0; /* preserve attributes and times */ extern char *basename(); extern int getopt(); extern int optind, opterr; extern char *optarg; /* * 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) write(out, bfr, size); } /* masscopy */ /* * 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 */ /* * docp() copies a single file */ void docp(src, dest) char *src, *dest; { register srcfd, dstfd; char ans[80]; if (inquire) { fprintf(stderr, "%s? ", src); fflush(stderr); gets(ans); if (ans[0] != 'Y' && ans[0] != 'y') 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) { close(srcfd); fprintf(stderr, "cp: couldn't create %s (destination)\n", dest); return; } masscopy(srcfd, dstfd); if (preserve && copytimes(srcfd, dstfd) != 0 && verbose) fprintf(stderr, "cp: couldn't copy times of %s\n", src); close(srcfd); close(dstfd); if (preserve && copymodes(src, dest) != 0 && verbose) fprintf(stderr, "cp: couldn't copy attributes of %s\n", src); else if (verbose && !inquire) puts(src); } else fprintf(stderr, "cp: can't open %s (source)\n",src); } /* docp */ /* * badboy() complains about bad use of arguments, then retires */ badboy() { fprintf(stderr, "usage: cp [-fipv] src dst\n"); fprintf(stderr, " cp [-fipv] src1 .. srcn dir\n"); exit(1); } /* badboy */ /* * cp, 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, "fipv")) != EOF) { switch (i) { case 'v': verbose = 1; break; case 'i': inquire = 1; break; case 'f': inquire = 0; break; case 'p': preserve= 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, "cp: 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])); docp(myargv[i], destfile); } } else docp(myargv[0], myargv[1]); exit(0); } /* main */