1 static char *sccsid = "@(#)cp.c 4.1 (Berkeley) 10/01/80"; 2 /* 3 * cp oldfile newfile 4 */ 5 6 #define BSIZE 1024 7 #include <stdio.h> 8 #include <sys/types.h> 9 #include <sys/stat.h> 10 struct stat stbuf1, stbuf2; 11 char iobuf[BSIZE]; 12 int iflag = 0; /* interactive flag. If this flag is set, 13 * the user is queried before files are 14 * destroyed by cp. 15 */ 16 17 main(argc, argv) 18 char *argv[]; 19 { 20 register i, r; 21 22 /* get the flag(s) */ 23 24 if (argc < 2) 25 goto usage; 26 if (*argv[1] == '-') { 27 argc--; 28 while (*++argv[1] != '\0') 29 switch (*argv[1]) { 30 31 /* interactive mode */ 32 case 'i': 33 iflag++; 34 break; 35 36 /* don't live with bad options */ 37 default: 38 goto usage; 39 } 40 argv++; 41 } 42 if (argc < 3) 43 goto usage; 44 if (argc > 3) { 45 if (stat(argv[argc-1], &stbuf2) < 0) 46 goto usage; 47 if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 48 goto usage; 49 } 50 r = 0; 51 for(i=1; i<argc-1;i++) 52 r |= copy(argv[i], argv[argc-1]); 53 exit(r); 54 usage: 55 fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n"); 56 exit(1); 57 } 58 59 copy(from, to) 60 char *from, *to; 61 { 62 int fold, fnew, n; 63 register char *p1, *p2, *bp; 64 int mode; 65 char c,i; 66 if ((fold = open(from, 0)) < 0) { 67 fprintf(stderr, "cp: cannot open %s\n", from); 68 return(1); 69 } 70 fstat(fold, &stbuf1); 71 mode = stbuf1.st_mode; 72 /* is target a directory? */ 73 if (stat(to, &stbuf2) >=0 && 74 (stbuf2.st_mode&S_IFMT) == S_IFDIR) { 75 p1 = from; 76 p2 = to; 77 bp = iobuf; 78 while(*bp++ = *p2++) 79 ; 80 bp[-1] = '/'; 81 p2 = bp; 82 while(*bp = *p1++) 83 if (*bp++ == '/') 84 bp = p2; 85 to = iobuf; 86 } 87 if (stat(to, &stbuf2) >= 0) { 88 if (stbuf1.st_dev == stbuf2.st_dev && 89 stbuf1.st_ino == stbuf2.st_ino) { 90 fprintf(stderr, "cp: cannot copy file to itself.\n"); 91 return(1); 92 } else if (iflag) { 93 fprintf (stderr, "overwrite %s? ", to); 94 i = c = getchar(); 95 while (c != '\n' && c != EOF) 96 c = getchar(); 97 if (i != 'y') 98 return(1); 99 } 100 } 101 if ((fnew = creat(to, mode)) < 0) { 102 fprintf(stderr, "cp: cannot create %s\n", to); 103 close(fold); 104 return(1); 105 } 106 while(n = read(fold, iobuf, BSIZE)) { 107 if (n < 0) { 108 perror("cp: read"); 109 close(fold); 110 close(fnew); 111 return(1); 112 } else 113 if (write(fnew, iobuf, n) != n) { 114 perror("cp: write"); 115 close(fold); 116 close(fnew); 117 return(1); 118 } 119 } 120 close(fold); 121 close(fnew); 122 return(0); 123 } 124