1 #include <u.h> 2 #include <libc.h> 3 4 #define DEFB (8*1024) 5 6 void copy(char *from, char *to, int todir); 7 void copy1(int fdf, int fdt, char *from, char *to); 8 9 void 10 main(int argc, char *argv[]) 11 { 12 Dir dirb; 13 int todir, i; 14 15 if(argc<3){ 16 fprint(2, "usage:\tcp fromfile tofile\n"); 17 fprint(2, "\tcp fromfile ... todir\n"); 18 exits("usage"); 19 } 20 todir=0; 21 if(dirstat(argv[argc-1], &dirb)==0 && (dirb.mode&CHDIR)) 22 todir=1; 23 if(argc>3 && !todir){ 24 fprint(2, "cp: %s not a directory\n", argv[argc-1]); 25 exits("bad usage"); 26 } 27 for(i=1; i<argc-1; i++) 28 copy(argv[i], argv[argc-1], todir); 29 exits(0); 30 } 31 32 void 33 copy(char *from, char *to, int todir) 34 { 35 Dir dirb, dirt; 36 char name[256]; 37 int fdf, fdt; 38 39 if(todir){ 40 char *s, *elem; 41 elem=s=from; 42 while(*s++) 43 if(s[-1]=='/') 44 elem=s; 45 sprint(name, "%s/%s", to, elem); 46 to=name; 47 } 48 if(dirstat(from, &dirb)!=0){ 49 fprint(2,"cp: can't stat %s: %r\n", from); 50 return; 51 } 52 if(dirb.mode&CHDIR){ 53 fprint(2, "cp: %s is a directory\n", from); 54 return; 55 } 56 dirb.mode &= 0777; 57 if(dirstat(to, &dirt)==0) 58 if(dirb.qid.path==dirt.qid.path && dirb.qid.vers==dirt.qid.vers) 59 if(dirb.dev==dirt.dev && dirb.type==dirt.type){ 60 fprint(2, "cp: %s and %s are the same file\n", from, to); 61 return; 62 } 63 fdf=open(from, OREAD); 64 if(fdf<0){ 65 fprint(2, "cp: can't open %s: %r\n", from); 66 return; 67 } 68 fdt=create(to, OWRITE, dirb.mode); 69 if(fdt<0){ 70 fprint(2, "cp: can't create %s: %r\n", to); 71 close(fdf); 72 return; 73 } 74 copy1(fdf, fdt, from, to); 75 close(fdf); 76 close(fdt); 77 } 78 79 void 80 copy1(int fdf, int fdt, char *from, char *to) 81 { 82 char *buf; 83 long n, n1, rcount; 84 85 buf = malloc(DEFB); 86 /* clear any residual error */ 87 memset(buf, 0, ERRLEN); 88 errstr(buf); 89 for(rcount=0;; rcount++) { 90 n = read(fdf, buf, DEFB); 91 if(n <= 0) 92 break; 93 n1 = write(fdt, buf, n); 94 if(n1 != n) { 95 fprint(2, "cp: error writing %s: %r\n", to); 96 break; 97 } 98 } 99 if(n < 0) 100 fprint(2, "cp: error reading %s: %r\n", from); 101 free(buf); 102 } 103