date and time created 80/10/01 17:25:52 by bill
authorBill Joy <bill@ucbvax.Berkeley.EDU>
Thu, 2 Oct 1980 09:25:52 +0000 (01:25 -0800)
committerBill Joy <bill@ucbvax.Berkeley.EDU>
Thu, 2 Oct 1980 09:25:52 +0000 (01:25 -0800)
SCCS-vsn: bin/cp/cp.c 4.1

usr/src/bin/cp/cp.c [new file with mode: 0644]

diff --git a/usr/src/bin/cp/cp.c b/usr/src/bin/cp/cp.c
new file mode 100644 (file)
index 0000000..c2897d9
--- /dev/null
@@ -0,0 +1,123 @@
+static char *sccsid = "@(#)cp.c        4.1 (Berkeley) %G%";
+/*
+ * cp oldfile newfile
+ */
+
+#define        BSIZE   1024
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+struct stat    stbuf1, stbuf2;
+char   iobuf[BSIZE];
+int    iflag = 0;      /* interactive flag. If this flag is set,
+                        * the user is queried before files are
+                        * destroyed by cp.
+                        */
+
+main(argc, argv)
+char *argv[];
+{
+       register i, r;
+
+       /* get the flag(s) */
+
+       if (argc < 2)
+               goto usage;
+       if (*argv[1] == '-') {
+               argc--;
+               while (*++argv[1] != '\0')
+                       switch (*argv[1]) {
+
+                       /* interactive mode */
+                       case 'i':
+                               iflag++;
+                               break;
+
+                       /* don't live with bad options */
+                       default:
+                               goto usage;
+                       }
+               argv++;
+       }
+       if (argc < 3) 
+               goto usage;
+       if (argc > 3) {
+               if (stat(argv[argc-1], &stbuf2) < 0)
+                       goto usage;
+               if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 
+                       goto usage;
+       }
+       r = 0;
+       for(i=1; i<argc-1;i++)
+               r |= copy(argv[i], argv[argc-1]);
+       exit(r);
+usage:
+       fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
+       exit(1);
+}
+
+copy(from, to)
+char *from, *to;
+{
+       int fold, fnew, n;
+       register char *p1, *p2, *bp;
+       int mode;
+       char c,i;
+       if ((fold = open(from, 0)) < 0) {
+               fprintf(stderr, "cp: cannot open %s\n", from);
+               return(1);
+       }
+       fstat(fold, &stbuf1);
+       mode = stbuf1.st_mode;
+       /* is target a directory? */
+       if (stat(to, &stbuf2) >=0 &&
+          (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
+               p1 = from;
+               p2 = to;
+               bp = iobuf;
+               while(*bp++ = *p2++)
+                       ;
+               bp[-1] = '/';
+               p2 = bp;
+               while(*bp = *p1++)
+                       if (*bp++ == '/')
+                               bp = p2;
+               to = iobuf;
+       }
+       if (stat(to, &stbuf2) >= 0) {
+               if (stbuf1.st_dev == stbuf2.st_dev &&
+                  stbuf1.st_ino == stbuf2.st_ino) {
+                       fprintf(stderr, "cp: cannot copy file to itself.\n");
+                       return(1);
+               } else if (iflag) {
+                       fprintf (stderr, "overwrite %s? ", to);
+                       i = c = getchar();
+                       while (c != '\n' && c != EOF)
+                               c = getchar();
+                       if (i != 'y')
+                               return(1);
+               }
+       }
+       if ((fnew = creat(to, mode)) < 0) {
+               fprintf(stderr, "cp: cannot create %s\n", to);
+               close(fold);
+               return(1);
+       }
+       while(n = read(fold,  iobuf,  BSIZE)) {
+               if (n < 0) {
+                       perror("cp: read");
+                       close(fold);
+                       close(fnew);
+                       return(1);
+               } else
+                       if (write(fnew, iobuf, n) != n) {
+                               perror("cp: write");
+                               close(fold);
+                               close(fnew);
+                               return(1);
+                       }
+       }
+       close(fold);
+       close(fnew);
+       return(0);
+}